Vault-Backed Dynamic Credentials with the Azure Provider
Important: If you are self-hosting Terraform Cloud Agents, ensure your agents use v1.8.0 or above. To use the latest dynamic credentials features, upgrade your agents to the latest version.
You can use Terraform Cloud’s native OpenID Connect integration with Vault to use Vault-backed dynamic credentials with the Azure provider in your Terraform Cloud runs. Configuring the integration requires the following steps:
- Configure Vault Dynamic Provider Credentials: Set up a trust configuration between Vault and Terraform Cloud, create Vault roles and policies for your Terraform Cloud workspaces, and add environment variables to those workspaces.
- Configure the Vault Azure Secrets Engine: Set up the Azure secrets engine in your Vault instance.
- Configure Terraform Cloud: Add additional environment variables to the Terraform Cloud workspaces where you want to use Vault-Backed Dynamic Credentials.
- Configure Terraform Providers: Configure your Terraform providers to work with Vault-backed Dynamic Credentials.
Once you complete this setup, Terraform Cloud automatically authenticates with Azure via Vault-generated credentials during the plan and apply phase of each run. The Azure provider's authentication is only valid for the length of the plan or apply phase.
Configure Vault Dynamic Provider Credentials
You must first set up Vault dynamic provider credentials before you can use Vault-backed dynamic credentials. This includes setting up the JWT auth backend in Vault, configuring trust between Terraform Cloud and Vault, and populating the required environment variables in your Terraform Cloud workspace.
See the setup instructions for Vault dynamic provider credentials.
Configure Vault Azure Secrets Engine
Follow the instructions in the Vault documentation for setting up the Azure secrets engine in your Vault instance. You can also do this configuration through Terraform. Refer to our example Terraform configuration.
Configure Terraform Cloud
Next, you need to set certain environment variables in your Terraform Cloud workspace to authenticate Terraform Cloud with Azure using Vault-backed dynamic credentials. These variables are in addition to those you previously set while configuring Vault dynamic provider credentials. You can add these as workspace variables or as a variable set.
Required Environment Variables
Variable | Value | Notes |
---|---|---|
TFC_VAULT_BACKED_AZURE_AUTH | true | Requires v1.8.0 or later if self-managing agents. Must be present and set to true , or Terraform Cloud will not attempt to authenticate with Azure. |
TFC_VAULT_BACKED_AZURE_RUN_VAULT_ROLE | The role to use in Vault. | Requires v1.8.0 or later if self-managing agents. Optional if TFC_VAULT_BACKED_AZURE_PLAN_VAULT_ROLE and TFC_VAULT_BACKED_AZURE_APPLY_VAULT_ROLE are both provided. These variables are described below. |
Optional Environment Variables
You may need to set these variables, depending on your use case.
Variable | Value | Notes |
---|---|---|
TFC_VAULT_BACKED_AZURE_MOUNT_PATH | The mount path of the Azure secrets engine in Vault. | Requires v1.8.0 or later if self-managing agents. Defaults to azure . |
TFC_VAULT_BACKED_AZURE_PLAN_VAULT_ROLE | The Vault role to use the plan phase of a run. | Requires v1.8.0 or later if self-managing agents. Will fall back to the value of TFC_VAULT_BACKED_AZURE_RUN_VAULT_ROLE if not provided. |
TFC_VAULT_BACKED_AZURE_APPLY_VAULT_ROLE | The Vault role to use for the apply phase of a run. | Requires v1.8.0 or later if self-managing agents. Will fall back to the value of TFC_VAULT_BACKED_AZURE_RUN_VAULT_ROLE if not provided. |
TFC_VAULT_BACKED_AZURE_SLEEP_SECONDS | The amount of time to wait, in seconds, after obtaining temporary credentials from Vault. e.g., 30 for 30 seconds. Must be 1500 seconds (25 minutes) or less. | Requires v1.12.0 or later if self-managing agents. Can be used to mitigate eventual consistency issues in Azure. |
TFC_VAULT_BACKED_AZURE_VAULT_CONFIG | The name of the non-default Vault configuration for workspaces using multiple Vault configurations. | Requires v1.12.0 or later if self-managing agents. Will fall back to using the default Vault configuration if not provided. |
Configure Terraform Providers
The final step is to directly configure your Azure and Vault providers.
Configure the AzureRM or AzureAD Provider
Ensure you pass a value for the subscription_id
and tenant_id
arguments in your provider configuration block or set the ARM_SUBSCRIPTION_ID
and ARM_TENANT_ID
variables in your workspace.
Do not set values for client_id
, use_oidc
, or oidc_token
in your provider configuration block. Additionally, do not set variable values for ARM_CLIENT_ID
, ARM_USE_OIDC
, or ARM_OIDC_TOKEN
.
Configure the Vault Provider
If you were previously using the Vault provider to authenticate the Azure provider, remove any existing usage of the Azure secrets engine from your Terraform Code.
This includes the vault_azure_access_credentials
data source and any instances of vault_generic_secret
you previously used to generate Azure credentials.
Specifying Multiple Configurations
Important: Ensure you are using version 3.60.0 or later of the AzureRM provider and version 2.43.0 or later of the AzureAD provider as required functionality was introduced in these provider versions.
Important: If you are self-hosting Terraform Cloud Agents, ensure your agents use v1.12.0 or above. To use the latest dynamic credentials features, upgrade your agents to the latest version.
You can add additional configurations to handle multiple distinct Vault-backed Azure setups, enabling you to use multiple provider aliases within the same workspace.
For more details, see Specifying Multiple Configurations.
Required Terraform Variable
To use additional configurations, add the following code to your Terraform configuration. This lets Terraform Cloud supply variable values that you can then use to map authentication and configuration details to the correct provider blocks.
variable "tfc_vault_backed_azure_dynamic_credentials" { description = "Object containing Vault-backed Azure dynamic credentials configuration" type = object({ default = object({ client_id_file_path = string client_secret_file_path = string }) aliases = map(object({ client_id_file_path = string client_secret_file_path = string })) })}
Example Usage
AzureRM Provider
provider "azurerm" { features {} // use_cli should be set to false to yield more accurate error messages on auth failure. use_cli = false client_id_file_path = var.tfc_vault_backed_azure_dynamic_credentials.default.client_id_file_path client_secret_file_path = var.tfc_vault_backed_azure_dynamic_credentials.default.client_secret_file_path subscription_id = "00000000-0000-0000-0000-000000000000" tenant_id = "10000000-0000-0000-0000-000000000000"} provider "azurerm" { features {} // use_cli should be set to false to yield more accurate error messages on auth failure. use_cli = false alias = "ALIAS1" client_id_file_path = var.tfc_vault_backed_azure_dynamic_credentials.aliases["ALIAS1"].client_id_file_path client_secret_file_path = var.tfc_vault_backed_azure_dynamic_credentials.aliases["ALIAS1"].client_secret_file_path subscription_id = "00000000-0000-0000-0000-000000000000" tenant_id = "20000000-0000-0000-0000-000000000000"}
AzureAD Provider
provider "azuread" { features {} // use_cli should be set to false to yield more accurate error messages on auth failure. use_cli = false client_id_file_path = var.tfc_vault_backed_azure_dynamic_credentials.default.client_id_file_path client_secret_file_path = var.tfc_vault_backed_azure_dynamic_credentials.default.client_secret_file_path subscription_id = "00000000-0000-0000-0000-000000000000" tenant_id = "10000000-0000-0000-0000-000000000000"} provider "azuread" { features {} // use_cli should be set to false to yield more accurate error messages on auth failure. use_cli = false alias = "ALIAS1" client_id_file_path = var.tfc_vault_backed_azure_dynamic_credentials.aliases["ALIAS1"].client_id_file_path client_secret_file_path = var.tfc_vault_backed_azure_dynamic_credentials.aliases["ALIAS1"].client_secret_file_path subscription_id = "00000000-0000-0000-0000-000000000000" tenant_id = "20000000-0000-0000-0000-000000000000"}