How to Manage Active Directory Objects with Azure AD Provider for Terraform
Tags: terraform, tutorial, azure, devops
Published: 2021-10-18 17:16:58

The [Azure AD provider for Terraform](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs) can be used to manage your Azure Active Directory resources declaratively. This allows you to do things like:

* Automatically provision users and make sure they belong to the correct groups.
* Manage Azure compute permissions via Azure AD groups.

#Example Usage
The following example shows how to use the Azure AD provider to create a group in Azure AD:

```hcl
terraform {
 required_providers {
   azuread = {
     source  = "hashicorp/azuread"
     version = "= 1.6.0"
   }
 }
}

resource "azuread_group" "test" {
 display_name = "Test Group"
}
```

The terraform section at the start is used to specify the version of the provider that we want to use, and the resource `azuread_group` `test` block defines our group.

# Authenticating with Azure

The Azure AD provider allows multiple authentication methods, which are outlined in the provider's documentation. To allow you to get up and running quickly, the AD provider will attempt to get your credentials via the Azure CLI.

While this is fine for experimentation and local testing, for non-interactive scenarios like CI you need to use a *Service Principal* or a *Managed Service Identity*.

# Permissions

In order to manage your Azure AD objects, the account used by Terraform needs to have the correct permissions to perform its actions. You can manage these permissions via the *Roles and administrators* section of Azure AD:

![Active Directory Objects with Azure AD Provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0onqbhu2dzyem75c9l0t.jpg)

For example, to allow a Service Principal to manage groups, you would add it to the *Groups administrator* role:

![Active Directory Objects with Azure AD Provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbggh8oethir4kpvfuob.jpg)

# API Permissions

Another option that can be used with Service Principals instead of granting an administrator role is to grant specific API permissions to them. To do this, first find the AD Application linked to your Service Principal in the *App Registrations* section:

![Active Directory Objects with Azure AD Provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izymbl2glz03qpqkvl9m.jpg)

Go to the API permissions page for the application, and click on *Add a permission*:
![Active Directory Objects with Azure AD Provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/34ksnk6phnudhgx4sube.jpg)

On the screen that appears, choose the *Azure Active Directory Graph* API, and then choose the relevant permission you want to add:

![Active Directory Objects with Azure AD Provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gng7dj5utfbh5pr5ho9r.jpg)

Before the Service Principal can actually use the permission you just added, you need to take a final step called granting *Admin Consent*. You can do this by clicking on the Grant admin consent for *<tenant>* button displayed above the permissions table:

![Active Directory Objects with Azure AD Provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftkkq9n5ny7fs2zo2vq9.jpg)

**NOTES**:

* When adding permissions to your Service Principal, you need to add *Application permissions* rather than *Delegated permissions*. This means that the Service Principal is allowed to perform the specified actions as itself, rather than on behalf of another user.
* The set of permissions that you can add via API permissions is quite limited. For example, to create AD groups you need to add the *Directory.ReadWrite.All* permission, but this will not allow your Service Principal to delete any groups it creates. In order to be able to delete groups, you need to grant it the *Group Administrator* role, so depending on your requirements there may not be any point in granting API permissions.
* The Azure AD Terraform provider is switching to the *Microsoft Graph API* as of version 2.0.0, so after version 2 is released you will need to grant permissions to the *Microsoft Graph API* instead of to the *Azure Active Directory Graph API*.


# More Examples

## Managing Users and Groups

The following example creates two users and two groups, and assigns each user to a group:

```hcl
resource "azuread_user" "adamc" {
 user_principal_name   = "adamc@adamrpconnellygmail.onmicrosoft.com"
 display_name          = "Adam Connelly"
 password              = "SuperSecret01@!"
 force_password_change = true
}

resource "azuread_user" "bobd" {
 user_principal_name   = "bobd@adamrpconnellygmail.onmicrosoft.com"
 display_name          = "Bob Dolton"
 password              = "SuperSecret01@!"
 force_password_change = true
}

resource "azuread_group" "development" {
 display_name = "Development"
 members = [
   azuread_user.adamc.id
 ]
}

resource "azuread_group" "sales" {
 display_name = "Sales"
 members = [
   azuread_user.bobd.id
 ]
}
```

## Creating a Service Principal and granting RBAC permissions

The following example combines the <a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs" target="_blank">Azure AD provider</a>
with the Azure RM provider, allowing you to create a Service Principal and assign it permission to manage certain Azure resources:

```hcl
# Create an AD Application
resource "azuread_application" "automation" {
 display_name = "sp-automation"
}

# Create a Service Principal from that Application
resource "azuread_service_principal" "automation" {
 application_id               = azuread_application.automation.application_id
 app_role_assignment_required = false
}

# Get information about the configured Azure subscription
data "azurerm_subscription" "primary" {}

# Grant our service principal "Contributor" access over the subscription
resource "azurerm_role_assignment" "automation_contributor" {
 scope                = data.azurerm_subscription.primary.id
 role_definition_name = "Contributor"
 principal_id         = azuread_service_principal.automation.object_id
}
```

# Conclusion

In this post I’ve covered what the Azure AD Terraform provider is used for, how to authenticate and grant the correct permissions, as well as showing a few examples of what you can do with it. Hopefully you’ve found it useful!

If you’re interested in finding out about how you can use Spacelift to manage your Azure resources, check out [Spacelift Azure documentation](https://docs.spacelift.io/integrations/cloud-providers/azure). Also, don’t forget that you can easily give Spacelift a [free test drive](https://spacelift.io/free-trial)!

You will find more [Terraform](https://spacelift.io/blog/what-is-terraform) Tutorials on our website:

* [How to Import Existing Infrastructure into Terraform](https://spacelift.io/blog/importing-exisiting-infrastructure-into-terraform)
* [How to Use Terraform Modules](https://spacelift.io/blog/what-are-terraform-modules-and-how-do-they-work)
* [How to Use Terraform Variables](https://spacelift.io/blog/how-to-use-terraform-variables)
* [How to Use Terraform Functions, Expression and Loops](https://spacelift.io/blog/terraform-functions-expressions-loops)
* [How to Destroy Resources from Terraform](https://spacelift.io/blog/how-to-destroy-terraform-resources)
* [How to Upgrade Terraform to the Latest Version](https://spacelift.io/blog/terraform-version-upgrade)
* [5 Ways to Manage Terraform at Scale](https://spacelift.io/blog/5-ways-to-manage-terraform-at-scale)
* [How to Provision an AWS EKS Kubernetes Cluster with Terraform](https://spacelift.io/blog/how-to-provision-aws-eks-kubernetes-cluster-with-terraform)
* [How to Get Started with Terraform on Google Cloud Platform](https://spacelift.io/blog/getting-started-with-terraform-on-google-cloud-platform-gcp)