It is confusing trying to understand which authentication method to use in terraform especially when there's concepts like managed identity and oidc. What is the difference and how to use it?
OIDC authentication using Azure Devops task
1. Setup service connection and federate:-
Prereq
1. Do you need to grant project collection admin to this service account
No you don't but you need to provide it with BASIC license access.
2. Do you need to federate it to the workload identity?
Yes you do - if you use Azure Devops service connection, it setup the federation automatically for you. Then if you go into the Certificate secret -> You will see this configuration in the "Federated" credential.
Setting up managed identity manual:
2. Setting up terraform
$idToken is generated automatically as documented here and this is passed to ARM_OIDC_TOKEN.
from terraform perspective ARM_USE_OIDC = true
Given that this step uses AzureCLI@2 - and the azureSubscription is configured to a service connection - it will use this service principal as the ID.
If it is a batch script, then it will use the workload identity instead.
- task: AzureCLI@2
inputs:
azureSubscription: $(SERVICE_CONNECTION_ID) ### Your will be using token generated by this service principal
scriptType: bash
scriptLocation: "inlineScript"
inlineScript: |
export ARM_CLIENT_ID=$servicePrincipalId
export ARM_SUBSCRIPTION_ID=$(az account show | jq -r '.id')
export ARM_TENANT_ID=$(az account show | jq -r '.tenantId')
#check the service connection using workload identity federation authentication or service principal authentication
#if using service principal authentication, will require the servicePrincipalKey
if [[ -z "${idToken}" ]]; then
echo "workload identity federation token is undefined"
export ARM_CLIENT_SECRET=$servicePrincipalKey
else
echo "workload identity federation token is defined"
export ARM_USE_OIDC=true
export ARM_OIDC_TOKEN=$idToken
fi
terraform init
trraform plan ........
terraform apply ......
env:
ARM_USE_OIDC: true
Some common questionDo you need service principal federation for this?
No you don't
Why account you will be using under here to create resources?
Service connection that you created for your Azure Devops project that is specified in AzureSubscription parameters.
I only have to provide ARM_USE_OIDC=true?
No, not really, you still need to configure ARM_CLIENT_ID, ARM_SUBSCRIPTION and ARM_TENANT_ID as shown above.
When is this setup or approach make sense?
In a normal context, service connection gets created with their own service principal to manage Azure resources in that specific project. So we wanted least privileged permission given and restrict that to a resource group instead of a subscription - so it cannot overwrite other Azure resources for another project.
In the workload identity setup context, this is to say, I have a agent running in my k8s cluster that has the permission to do things in Azure and I just need to specify which agent I would like to use. So this would work if you decided to go with agent pool as the way to managed your Azure resource.
Comments