• HashiCorp Developer

  • HashiCorp Cloud Platform
  • Terraform
  • Packer
  • Consul
  • Vault
  • Boundary
  • Nomad
  • Waypoint
  • Vagrant
Terraform
  • Install
  • Tutorials
    • About the Docs
    • Configuration Language
    • Terraform CLI
    • Terraform Cloud
    • Terraform Enterprise
    • CDK for Terraform
    • Provider Use
    • Plugin Development
    • Registry Publishing
    • Integration Program
  • Registry(opens in new tab)
  • Try Cloud(opens in new tab)
  • Sign up
Azure Services

Skip to main content
4 tutorials
  • Deploy the Microsoft Cloud Adoption Framework Enterprise-Scale Module
  • Provision an AKS Cluster (Azure)
  • Manage Azure Active Directory (Azure AD) Users and Groups
  • Deploy Federated Multi-Cloud Kubernetes Clusters

  • Resources

  • Tutorial Library
  • Certifications
  • Community Forum
    (opens in new tab)
  • Support
    (opens in new tab)
  • GitHub
    (opens in new tab)
  • Terraform Registry
    (opens in new tab)
  1. Developer
  2. Terraform
  3. Tutorials
  4. Azure Services
  5. Manage Azure Active Directory (Azure AD) Users and Groups

Manage Azure Active Directory (Azure AD) Users and Groups

  • 20min

  • TerraformTerraform

Azure Active Directory (Azure AD) is an enterprise identity service that manages your organization's user lifecycle. The Azure AD Terraform provider lets organization administrators manage users, groups, service principals, and applications as code. Terraform provides several benefits over using the Azure Portal to manage your organization's Active Directory:

  • Safety and consistency Defining your Active Directory infrastructure as code (IaC) reduces the risk of human error. With IaC, you can version control your configuration and ensure that the proper reviewers approve changes before merging them. IaC allows you to track and revert changes to your AD resources as your organization evolves.

  • Improved automation Terraform can create, update, and delete tracked resources without requiring you to keep track of each resource's dependencies. With Terraform, you can develop modules for your users, groups, applications, and service principals that comply with your organization's policies. For example, you can use Terraform to ensure that the security team has access to every new AD group.

In this tutorial, you will create new users in your Azure AD with data populated from a CSV file. Then, you will create new AD groups and dynamically assign users to their respective groups based on their roles. Finally, you will create additional new users by updating the CSV file. In the process, you will learn Terraform's configuration language, the Terraform Azure AD provider, and how to leverage both to simplify and automate your workflows.

Prerequisites

For this tutorial, you will need:

  • the Terraform 1.0.4+ CLI installed locally.
  • an Azure account with an Azure AD tenant.
  • a configured Azure CLI.

You must have an Azure AD tenant to follow this tutorial. An Azure AD tenant represents an organization that allows you to use the Microsoft identity platform in your applications for identity and access management. Refer to this tenant setup quickstart page to verify you have an existing Azure AD tenant or to create a new one.

Authenticate Azure AD provider

The Azure AD provider needs to authenticate to Azure to manage your resources. There are multiple ways to authenticate the Azure AD provider. In this tutorial, you will authenticate the provider using the Azure CLI.

First, log in to the Azure CLI and follow the instructions in the prompt. Since Azure AD tenants can exist without a subscription, use the --allow-no-subscriptions flag to list all tenants.

$ az login --allow-no-subscriptions
The default web browser has been opened at https://login.microsoftonline.com/common/oauth2/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.
You have logged in. Now let us find all the subscriptions to which you have access...
The following tenants don't contain accessible subscriptions. Use 'az login --allow-no-subscriptions' to have tenant level access.
REDACTED 'hashicorp.com'
[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "00000000-0000-0000-0000-000000000000",
    "id": "00000000-0000-0000-0000-000000000000",
    "isDefault": true,
    "managedByTenants": [
      {
        "tenantId": "00000000-0000-0000-0000-000000000000"
      }
    ],
    "name": "My Subscription",
    "state": "Enabled",
    "tenantId": "00000000-0000-0000-0000-000000000000",
    "user": {
      "name": "J. Doe",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "id": "00000000-0000-0000-0000-000000000000",
    "isDefault": false,
    "name": "N/A(tenant level account)",
    "state": "Enabled",
    "tenantId": "00000000-0000-0000-0000-000000000000",
    "user": {
      "name": "J. Doe",
      "type": "user"
    }
  }
]

The login command outputs a list of subscriptions and tenants associated with the account. The provider will automatically select the tenant ID from your default Azure CLI account. If you have more than one tenant, specify the tenant by setting the ARM_TENANT_ID environment variable to your preferred tenant ID (tenantId field from the previous command's output).

$ export ARM_TENANT_ID=

Clone example repository

Clone the example repository, which contains configuration to create new users in your Azure AD tenant.

$ git clone https://github.com/hashicorp/learn-terraform-azure-ad

Change into the repository directory.

$ cd learn-terraform-azure-ad

Review users CSV file

Open users.csv. This CSV file contains a list of user information that Terraform will use to configure AD users.

users.csv
first_name,last_name,department,job_title
Michael,Scott,Education,Manager
Jim,Halpert,Education,Engineer
Pam,Beesly,Education,Engineer

The first line is the header. Each field in the header is a key for the corresponding value in the same position in the remaining rows. Each remaining row represents a user and must contain the same number of fields as the header. These header key names allow you to reference a specific user attribute in your Terraform configuration.

Review configuration

Open versions.tf. This file contains a terraform {} block that defines Terraform settings, including the required providers Terraform will use to provision your infrastructure. A provider is a plugin that Terraform uses to interact with APIs. The source attribute defines an optional hostname, a namespace, and the provider type for each provider. Terraform installs providers from the Terraform Registry by default. This example configuration defines the azuread provider's source as hashicorp/azuread, which is shorthand for registry.terraform.io/hashicorp/azuread.

You can also set a version constraint for each provider defined in the required_providers block. The version attribute is optional, but we recommend using it to constrain the provider version so that Terraform does not install a provider version that does not work with your configuration. If you do not specify a provider version, Terraform will automatically download the version listed in the .terraform.lock.hcl file. If neither exist, Terraform will download the latest version during initialization.

versions.tf
terraform {
  required_providers {
    azuread = {
      source  = "hashicorp/azuread"
      version = "~> 2.0.0"
    }
  }
}

Open main.tf to review the Terraform configuration that will create the users defined in your CSV file. Terraform configuration consists of blocks of code written in Terraform configuration language. Review each block below to learn what this Terraform configuration defines.

Provider block

To use the Azure AD provider, you must define a provider block in your configuration.

main.tf
provider "azuread" {}

The azuread provider block is empty because it uses the credentials configured by the Azure CLI for authentication. You can configure other optional, provider-specific settings in this block, like client ID, environment, or tenant ID. This provider automatically uses your default tenant ID if you do not set the ARM_TENANT_ID environment variable.

Data source block

Data sources allow you to retrieve information from the provider.

main.tf
data "azuread_domains" "default" {
  only_initial = true
}

This azuread_domains data source retrieves your primary Azure AD tenant domain. Terraform will use this to create user principal names for your users.

Local values

The locals block allows you to define values that you reference throughout your configuration. Locals capture common values to make your configuration easier to read and less repetitive.

main.tf
locals {
  domain_name = data.azuread_domains.default.domains.0.domain_name
  users       = csvdecode(file("${path.module}/users.csv"))
}

This locals block defines two values:

  1. The domain_name local value stores the Azure AD tenant domain name retrieved by the azuread_domains.default data source. This allows you to use local.domain_name instead of parsing the data source every time you reference it.

  2. The users local value parses the users.csv file using the csvdecode and file functions. The csvdecode function converts the file contents into a list of maps, allowing Terraform to reference the values in the CSV file in the configuration.

Resources

Resource blocks are the primary way you interact with the provider to manage its components.

Resource blocks have two strings in the first line of the block: the resource type and the resource name. The first resource block defines a random_pet resource named suffix, which generates a random pet name. This configuration uses this resource to ensure that your users have unique principal names.

main.tf
resource "random_pet" "suffix" {
  length = 2
}

Now, find the first two lines of the AzureAD users resource block.

main.tf
resource "azuread_user" "users" {
  for_each = { for user in local.users : user.first_name => user }
##...

This azuread_user resource block is named users. The for_each meta-argument tells Terraform that this block defines multiple users, each one mapped to a user in the local.users value. By storing information about your users in a CSV file and using the for_each meta-argument to iterate over the decoded contents, you avoid creating unique resource blocks for each user, which can become difficult to manage as you add more users.

Each resource has required or optional arguments that Terraform uses to configure the resource to your specifications. Refer to the resource's documentation in Terraform Registry to find a complete list of arguments.

The azuread_user resource requires the user_principal_name, password, and display_name arguments.

Tip: This block references a specific user's information by using each.value.attribute_name. The attribute_name maps to the header row in the CSV file. For example, each.value.first_name maps to the user's first name.

main.tf
##...
  user_principal_name = format(
    "%s%s-%s@%s",
    substr(lower(each.value.first_name), 0 , 1),
    lower(each.value.last_name),
    random_pet.suffix.id,
    local.domain_name
  )

  password = format(
    "%s%s%s!",
    lower(each.value.last_name),
    substr(lower(each.value.first_name), 0 , 1),
    length(each.value.first_name)
  )
  force_password_change = true

  display_name = "${each.value.first_name} ${each.value.last_name}"
##...

The user_principal_name and password arguments use the format() function to generate these values from the user's first name, last name, and the Azure AD tenant's domain name (local.domain_name).

For example, if your user is named "Jim Halpert", their user principal name would be jhalpert@domain_name, where the domain name is your AD tenant's domain name, and their password would be halpertj3!.

The password argument sets the user's initial password. Azure will force them to change it after the initial sign-in.

The display_name argument uses Terraform interpolation (${}) to generate a string from the user's first and last name.

The configuration also sets the job_title and department attributes, which are optional for the azuread_user resource.

main.tf
  ##...
  department   = each.value.department
  job_title    = each.value.job_title
}

Create AD users

Initialize the Terraform configuration. Initializing a configuration directory downloads and installs the providers defined in the configuration, which in this case is the azuread provider.

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp.com/edu/azuread from the dependency lock file
- Installing hashicorp.com/edu/azuread v2.0.0...
- Installed hashicorp.com/edu/azuread v2.0.0 (unauthenticated)

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Next, apply the configuration. Respond yes when prompted to create your AD users.

$ terraform apply

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

## ...

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

random_pet.suffix: Creating...
random_pet.suffix: Creation complete after 0s [id=artistic-coyote]
azuread_user.users["Jim"]: Creating...
azuread_user.users["Michael"]: Creating...
azuread_user.users["Pam"]: Creating...
azuread_user.users["Michael"]: Creation complete after 2s [id=00000000-0000-0000-0000-000000000000]
azuread_user.users["Pam"]: Creation complete after 2s [id=b1118a72-f6a7-4f31-85a7-f1febbb9afbb]
azuread_user.users["Jim"]: Creation complete after 2s [id=8ce974f1-c6ee-4234-96fa-748f01f2488d]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Notice that Terraform created three users, one for each row defined in your users.csv file. Using the for_each meta-argument, you created three unique users using a single resource block.

Use the Terraform state command to list all resources managed by Terraform.

$ terraform state list
data.azuread_domains.default
azuread_user.users["Jim"]
azuread_user.users["Michael"]
azuread_user.users["Pam"]
random_pet.suffix

Retrieve Pam's AD user information.

$ terraform state show 'azuread_user.users["Pam"]'
resource "azuread_user" "users" {
    account_enabled         = true
    business_phones         = []
    department              = "Education"
    display_name            = "Pam Beesly"
    force_password_change   = true
    id                      = "REDACTED"
    im_addresses            = []
    job_title               = "Engineer"
    mail_nickname           = "pbeesly"
    object_id               = "REDACTED"
    onpremises_sync_enabled = false
    password                = (sensitive value)
    proxy_addresses         = []
    show_in_address_list    = true
    user_principal_name     = "pbeesly@terraformhashicorp.onmicrosoft.com"
    user_type               = "Member"
}

Verify user creation

Use the Azure CLI to retrieve your newly created users. This command filters users that are in the "Education" department.

$ az ad user list --query "[?department=='Education'].{ department: department, name: displayName, jobTitle: jobTitle, pname: userPrincipalName }" --output tsv
Education       Jim Halpert     Engineer        jhalpert@terraformhashicorp.onmicrosoft.com
Education       Michael Scott   Manager mscott@terraformhashicorp.onmicrosoft.com
Education       Pam Beesly      Engineer        pbeesly@terraformhashicorp.onmicrosoft.com

You will find three users, as defined in users.csv.

Create AD groups and assign members

Now that you have created AD users, you will create groups and assign users to them based on their attributes.

Create a new file named groups.tf with the following configuration.

groups.tf
resource "azuread_group" "engineering" {
  display_name = "Education Department"
  security_enabled = true
}

resource "azuread_group_member" "education" {
  for_each = { for u in azuread_user.users: u.mail_nickname => u if u.department == "Education" }

  group_object_id  = azuread_group.engineering.id
  member_object_id = each.value.id
}

resource "azuread_group" "managers" {
  display_name = "Education - Managers"
  security_enabled = true
}

resource "azuread_group_member" "managers" {
  for_each = { for u in azuread_user.users: u.mail_nickname => u if u.job_title == "Manager" }

  group_object_id  = azuread_group.managers.id
  member_object_id = each.value.id
}

resource "azuread_group" "engineers" {
  display_name = "Education - Engineers"
  security_enabled = true
}

resource "azuread_group_member" "engineers" {
  for_each = { for u in azuread_user.users: u.mail_nickname => u if u.job_title == "Engineer" }

  group_object_id  = azuread_group.engineers.id
  member_object_id = each.value.id
}

This configuration creates three groups and assigns the appropriate users based on their department or job title.

  1. The azuread_group.education resource creates a new group named "Education Department". The azuread_group requires either the mail_enabled or security_enabled argument. The azuread_group_member.education resource assigns all users in the Education department to this group.

    This resource uses the for_each meta-argument to loop through all users created by azuread_user.users. This creates an implicit dependency and ensures that the user exists in your AD tenant before assigning it to the group. The for_each meta-argument uses u.mail_nickname as the key. This maps each member to a member association in the resource ID. For example, azuread_group_member.education[\"jhalpert-artistic-coyote\"] maps to Jim Halpert's education member association.

  2. The azuread_group.managers creates a new group named "Education - Managers". The azuread_group_member.managers resource loops through all created users and assigns all managers to the group.

  3. The azuread_group.engineers creates a new group named "Education - Engineers". The azuread_group_member.engineers resource loops through all created users and assigns all engineers to the group.

Apply the configuration. Respond yes when prompted to create your AD groups and assign users to the appropriate ones.

$ terraform apply

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

## ...

Plan: 9 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azuread_group.education: Creating...
azuread_group.managers: Creating...
azuread_group.engineers: Creating...
azuread_group.education: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000]
azuread_group.managers: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000]
azuread_group_member.education["mscott-artistic-coyote"]: Creating...
azuread_group_member.managers["mscott-artistic-coyote"]: Creating...
azuread_group_member.education["jhalpert-artistic-coyote"]: Creating...
azuread_group_member.education["pbeesly-artistic-coyote"]: Creating...
azuread_group.engineers: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000]
azuread_group_member.engineers["jhalpert-artistic-coyote"]: Creating...
azuread_group_member.engineers["pbeesly-artistic-coyote"]: Creating...
azuread_group_member.education["mscott-artistic-coyote"]: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.engineers["jhalpert-artistic-coyote"]: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.managers["mscott-artistic-coyote"]: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.education["pbeesly-artistic-coyote"]: Creation complete after 6s [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.engineers["pbeesly-artistic-coyote"]: Creation complete after 6s [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.education["jhalpert-artistic-coyote"]: Creation complete after 9s [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]

Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

Verify group creation and user assignment

Use the Azure CLI to verify that Terraform created the three groups you defined.

$ az ad group list --query "[?contains(displayName,'Education')].{ name: displayName }" --output tsv
Education - Engineers
Education - Managers
Education Department

List all the users in the Education department group.

$ az ad group member list --group "Education Department" --query "[].{ name: displayName }" --output tsv
Michael Scott
Jim Halpert
Pam Beesly

List all the users in the managers group.

$ az ad group member list --group "Education - Managers" --query "[].{ name: displayName }" --output tsv
Michael Scott

List all the users in the engineers group.

$ az ad group member list --group "Education - Engineers" --query "[].{ name: displayName }" --output tsv
Jim Halpert
Pam Beesly

Manage new users

Add the following new users to your users.csv file.

users.csv
first_name,last_name,department,job_title
Michael,Scott,Education,Manager
Jim,Halpert,Education,Engineer
Pam,Beesly,Education,Engineer
Dwight,Schrute,Education,Engineer
Phyllis,Vance,Education,Engineer
Kelly,Kapoor,Education,Customer Success

Tip: Make sure to remove any trailing white space from each user's job title.

Add a new group

Since Kelly Kapoor is a customer success engineer, Terraform will only assign Kelly to the "Education Department" group.

In groups.tf, add the following configuration to create a new group named "Education - Customer Success" and assign all accountants to the group.

groups.tf
resource "azuread_group" "customer_success" {
  display_name = "Education - Customer Success"
  security_enabled = true
}

resource "azuread_group_member" "customer_success" {
  for_each = { for u in azuread_user.users: u.mail_nickname => u if u.job_title == "Customer Success" }

  group_object_id  = azuread_group.customer_success.id
  member_object_id = each.value.id
}

Create new users

Since the azuread_group_member resources rely on the azuread_user.users resource to determine the number of group/user assignments, you need to create the users resource first.

Apply the configuration using the -target flag to create the new users first. The -target flag instructs Terraform to only change a single resource rather than all resources in the current directory. When you apply your configuration, Terraform will create three new AD users and add the new users to their respective teams. Respond yes when prompted to add the new users.

$ terraform apply -target azuread_user.users

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

## ...

Plan: 3 to add, 0 to change, 0 to destroy.
â•·
│ Warning: Resource targeting is in effect
│ 
│ You are creating a plan with the -target option, which means that the result of this plan may not
│ represent all of the changes requested by the current configuration.
│ 
│ The -target option is not for routine use, and is provided only for exceptional situations such as
│ recovering from errors or mistakes, or when Terraform specifically suggests to use it as part of an
│ error message.
╵

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azuread_user.users["Kelly"]: Creating...
azuread_user.users["Phyllis"]: Creating...
azuread_user.users["Dwight"]: Creating...
azuread_user.users["Dwight"]: Creation complete after 2s [id=00000000-0000-0000-0000-000000000000]
azuread_user.users["Phyllis"]: Creation complete after 2s [id=00000000-0000-0000-0000-000000000000]
azuread_user.users["Kelly"]: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000]
â•·
│ Warning: Applied changes may be incomplete
│ 
│ The plan was created with the -target option in effect, so some changes requested in the configuration
│ may have been ignored and the output values may not be fully updated. Run the following command to
│ verify that no other changes are pending:
│     terraform plan
│ 
│ Note that the -target option is not suitable for routine use, and is provided only for exceptional
│ situations such as recovering from errors or mistakes, or when Terraform specifically suggests to use
│ it as part of an error message.
╵

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Update group assignments

Now, apply the configuration again. Respond yes when prompted to create the Customer Success group and update the group assignments.

$ terraform apply

Plan: 7 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azuread_group.customer_success: Creating...
azuread_group_member.engineers["pvance-artistic-coyote"]: Creating...
azuread_group_member.education["dschrute-artistic-coyote"]: Creating...
azuread_group_member.education["kkapoor-artistic-coyote"]: Creating...
azuread_group_member.education["pvance-artistic-coyote"]: Creating...
azuread_group_member.engineers["dschrute-artistic-coyote"]: Creating...
azuread_group_member.engineers["pvance-artistic-coyote"]: Creation complete after 3s [id=00000000-0000-0000-0000-000000000000/member/764e9554-37cb-4382-a9cb-877fbf72516d]
azuread_group_member.education["pvance-artistic-coyote"]: Creation complete after 4s [id=00000000-0000-0000-0000-000000000000/member/764e9554-37cb-4382-a9cb-877fbf72516d]
azuread_group.customer_success: Creation complete after 4s [id=3ed46611-c575-4031-bf85-f95760242cb0]
azuread_group_member.customer_success["kkapoor-artistic-coyote"]: Creating...
azuread_group_member.engineers["dschrute-artistic-coyote"]: Creation complete after 6s [id=00000000-0000-0000-0000-000000000000/member/82cbf25d-1834-449c-857d-91c143514ef9]
azuread_group_member.customer_success["kkapoor-artistic-coyote"]: Creation complete after 3s [id=3ed46611-c575-4031-bf85-f95760242cb0/member/722a0b0d-269e-4948-8415-75a270c4e4f6]
azuread_group_member.education["kkapoor-artistic-coyote"]: Creation complete after 7s [id=00000000-0000-0000-0000-000000000000/member/722a0b0d-269e-4948-8415-75a270c4e4f6]
azuread_group_member.education["dschrute-artistic-coyote"]: Still creating... [10s elapsed]
azuread_group_member.education["dschrute-artistic-coyote"]: Creation complete after 10s [id=00000000-0000-0000-0000-000000000000/member/82cbf25d-1834-449c-857d-91c143514ef9]

Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

Verify resource creation and user assignment

Use the Azure CLI to retrieve your newly created users. You will find a total of six users.

$ az ad user list --query "[?department=='Education'].{ department: department, name: displayName, jobTitle: jobTitle, pname: userPrincipalName }" --output tsv
Education       Dwight Schrute  Engineer        dschrute@terraformhashicorp.onmicrosoft.com
Education       Jim Halpert     Engineer        jhalpert@terraformhashicorp.onmicrosoft.com
Education       Kelly Kapoor    Customer Success        kkapoor@terraformhashicorp.onmicrosoft.com
Education       Michael Scott   Manager mscott@terraformhashicorp.onmicrosoft.com
Education       Pam Beesly      Engineer        pbeesly@terraformhashicorp.onmicrosoft.com
Education       Phyllis Vance   Engineer        pvance@terraformhashicorp.onmicrosoft.com

Verify that Terraform created the groups you defined. You will find four groups, including the new Customer Success group.

$ az ad group list --query "[?contains(displayName,'Education')].{ name: displayName }" --output tsv
Education - Engineers
Education - Managers
Education Department
Education - Customer Success

List all the users in the Education department group. You will find a total of six users.

$ az ad group member list --group "Education Department" --query "[].{ name: displayName }" --output tsv
Michael Scott
Jim Halpert
Pam Beesly
Dwight Schrute
Phyllis Vance
Kelly Kapoor

List all the users in the engineers group. You will find a total of four users.

$ az ad group member list --group "Education - Engineers" --query "[].{ name: displayName }" --output tsv
Jim Halpert
Pam Beesly
Dwight Schrute
Phyllis Vance

Finally, list all the users in the customer success group. You will find Kelly Kapoor.

$ az ad group member list --group "Education - Customer Success" --query "[].{ name: displayName }" --output tsv
Kelly Kapoor

Clean up resources

Before moving on, destroy the resources you created in this tutorial. Respond yes when prompted to destroy all AD users and groups.

$ terraform destroy

## ...
Plan: 0 to add, 0 to change, 23 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

azuread_group_member.engineers["jhalpert-artistic-coyote"]: Destroying... [id=00000000-0000-0000-0000-000000000000/member/8ce974f1-c6ee-4234-96fa-748f01f2488d]
azuread_group_member.engineers["pvance-artistic-coyote"]: Destroying... [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.managers["mscott-artistic-coyote"]: Destroying... [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.customer_success["kkapoor-artistic-coyote"]: Destroying... [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
azuread_group_member.education["kkapoor-artistic-coyote"]: Destroying... [id=00000000-0000-0000-0000-000000000000/member/00000000-0000-0000-0000-000000000000]
## ...

Destroy complete! Resources: 23 destroyed.

Next steps

In this tutorial, you created new users in your Azure AD with data populated from a CSV file. Then, you created new AD groups and dynamically assigned users to their respective groups based on their roles. Finally, you created new users by updating the CSV file and created a new group for customer success. In the process, you used a wide variety of Terraform's configuration language elements and functions like resource blocks, locals, and the csvdecode() function. In addition, you learned about the resources the Azure AD provider can manage.

For more information on topics covered in this tutorial, check out the following resources:

  • Learn more about input variables and dynamic expressions, which you used in this tutorial.

  • Complete the Reuse Configuration with Modules tutorials to learn how to create reusable modules to enable repeatable workflows.

  • Visit the Azure AD provider documentation to learn more about the Azure AD resources and data sources you can manage using Terraform.

 Previous
 Next

This tutorial also appears in:

  •  
    3 tutorials
    IT/SaaS Providers
    Manage your organization, users, and workflows with Terraform's Information Technology (IT) and Software as a Service (SaaS) focused providers.
    • Terraform

On this page

  1. Manage Azure Active Directory (Azure AD) Users and Groups
  2. Prerequisites
  3. Clone example repository
  4. Review users CSV file
  5. Review configuration
  6. Create AD users
  7. Create AD groups and assign members
  8. Verify group creation and user assignment
  9. Manage new users
  10. Verify resource creation and user assignment
  11. Clean up resources
  12. Next steps
Give Feedback(opens in new tab)
  • Certifications
  • System Status
  • Terms of Use
  • Security
  • Privacy
  • Trademark Policy
  • Trade Controls
  • Give Feedback(opens in new tab)