Skip to content

Azure Provider — Credentials and Permissions

First PublishedByAtif Alam

When you use the Azure provider (azurerm) in Terraform, Terraform calls the Azure Resource Manager (ARM) API to create, update, and delete resources. Those API calls are authorized using Azure credentials.

Terraform does not have its own credential system — the Azure provider uses the same authentication mechanisms as the Azure CLI and Azure SDK.

Whoever or whatever runs terraform plan and terraform apply must have an Azure AD identity (user or service principal) with the right RBAC (Role-Based Access Control) permissions on the subscription or resource groups you manage.

The Azure provider can authenticate in several ways:

SourceWhen it’s used
Environment variablesARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_SUBSCRIPTION_ID, ARM_TENANT_ID — typically for a service principal. Used in CI or when you don’t use the Azure CLI.
Azure CLIAfter you run az login, the provider can use the same credentials (your user or the account you logged in as). No env vars needed for local use.
Managed identityWhen Terraform runs on an Azure VM, in Azure DevOps, or in another Azure service with a managed identity, the provider can use that identity. No client secret.
OIDC / workload identityIn CI (e.g. GitHub Actions, GitLab), you can use federated credentials so the pipeline assumes an Azure AD app registration without storing a client secret.

Example: configuring the provider with subscription and optional tenant/client settings:

provider "azurerm" {
subscription_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
tenant_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # optional if using Azure CLI
client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # optional if using Azure CLI
client_secret = var.arm_client_secret # optional; use env ARM_CLIENT_SECRET in CI
features {}
}

If you use Azure CLI (az login) and don’t set client_id / client_secret, the provider uses your CLI identity. For CI, set the ARM_* environment variables (or use OIDC) and optionally pass subscription/tenant in the provider block or via env vars.

Terraform can only create or change resources for which the active identity has RBAC permissions. Azure uses roles (e.g. Contributor, Owner) scoped to a subscription or resource group. The identity must be allowed to perform the ARM operations your resources use. For example:

  • azurerm_resource_group → ability to create resource groups in the subscription.
  • azurerm_virtual_network, azurerm_subnet → network write permissions.
  • azurerm_linux_virtual_machine → compute and disk permissions.
  • azurerm_key_vault → Key Vault and access policy permissions.

There is no single “Terraform” role that fits every scenario. In practice you either:

  • Use broad roles (e.g. Contributor on a subscription or resource group) for simplicity, or
  • Create custom RBAC roles or use built-in roles with narrow scope (e.g. a resource group only) so Terraform has least privilege.

Best practice: use a dedicated service principal for Terraform (e.g. “terraform-sp”) with Contributor (or a custom role) scoped to the subscription or resource groups you manage. In CI, prefer OIDC/federated credentials so no long-lived client secret is stored.

Running Terraform in CI (GitHub Actions, etc.)

Section titled “Running Terraform in CI (GitHub Actions, etc.)”

In CI, do not commit client secrets. Prefer:

  • OIDC (federated credentials) — Configure the Azure AD app to trust your CI provider (e.g. GitHub). The workflow obtains a short-lived token; the provider uses it. No ARM_CLIENT_SECRET needed.
  • Service principal with secret — If OIDC isn’t an option, store the client secret in CI secrets and set ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_SUBSCRIPTION_ID, and ARM_TENANT_ID in the job environment.

The provider block can stay the same; only the source of the credentials changes. For more on CI/CD layout and storing secrets, see Best Practices.

  • Terraform’s permissions with Azure come from the credentials used by the Azure provider — env vars (ARM_*), Azure CLI, or managed identity.
  • The Azure AD identity (user or service principal) must have RBAC permissions (e.g. Contributor) on the subscription or resource groups your config targets.
  • Use a dedicated service principal for Terraform and least privilege where possible; in CI, prefer OIDC over long-lived client secrets.