Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a script access Service Connections? (Azure Devops Pipelines)

According to https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints there's a rich array of Service Connection types. I can easily manage a set of service connections at the project level and set permissions to limit which users are able to view/edit them -- this is all good.

But I can't figure out how to access a Service Connection with a script step in my build pipeline. For example, let's say I have a Service Connection representing credentials for an Azure Service Principal. I'd like to access those credentials in a script step.

How can I write a script step that makes use of them?

like image 944
Bosh Avatar asked Jul 27 '19 16:07

Bosh


People also ask

How do I give access to Azure DevOps pipelines?

In your project, go to Pipelines > Pipelines. Select Manage security from More actions . Modify the permissions associated with an Azure DevOps group (example: Build Administrators) or individual user. Set permissions by selecting Allow or Deny for the permission for a security group or an individual user.

What is the function of service connections in Azure DevOps?

A service connection, in simple terms, is a defined connection that allows Azure DevOps to communicate with an external service.

Where is service connection Azure DevOps?

In Azure DevOps, open the Service connections page from the project settings page. In TFS, open the Services page from the "settings" icon in the top menu bar. Choose + New service connection and select Azure Resource Manager. Choose Service Principal (manual) option and enter the Service Principal details.


2 Answers

Because a Service Connection involves data shaped specifically to the connected service (the Generic Service Connection being the exception that proves the rule...), you won't be able to make use of strongly typed properties in your Bash task. Instead, you may want to examine environment variables and process the service connection data manually.

Based on a survey of some of the tasks in the Azure DevOps repos, it appears that service connections and their data are populated as environment variables on the agent running the build task. The service connections are retrieved via a method that runs a given name string through the following regex before retrieving the resultant environment key's value:

process.env[name.replace(/\./g, '_').toUpperCase()];

The retrieval of various Service Endpoint data is wrapped in the vsts-task-lib/task module, allowing consuming tasks to write code like so:

taskLib.getEndpointAuthorization('SYSTEMVSSCONNECTION', false);  taskLib.getEndpointDataParameter('MYSERVICECONNECTION', 'SOME_PARAMETER_NAME', false);  taskLib.getEndpointUrl('MYSERVICECONNECTION', false) // <-- last param indicates required or not 

Therefore, if you wanted to access service connections in a bash script without any additional customization, I would recommend that you:

a) Validate the availability of service connection information in the build script task by iterating and writing environment variables, setting the system.debug environment variable. There's some indication that build tasks aren't "seeded" with connections they aren't requesting specifically, so you may need to create a custom build task which has as one of its' inputs the service connection name you want to use

b) read the desired values from variables as outlined above in your bash script. Service connection variable names may be computed similarly to this:

   var dataParam = getVariable('ENDPOINT_DATA_' + id + '_' + key.toUpperCase());   

You may need to iterate against this to determine the data schema/structure.

like image 163
Josh E Avatar answered Oct 02 '22 14:10

Josh E


I've been wondering about this too. The solution I've settled on is to use the 'Azure CLI' task rather than the basic 'Script' (or 'Bash') task. This is ostensibly for running Az CLI commands, but there's nothing to stop you running only standard Bash scripts (or PSCore if that's your thing).

If you examine the environment variables present when you run this task, you'll see a bunch of information about the Service Connection in variables prefixed with 'ENDPOINT_DATA_'. This tallies up with what Josh E was saying. It includes Azure Subscription ID, name, Service Principle Object ID, etc.

Optionally you can enable the Service Principle details to be added to the environment too. This will then include SPN key, TenantID, etc. as secret environment variables.

Here's what the tasks look like:

- task: AzureCLI@2   displayName: 'Azure CLI'   inputs:     scriptType: bash     scriptLocation: inlineScript     azureSubscription: '<Service Connection Name>'     inlineScript: |       env | sort  - task: AzureCLI@2   displayName: 'Azure CLI, with SPN info'   inputs:     scriptType: bash     scriptLocation: inlineScript     azureSubscription: '<Service Connection Name>'     addSpnToEnvironment: true     inlineScript: |       env | sort 

Of course this is all only applicable to Azure Cloud Service Connections. There might be similar techniques you could use for other Service Connections, but I haven't investigated them.

like image 22
Rich Lewis Avatar answered Oct 02 '22 13:10

Rich Lewis