Skip to content

Automate Docker Service Connection #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This repo contains a few [PowerShell](https://github.com/PowerShell/PowerShell)

- Configure Terraform [azuread](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs#authenticating-to-azure-active-directory)/[azurerm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure) provider `ARM_*` environment variables to use the [AzureCLI](https://learn.microsoft.com/azure/devops/pipelines/tasks/reference/azure-cli-v2?view=azure-pipelines) task [Service Connection](https://learn.microsoft.com/azure/devops/pipelines/library/connect-to-azure?view=azure-devops):
[set_terraform_azurerm_vars.ps1](scripts/azure-devops/set_terraform_azurerm_vars.ps1)
- Create Managed Identity for Service Connection with Workload identity federation: [create_azurerm_msi_oidc_service_connection.ps1](scripts/azure-devops/create_azurerm_msi_oidc_service_connection.ps1)
- Create Managed Identity and (Azure or Docker Registry) Service Connection with Workload identity federation: [create_azure_msi_oidc_service_connection.ps1](scripts/azure-devops/create_azure_msi_oidc_service_connection.ps1)
- List identities for Azure DevOps Service Connections in Entra ID pertaining to Azure DevOps organization and (optionally) project: [list_service_connection_identities.ps1](scripts/azure-devops/list_service_connection_identities.ps1)
- List Azure DevOps Service Connections in an Azure DevOps organization and project: [list_service_connections.ps1](scripts/azure-devops/list_service_connections.ps1)
- 'Pretty-name' Entra ID applications created for Service Connections, so the Service Connection name is included in the application display name: [rename_service_connection_applications.ps1](scripts/azure-devops/rename_service_connection_applications.ps1)
Expand Down
83 changes: 64 additions & 19 deletions scripts/azure-devops/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,16 @@ variables:
value: true
- name: AZURE_EXTENSION_USE_DYNAMIC_INSTALL
value: yes_without_prompt
- name: acrName
value: ciacr$(Build.BuildId)
- name: acrServiceConnectionToCreate
value: oidc-msi-test-acr-$(Build.BuildId)
- name: azureServiceConnectionToCreate
value: oidc-msi-test-$(Build.BuildId)
- name: scriptDirectory
value: $(Build.SourcesDirectory)/scripts/azure-devops
- name: organizationName
value: ${{ split(variables['System.CollectionUri'],'/')[3] }}
- name: serviceConnectionToCreate
value: oidc-msi-test-$(Build.BuildId)
# TODO: Convert multiple service connections
- name: serviceConnectionToConvert
value: oidc-convert-test-$(Build.BuildId)

Expand Down Expand Up @@ -178,7 +181,7 @@ jobs:
Write-Host "##vso[task.setvariable variable=scopeResourceGroupName;isOutput=true]${scopeResourceGroupName}"

- task: AzureCLI@2
displayName: 'Create Managed Identity and Service Connection'
displayName: 'Create Managed Identity and Azure Service Connection'
name: identity
inputs:
azureSubscription: '$(azureConnectionWIF)'
Expand All @@ -195,11 +198,55 @@ jobs:

Get-ChildItem -Path Env: -Force -Recurse -Include * | Sort-Object -Property Name | Format-Table -AutoSize | Out-String
}
./create_azurerm_msi_oidc_service_connection.ps1 -IdentityName ${{ variables['organizationName'] }}-service-connection-test-$(Build.BuildId) `
-IdentityResourceGroupName $(resourceGroup.managedIdentityResourceGroupName) `
-IdentitySubscriptionId $(az account show --query id -o tsv) `
-ServiceConnectionName $(serviceConnectionToCreate) `
-ServiceConnectionScope $(resourceGroup.scopeResourceGroupId)
./create_azure_msi_oidc_service_connection.ps1 -IdentityName ${{ variables['organizationName'] }}-service-connection-test-$(Build.BuildId) `
-IdentityResourceGroupName $(resourceGroup.managedIdentityResourceGroupName) `
-IdentitySubscriptionId $(az account show --query id -o tsv) `
-ServiceConnectionName $(azureServiceConnectionToCreate) `
-ServiceConnectionRole Reader `
-ServiceConnectionScope $(resourceGroup.scopeResourceGroupId) `
-ServiceConnectionType AzureRM

az identity list -g $(resourceGroup.managedIdentityResourceGroupName) `
--query [0].clientId `
-o tsv `
| Set-Variable -Name clientId
Write-Host "##vso[task.setvariable variable=clientId;isOutput=true]${clientId}"

workingDirectory: '$(scriptDirectory)'

- task: AzureCLI@2
displayName: 'Create ACR, Managed Identity and Docker Registry Service Connection'
name: acrIdentity
inputs:
azureSubscription: '$(azureConnectionWIF)'
failOnStandardError: true
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
if ($env:SYSTEM_DEBUG -eq "true") {
$InformationPreference = "Continue"
$VerbosePreference = "Continue"
$DebugPreference = "Continue"

Set-PSDebug -Trace 1

Get-ChildItem -Path Env: -Force -Recurse -Include * | Sort-Object -Property Name | Format-Table -AutoSize | Out-String
}
Write-Host "Creating Azure Container Registry.."
az acr create --resource-group $(resourceGroup.scopeResourceGroupName) `
--name $(acrName) `
--sku Basic `
-o json `
| ConvertFrom-Json `
| Tee-Object -Variable acr

./create_azure_msi_oidc_service_connection.ps1 -IdentityName ${{ variables['organizationName'] }}-service-connection-test-$(Build.BuildId) `
-IdentityResourceGroupName $(resourceGroup.managedIdentityResourceGroupName) `
-IdentitySubscriptionId $(az account show --query id -o tsv) `
-ServiceConnectionName $(acrServiceConnectionToCreate) `
-ServiceConnectionRole AcrPull `
-ServiceConnectionScope $acr.id `
-ServiceConnectionType dockerregistry

az identity list -g $(resourceGroup.managedIdentityResourceGroupName) `
--query [0].clientId `
Expand All @@ -220,7 +267,7 @@ jobs:

steps:
- task: AzureCLI@2
displayName: 'Test Service Connection $(serviceConnectionToCreate)'
displayName: 'Test Azure Service Connection $(azureServiceConnectionToCreate)'
timeoutInMinutes: 5
inputs:
azureSubscription: '$(azureConnectionWIF)'
Expand All @@ -229,7 +276,7 @@ jobs:
scriptLocation: inlineScript
workingDirectory: '$(scriptDirectory)'
inlineScript: |
./test_service_connection.ps1 -ServiceConnectionName $(serviceConnectionToCreate) `
./test_service_connection.ps1 -ServiceConnectionName $(azureServiceConnectionToCreate) `
-ServiceConnectionTestPipelineId $(serviceConnectionTestPipelineId)

- ${{ if or(eq(parameters.jobsToRun, 'Non-modifying tests'),eq(parameters.jobsToRun, 'Both')) }}:
Expand Down Expand Up @@ -338,7 +385,8 @@ jobs:
# convertedServiceConnectionId1: $[ dependencies.convertServiceConnection.outputs['job1.convert.serviceConnectionId'] ]
# convertedServiceConnectionId2: $[ dependencies.convertServiceConnection.outputs['job2.convert.serviceConnectionId'] ]
convertedServiceConnectionId: $[ dependencies.convertServiceConnection.outputs['convert.serviceConnectionId'] ]
createdClientId: $[ dependencies.createServiceConnection.outputs['identity.clientId'] ]
createdAzureClientId: $[ dependencies.createServiceConnection.outputs['identity.clientId'] ]
createdACRClientId: $[ dependencies.createServiceConnection.outputs['acrIdentity.clientId'] ]
steps:
- task: AzureCLI@2
name: teardownAzure
Expand Down Expand Up @@ -390,14 +438,11 @@ jobs:
$ErrorActionPreference = "Continue" # Continue to remove resources if remove by resource group fails
az devops configure --defaults organization="$(System.CollectionUri)" project="$(System.TeamProject)"

az devops service-endpoint list --query "[?authorization.parameters.serviceprincipalid=='$(createdClientId)'].id" `
az devops service-endpoint list --query "[?authorization.parameters.serviceprincipalid=='$(createdAzureClientId)' || authorization.parameters.serviceprincipalid=='$(createdACRClientId)'].id" `
-o tsv `
| Set-Variable -Name serviceConnectionId
if (!$serviceConnectionId) {
Write-Host "No created service connections to remove"
exit 0
} else {
Write-Host "Removing created service connection ${serviceConnectionId}..."
| Set-Variable -Name serviceConnectionIds
foreach ($serviceConnectionId in $serviceConnectionIds) {
Write-Host "Removing service connection ${serviceConnectionId}..."
&{ # az writes information to stderr
$ErrorActionPreference = 'SilentlyContinue'
az devops service-endpoint delete --id $serviceConnectionId --yes 2>&1
Expand Down
Loading
Loading