I have a Azure DevOps YAML pipeline and want to deploy resources with Terraform to Azure. As first step I need to run terraform init. For that I want to use TerraformTaskV4
(https://github.com/microsoft/azure-pipelines-terraform/blob/main/Tasks/TerraformTask/TerraformTaskV4/README.md):
- task: TerraformTaskV4@4
displayName: Initialize Terraform
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'your-backend-service-connection'
backendAzureRmResourceGroupName: 'your-rg-name'
backendAzureRmStorageAccountName: 'your-stg-name'
backendAzureRmContainerName: 'your-container-name'
backendAzureRmKey: 'state.tfstate'
But there are two challenges:
- I want to use another Azure subscription than related to the service connection. The service principal of the service connection has access to multiple subscriptions
- I am using a service connection with a service principal leveraging Workflow Identity Federation
How can I run terraform init accordingly?
2
Answers
TerraformTaskV4@4
. It always takes the subscription related to the service connection. Therefore I switched to usingAzureCLI@2
(https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-cli-v2?view=azure-pipelines)addSpnToEnvironment
) in theAzureCLI@2
task and add the environment variables (https://developer.hashicorp.com/terraform/language/backend/azurerm#backend-azure-ad-service-principal-or-user-assigned-managed-identity-via-oidc-workload-identity-federation) to the environment. This has to happen in a first and separate task. Then you can create a subsequent task (in the same job) for e.g. terraform initExample:
If all of your Azure subscriptions are in the same Microsoft Entra ID tenant, you also can consider using Azure management group:
Create a management group in your tenant on Azure Portal. Assign the service principal with the
Reader
role at least on the new management group.Move all of your Azure subscriptions into the new management group.
Go to Azure DevOps to create a new ARM connection (Azure Resource Manager service connection) using workload identity federation. Since you have an existing service principal, you can select "Workload Identity federation (manual)".
Give a customized name to the new ARM connection to complete Step 1. Click "
Next
" to start Step 2.Open the existing service principal on Azure Portal. Go to "Certificates & secrets" > "Federated credentials" tab to add a new credential. Fill in the required information on the new credential.
Other issuer
Back to the new ARM connection window to finish Step 2.
Management Group
".Application (client) ID
of the service principal.Tenant ID
of the your tenant.After above configuration, you can use the new ARM connection on the TerraformTaskV4@4 task and specify the Azure subscription ID like as below:
Directly specify the subscription ID using the command argument "
-backend-config=subscription_id=xxxx
" on the task.Set the subscription ID as the environment variable. Since the pipeline variables will be automatically mapped as environment variables (except secret variables), you can directly define a pipeline variable with the name "
ARM_SUBSCRIPTION_ID
" and set the subscription ID as the value.