Skip to content

Commit

Permalink
Update ADO Pipeline instructions (#813)
Browse files Browse the repository at this point in the history
* Update ADO Pipeline instructions

* Use parameter -Wait instead of while-loop

* Update ADOPS module version
  • Loading branch information
SimonWahlin authored Jul 12, 2023
1 parent 8d59db5 commit 061d024
Showing 1 changed file with 62 additions and 96 deletions.
158 changes: 62 additions & 96 deletions docs/wiki/Azure-Pipelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,123 +66,89 @@ $SubscriptionId = '<Value>'
$ARM_CLIENT_ID = '<Value>'
$ARM_CLIENT_SECRET = '<Value>'
# Create a new project
$Project = az devops project list --query "value[?name=='$ProjectName'].{name:name, id:id}" --organization "https://dev.azure.com/$Organization" | ConvertFrom-Json
if ($null -eq $Project) {
$Project = az devops project create --name $ProjectName --organization "https://dev.azure.com/$Organization" `
--query "{name:name, id:id}" | ConvertFrom-Json
$OrgParams = @{
Organization = $Organization
Project = $ProjectName
}
# Set the defaults for the local Azure Cli shell
az devops configure `
--defaults organization="https://dev.azure.com/$Organization" project="$ProjectName"
# Install the ADOPS PowerShell module
Install-Module -Name ADOPS -Scope CurrentUser -RequiredVersion '2.0.1' -Force
# Create a new repository from the AzOps Accelerator template repository
$Repo = az repos list --query "[?name=='$RepoName'].{name:name, id:id}" | ConvertFrom-Json
if ($null -eq $Repo) {
$Repo = az repos create --name $RepoName --query "{name:name, id:id}" | ConvertFrom-Json
# Connect to Azure DevOps (This will open a browser window for you to login)
Connect-ADOPS -Organization $Organization
# Create a new project and wait for it to be created
$Project = Get-ADOPSProject @OrgParams
if ($null -eq $Project) {
$Project = New-ADOPSProject -Name $ProjectName -Organization $Organization -Visibility Private -Wait
}
az repos import create `
--git-url "https://github.com/Azure/AzOps-Accelerator.git" --repository "$($Repo.name)"
$null = az repos update --repository $RepoName --default-branch 'main'
# Add a variable group for authenticating pipelines with Azure Resource Manager and record the id output
if ($ARM_CLIENT_SECRET) {
$VariableGroupId = az pipelines variable-group create `
--name 'credentials' `
--variables `
"ARM_TENANT_ID=$TenantId" "ARM_SUBSCRIPTION_ID=$SubscriptionId" "ARM_CLIENT_ID=$ARM_CLIENT_ID" `
--query 'id'
} else {
$VariableGroupId = az pipelines variable-group create `
--name 'credentials' `
--variables `
"ARM_TENANT_ID=$TenantId" "ARM_SUBSCRIPTION_ID=$SubscriptionId" "ARM_CLIENT_ID=$ARM_CLIENT_ID" "ARM_CLIENT_SECRET=$ARM_CLIENT_SECRET" `
--query 'id'
# Create a new repository from the AzOps Accelerator template repository
try {
$Repo = Get-ADOPSRepository @OrgParams -Repository $RepoName
}
catch {
$Repo = New-ADOPSRepository @OrgParams -Name $RepoName
}
$ConfigVariableGroupId = az pipelines variable-group create `
--name 'azops' `
--variables `
"AZOPS_MODULE_VERSION=" "AZOPS_CUSTOM_SORT_ORDER=false" `
--query 'id'
# Import the AzOps Accelerator template repository and wait for the import to complete
$null = Import-ADOPSRepository @OrgParams -RepositoryName $RepoName -GitSource 'https://github.com/Azure/AzOps-Accelerator.git' -Wait
$null = Set-ADOPSRepository -RepositoryId $repo.id -DefaultBranch 'main' @OrgParams
# Add a secret to the variable group just created using id from above if using service principal
# Add a variable group for authenticating pipelines with Azure Resource Manager and record the id output
$CredentialVariableGroup = @(
@{Name = 'ARM_TENANT_ID'; Value = $TenantId; IsSecret = $false }
@{Name = 'ARM_SUBSCRIPTION_ID'; Value = $SubscriptionId; IsSecret = $false }
@{Name = 'ARM_CLIENT_ID'; Value = $ARM_CLIENT_ID; IsSecret = $false }
)
if ($ARM_CLIENT_SECRET) {
az pipelines variable-group variable create `
--id $VariableGroupId --name 'ARM_CLIENT_SECRET' --secret true --value $ARM_CLIENT_SECRET
$CredentialVariableGroup += @{Name = 'ARM_CLIENT_SECRET'; Value = $ARM_CLIENT_SECRET; IsSecret = $true }
}
$null = New-ADOPSVariableGroup -VariableGroupName 'credentials' -VariableHashtable $CredentialVariableGroup @OrgParams
# Create three new pipelines from existing YAML manifests.
az pipelines create --skip-first-run true `
--name 'AzOps - Push' --branch main --repository "$RepoName" --repository-type tfsgit --yaml-path .pipelines/push.yml
az pipelines create --skip-first-run true `
--name 'AzOps - Pull' --branch main --repository "$RepoName" --repository-type tfsgit --yaml-path .pipelines/pull.yml
$ConfigVariableGroup = @(
@{Name = 'AZOPS_MODULE_VERSION'; Value = ''; IsSecret = $false }
@{Name = 'AZOPS_CUSTOM_SORT_ORDER'; Value = 'false'; IsSecret = $false }
)
$null = New-ADOPSVariableGroup -VariableGroupName 'azops' -VariableHashtable $ConfigVariableGroup @OrgParams
az pipelines create --skip-first-run true `
--name 'AzOps - Validate' --branch main --repository "$RepoName" --repository-type tfsgit --yaml-path .pipelines/validate.yml
# Create three new pipelines from existing YAML manifests.
$null = New-ADOPSPipeline -Name 'AzOps - Push' -YamlPath '.pipelines/push.yml' -Repository $RepoName @OrgParams
$null = New-ADOPSPipeline -Name 'AzOps - Pull' -YamlPath '.pipelines/pull.yml' -Repository $RepoName @OrgParams
$null = New-ADOPSPipeline -Name 'AzOps - Validate' -YamlPath '.pipelines/validate.yml' -Repository $RepoName @OrgParams
# Add build validation policy to validate pull requests
az repos policy build create --blocking true --branch main `
--build-definition-id (az pipelines show --name 'AzOps - Validate' --query 'id') `
--display-name 'Validate' --enabled true --queue-on-source-update-only false `
--repository-id (az repos list --query "[?name=='$RepoName'].id" -o tsv) `
--manual-queue-only false --valid-duration 0 --path-filter '/root/*'
$RepoId = Get-ADOPSRepository -Repository $RepoName @OrgParams | Select-Object -ExpandProperty Id
$PipelineId = Get-ADOPSPipeline -Name 'AzOps - Validate' @OrgParams | Select-Object -ExpandProperty Id
$BuildPolicyParam = @{
RepositoryId = $RepoId
Branch = 'main'
PipelineId = $PipelineId
Displayname = 'Validate'
filenamePatterns = '/root/*'
}
$null = New-ADOPSBuildPolicy @BuildPolicyParam @OrgParams
# Add branch policy to limit merge types to squash only
az repos policy merge-strategy create --blocking true --branch main `
--repository-id (az repos list --query "[?name=='$RepoName'].id" -o tsv) --enabled true `
--allow-no-fast-forward false --allow-rebase false --allow-rebase-merge false `
--allow-squash true
$null = New-ADOPSMergePolicy -RepositoryId $RepoId -Branch 'main' -allowSquash @OrgParams
# Add permissions for the Build Service account to the git repository
$AzureDevOpsGlobalAppId = '499b84ac-1321-427f-aa17-267ca6975798'
$AzureReposSecurityNamespaceId = '2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87'
$ProjectId = az devops project list --query "value[?name=='$ProjectName'].id" -o tsv
$RepoId = az repos list --query "[?name=='$RepoName'].id" -o tsv
$QueryStrings = "searchFilter=General&queryMembership=None&api-version=6.0&filtervalue=$ProjectName Build Service ($Organization)"
$Uri = "`"https://vssps.dev.azure.com/$Organization/_apis/identities?$QueryStrings`""
$Subject = az rest --method get --uri $Uri --resource $AzureDevOpsGlobalAppId -o json | ConvertFrom-Json
$Body = @{
token = "repov2/$ProjectId/$RepoId"
merge = $true
accessControlEntries = @(
@{
# Contribute: 4
# Force push: 8
# CreateBranch: 16
# Contribute to pull requests: 16384
# Bypass policies when completing pull requests: 32768
allow = 4 + 8 + 16 + 16384 + 32768
deny = 0
descriptor = $Subject.value.descriptor
}
)
} | ConvertTo-Json -Compress | ConvertTo-Json # Convert to json twice to properly escape characters for Python interpreter
$Uri = "`"https://dev.azure.com/$Organization/_apis/accesscontrolentries/${AzureReposSecurityNamespaceId}?api-version=6.0`""
az rest --method post --uri $Uri --body $Body --resource $AzureDevOpsGlobalAppId -o json
$ProjectId = Get-ADOPSProject @OrgParams | Select-Object -ExpandProperty Id
$BuildAccount = Get-ADOPSUser -Organization $Organization |
Where-Object displayName -eq "$ProjectName Build Service ($Organization)"
foreach ($permission in 'GenericContribute', 'ForcePush', 'CreateBranch', 'PullRequestContribute', 'PullRequestBypassPolicy') {
$null = Set-ADOPSGitPermission -ProjectId $ProjectId -RepositoryId $RepoId -Descriptor $BuildAccount.descriptor -Allow $permission
}
# Add pipeline permissions for all three pipelines to the credentials Variable Groups
$AzureDevOpsGlobalAppId = '499b84ac-1321-427f-aa17-267ca6975798'
$Pipelines = az pipelines list --query "[? contains(name,'AzOps')].{id:id,name:name}" | ConvertFrom-Json
$Body = @(
@{
resource = @{}
pipelines = @(
foreach ($pipeline in $Pipelines) {
@{
id = $pipeline.id
authorized = $true
}
}
)
$Uri = "https://dev.azure.com/$Organization/$ProjectName/_apis/distributedtask/variablegroups?api-version=7.1-preview.2"
$VariableGroups = (Invoke-ADOPSRestMethod -Uri $Uri -Method 'Get').value | Where-Object name -in 'credentials', 'azops'
foreach ($pipeline in 'AzOps - Push', 'AzOps - Pull', 'AzOps - Validate') {
$PipelineId = Get-ADOPSPipeline -Name $pipeline @OrgParams | Select-Object -ExpandProperty Id
foreach ($groupId in $VariableGroups.id) {
$null = Grant-ADOPSPipelinePermission -PipelineId $PipelineId -ResourceType 'VariableGroup' -ResourceId $groupId @OrgParams
}
) | ConvertTo-Json -Depth 5 -Compress | ConvertTo-Json # Convert to json twice to properly escape characters for Python interpreter
foreach($groupName in 'credentials','azops') {
$VariableGroup = az pipelines variable-group list --query "[?name=='$groupName'].{id:id,name:name}" | ConvertFrom-Json
$Uri = "`"https://dev.azure.com/$Organization/$ProjectName/_apis/pipelines/pipelinepermissions/variablegroup/$($VariableGroup.id)?api-version=6.1-preview.1`""
az rest --method patch --uri $Uri --body $Body --resource $AzureDevOpsGlobalAppId -o json
}
```

Expand Down

0 comments on commit 061d024

Please sign in to comment.