Skip to content

Authenticating with Azure

Terragrunt reads Azure credentials from the sources below to bootstrap, migrate, and delete the azurerm state backend. Set the same ARM_* variables for the OpenTofu/Terraform backend and providers.

Set the subscription, then pick whichever credential source fits where Terragrunt is running:

On a workstation, log in with the Azure CLI. Terragrunt and the providers pick the session up from the default credential chain:

Terminal window
az login
export ARM_SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
terragrunt apply

The non-secret values can also be set in the remote_state config (subscription_id, tenant_id, client_id, use_oidc, use_msi, msi_resource_id), and environment variables fill in whatever the config leaves unset. Keep ARM_CLIENT_SECRET in the environment: OpenTofu/Terraform copies backend configuration into .terraform/terraform.tfstate and into saved plan files, so a secret placed in remote_state.config ends up on disk in plain text.

Use the ARM_* names. Terragrunt also accepts the AZURE_* spellings used by the Azure SDKs (AZURE_CLIENT_ID, AZURE_TENANT_ID, and so on) for its own work, but the azurerm backend inside OpenTofu/Terraform reads only ARM_*, so a run that also initializes the backend fails with AZURE_* alone.

The auth provider command works for Azure too: return the ARM_* variables in its envs map to select credentials per unit at runtime.

Reading and writing state with use_azuread_auth requires the Storage Blob Data Contributor role on the storage account. Holding Contributor or Owner on the subscription is not enough on its own, because those are control-plane roles. Either grant the data-plane role out of band, or set assign_blob_data_role = true so that backend bootstrap grants it to the identity Terragrunt runs as. The latter needs permission to create role assignments (Microsoft.Authorization/roleAssignments/write), which Owner and User Access Administrator hold and Contributor does not.

Bootstrapping the backend additionally needs permission to create the resource group, storage account and container. If the identity must not create them, create them in advance and set skip_resource_group_creation, skip_storage_account_creation and skip_container_creation in the remote_state config.