I’ve been writing some terraform to create VMs in Azure and then install the Azure DevOps Build Agent service on it. Actually, I’ve not been writing it, I’ve taken this useful repo and made some modifications. Anyway, I want to run the terraform in an Azure Pipeline itself, written in yaml. However, to register the agent to Azure DevOps you need to specify a PAT, and storing it in the script would be bad, obviously. So it becomes necessary to have create a PAT and store it as a protected variable on the pipeline in Azure DevOps. Or something like stick it in a key vault and creataea variable group form the key vault. Either way this is a pain for several reasons, and creates an overhead that I find quite unappelaing; I’d like to be able to create a pipeline that deploys the terraform and then kind of forget about it, rather than have to recycle the token. And so but I found that there is a predefined variable called system.accesstoken that can be used where you would otherwise use a PAT. This is incredibly useful because what I have to do is give the project build service administration permissions on the agent pool (these need to be set at the organisation level, not the project level of the agent pool). So something like below would work.

  - script: |
       terraform apply -auto-approve -var "pat=$SYSTEM_ACCESSTOKEN"
    displayName: terraform apply
    workingDirectory: $(System.DefaultWorkingDirectory)/tf
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)
    condition: and(succeeded(), eq('${{ parameters.apply }}', true))

What I really like about this variable is that there have been times I want to access the API of Azure DevOps in a pipeline but need to create a PAT, and now I can use the system.accesstoken instead. This also means monitoring scripts can be written and executed on pipelines themselves. Handy!