From c6065ea2e86ad43024c4d4cdf36f3c8a48db0ccd Mon Sep 17 00:00:00 2001 From: Matt White <16320656+matt-FFFFFF@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:42:47 +0000 Subject: [PATCH] ci: migrate to oidc (#1262) --- .github/workflows/update-policy.yml | 16 ++++++-- tests/pipelines/templates/tests-backend.yml | 11 ++--- tests/pipelines/templates/tests-common.yml | 17 +++----- tests/pipelines/templates/tests-loop.yml | 43 +++++++++++++------- tests/pipelines/templates/tests-strategy.yml | 10 +++-- tests/pipelines/tests-e2e.yml | 2 +- tests/pipelines/tests-unit.yml | 2 +- tests/scripts/azp-backend.sh | 14 ++----- tests/scripts/azp-strategy.ps1 | 39 +----------------- tests/scripts/tf-destroy.sh | 8 ---- tests/scripts/tf-init.sh | 30 ++++++++------ tests/scripts/tf-prepare.sh | 34 ---------------- 12 files changed, 82 insertions(+), 144 deletions(-) diff --git a/.github/workflows/update-policy.yml b/.github/workflows/update-policy.yml index 958dda771..1e6ae2cfe 100644 --- a/.github/workflows/update-policy.yml +++ b/.github/workflows/update-policy.yml @@ -4,7 +4,7 @@ name: Update Library Templates # yamllint disable-line rule:truthy on: schedule: - - cron: "0 8 * * 1-5" + - cron: "0 8 * * 1" workflow_dispatch: inputs: enterprise-scale-repository-branch: @@ -42,11 +42,11 @@ jobs: path: ${{ env.remote_repository }} ref: ${{ env.remote_repository_branch }} - - uses: tibdex/github-app-token@v2 + - uses: actions/create-github-app-token@v1 id: generate-token with: - app_id: ${{ secrets.APP_ID }} - private_key: ${{ secrets.APP_PRIVATE_KEY }} + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} - name: Configure local git run: | @@ -106,6 +106,14 @@ jobs: git push origin ${{ env.branch_name }} working-directory: ${{ github.repository }} + - name: close and comment out of date prs + if: steps.git_status.outputs.changes > 0 + run: | + PULL_REQUESTS=$(gh pr list --search "${{ env.pr_title }}" --json number,headRefName) + echo "$PULL_REQUESTS" | jq -r '.[] | .number' | xargs -I {} gh pr close {} --delete-branch --comment "Out of date PR, closing and deleting branch" + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + - name: Create pull request if: steps.git_status.outputs.changes > 0 run: | diff --git a/tests/pipelines/templates/tests-backend.yml b/tests/pipelines/templates/tests-backend.yml index 0a84b53cb..6022e985f 100644 --- a/tests/pipelines/templates/tests-backend.yml +++ b/tests/pipelines/templates/tests-backend.yml @@ -1,10 +1,11 @@ --- steps: - - task: Bash@3 + - task: AzureCLI@2 name: prepare_backend displayName: "Prepare Backend Storage" inputs: - targetType: "inline" - script: "make azp-backend" - env: - ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) + azureSubscription: ado-mscet-cae-estf + scriptLocation: scriptPath + scriptPath: "tests/scripts/azp-backend.sh" + scriptType: bash + failOnStandardError: true diff --git a/tests/pipelines/templates/tests-common.yml b/tests/pipelines/templates/tests-common.yml index b26210907..c5fe640b8 100644 --- a/tests/pipelines/templates/tests-common.yml +++ b/tests/pipelines/templates/tests-common.yml @@ -11,16 +11,11 @@ steps: targetType: "inline" script: "make tf-install" - - task: GoTool@0 - displayName: "Install Go" - inputs: - version: "1.22.3" - condition: and(succeeded(), eq('${{ parameters.run_type }}', 'unit')) - - - task: Bash@3 + - task: AzureCLI@2 displayName: "Prepare Terraform Environment" inputs: - targetType: "inline" - script: "make tf-prepare" - env: - ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) + azureSubscription: ado-mscet-cae-estf + scriptLocation: scriptPath + scriptPath: "tests/scripts/tf-prepare.sh" + scriptType: bash + failOnStandardError: true diff --git a/tests/pipelines/templates/tests-loop.yml b/tests/pipelines/templates/tests-loop.yml index b3cd20b4c..5129fc0ff 100644 --- a/tests/pipelines/templates/tests-loop.yml +++ b/tests/pipelines/templates/tests-loop.yml @@ -6,41 +6,54 @@ parameters: type: string steps: - - task: Bash@3 + - task: AzureCLI@2 displayName: "[terraform init]" inputs: - targetType: "inline" - script: "make tf-init" + scriptType: bash + scriptLocation: scriptPath + scriptPath: "tests/scripts/tf-init.sh" + failOnStandardError: true + addSpnToEnvironment: true + azureSubscription: ado-mscet-cae-estf env: - ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) TEST_MODULE_PATH: "${{ parameters.module_path }}" condition: and(succeeded(), in('${{ parameters.run_type }}', 'unit', 'e2e', 'destroy')) - - task: Bash@3 + - task: AzureCLI@2 displayName: "[terraform plan]" inputs: - targetType: "inline" - script: "make tf-plan" + scriptType: bash + scriptLocation: scriptPath + scriptPath: "tests/scripts/tf-plan.sh" + failOnStandardError: true + addSpnToEnvironment: true + azureSubscription: ado-mscet-cae-estf env: - ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) TEST_MODULE_PATH: "${{ parameters.module_path }}" condition: and(succeeded(), in('${{ parameters.run_type }}', 'unit')) - - task: Bash@3 + - task: AzureCLI@2 displayName: "[terraform apply]" inputs: - targetType: "inline" - script: "make tf-apply" + scriptType: bash + scriptLocation: scriptPath + failOnStandardError: true + addSpnToEnvironment: true + scriptPath: "tests/scripts/tf-apply.sh" + azureSubscription: ado-mscet-cae-estf env: - ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) TEST_MODULE_PATH: "${{ parameters.module_path }}" condition: and(succeeded(), eq('${{ parameters.run_type }}', 'e2e')) - - task: Bash@3 + - task: AzureCLI@2 displayName: "[terraform destroy]" inputs: - targetType: "inline" - script: "make tf-destroy" + scriptType: bash + scriptLocation: scriptPath + failOnStandardError: true + addSpnToEnvironment: true + scriptPath: "tests/scripts/tf-destroy.sh" + azureSubscription: ado-mscet-cae-estf env: ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) TEST_MODULE_PATH: "${{ parameters.module_path }}" diff --git a/tests/pipelines/templates/tests-strategy.yml b/tests/pipelines/templates/tests-strategy.yml index d766b0df3..019fa8e70 100644 --- a/tests/pipelines/templates/tests-strategy.yml +++ b/tests/pipelines/templates/tests-strategy.yml @@ -1,11 +1,13 @@ --- steps: - - task: PowerShell@2 + - task: AzurePowerShell@5 name: build_strategy displayName: "Generate Build Strategy" inputs: - targetType: "inline" - script: "make azp-strategy" + azureSubscription: ado-mscet-cae-estf + scriptType: FilePath + scriptPath: "tests/scripts/azp-strategy.ps1" + failOnStandardError: true + azurePowerShellVersion: 'LatestVersion' # Adding version specification for clarity env: - ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET) BILLING_SCOPE: $(BILLING_SCOPE) diff --git a/tests/pipelines/tests-e2e.yml b/tests/pipelines/tests-e2e.yml index b1eb50ffd..ead159618 100644 --- a/tests/pipelines/tests-e2e.yml +++ b/tests/pipelines/tests-e2e.yml @@ -4,7 +4,7 @@ name: "Tests (E2E)" trigger: none pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 variables: - group: csu-tf-environment diff --git a/tests/pipelines/tests-unit.yml b/tests/pipelines/tests-unit.yml index 899e27b6d..d4142ee10 100644 --- a/tests/pipelines/tests-unit.yml +++ b/tests/pipelines/tests-unit.yml @@ -4,7 +4,7 @@ name: "Tests (Unit)" trigger: none pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 variables: - group: csu-tf-environment diff --git a/tests/scripts/azp-backend.sh b/tests/scripts/azp-backend.sh index 9cf403a4b..a2a5e357c 100755 --- a/tests/scripts/azp-backend.sh +++ b/tests/scripts/azp-backend.sh @@ -5,20 +5,9 @@ set -e # Shell Script # - Terraform Create or Update Azure Backend Storage # - -echo "==> Authenticating cli..." -az login \ - --service-principal \ - --tenant "$ARM_TENANT_ID" \ - --username "$ARM_CLIENT_ID" \ - --password "$ARM_CLIENT_SECRET" \ - --query [?isDefault] - echo "==> Setting active Subscription..." az account set \ --subscription "$ARM_SUBSCRIPTION_ID" -az account list \ - --query "[?isDefault]" echo "==> Create or update Resource Group..." RSG_NAME="$DEFAULT_PREFIX" @@ -40,6 +29,7 @@ SA_NAME=$( ) SA_ID=$( az storage account create \ + --only-show-errors \ --name "$SA_NAME" \ --resource-group "$RSG_NAME" \ --location "$PRIMARY_LOCATION" \ @@ -56,6 +46,7 @@ echo "##vso[task.setVariable variable=STORAGE_ACCOUNT_NAME;isOutput=true]$SA_NAM echo "==> Create or update Storage Account permissions..." az role assignment create \ + --only-show-errors \ --role 'Storage Blob Data Contributor' \ --assignee "$ARM_CLIENT_ID" \ --scope "$SA_ID" @@ -63,6 +54,7 @@ az role assignment create \ echo "==> Create or update Storage Account container..." SC_NAME="tfstate" az storage container create \ + --only-show-errors \ --name "$SC_NAME" \ --auth-mode 'login' \ --account-name "$SA_NAME" \ diff --git a/tests/scripts/azp-strategy.ps1 b/tests/scripts/azp-strategy.ps1 index 59798ed04..2f100f4c0 100755 --- a/tests/scripts/azp-strategy.ps1 +++ b/tests/scripts/azp-strategy.ps1 @@ -20,7 +20,6 @@ $ErrorActionPreference = "Stop" Write-Information "==> Generating Azure Pipelines Strategy Matrix..." -InformationAction Continue $jsonDepth = 4 -$terraformUrl = "https://api.github.com/repos/hashicorp/terraform/tags" function Get-RandomId { [CmdletBinding()] @@ -38,13 +37,7 @@ function Get-RandomId { # 1.3.* (latest 1) ######################################## -$terraformVersionsResponse = Invoke-RestMethod -Method Get -Uri $terraformUrl -FollowRelLink -$terraformVersionsAll = $terraformVersionsResponse.name -replace "v", "" - -$terraformVersions = @("1.7.0") -$terraformVersions += $terraformVersionsAll | Where-Object { $_ -match "^1(\.\d{1,2}){1,2}$" } | Select-Object -First 1 - -$terraformVersions = $terraformVersions | Sort-Object +$terraformVersions = @("1.11.0") $terraformVersionsCount = $terraformVersions.Count @@ -54,8 +47,7 @@ $terraformVersionsCount = $terraformVersions.Count # - Latest Versions: (latest 1) ####################################### -$azurermProviderVersionBase = "3.108.0" -$azurermProviderVersionLatest = "3.116.0" +$azurermProviderVersionBase = "3.117.0" ####################################### # Generate Subscription Aliases @@ -69,20 +61,6 @@ Import-Module -Name "Az.Accounts" -Force Write-Information "==> Getting Subscription Aliases..." -InformationAction Continue -Write-Verbose "Switching Azure Context using Client ID [$($env:ARM_CLIENT_ID)]." -$Credential = New-Object System.Management.Automation.PSCredential ( - $($env:ARM_CLIENT_ID), - $($env:ARM_CLIENT_SECRET | ConvertTo-SecureString -AsPlainText -Force) -) -$ctx = Connect-AzAccount ` - -ServicePrincipal ` - -Tenant $($env:ARM_TENANT_ID) ` - -SubscriptionId $($env:ARM_SUBSCRIPTION_ID) ` - -Credential $Credential ` - -WarningAction SilentlyContinue - -Write-Information " Successfully authenticated account ($($ctx.Context.Account.Id))." -InformationAction Continue - Write-Verbose "Checking for Management Subscription Aliases." $subscriptionAliasesManagement = [PSCustomObject]@{} for ($i = 1; $i -lt (($terraformVersionsCount * 2) + 1); $i++) { @@ -149,9 +127,7 @@ $matrixObject = [PSCustomObject]@{} for ($i = 0; $i -lt $terraformVersionsCount; $i++) { $terraformVersion = $terraformVersions[$i] $jobId1 = ($i * 2) + 1 - $jobId2 = ($i * 2) + 2 $jobName1 = "$jobId1. (TF: $terraformVersion, AZ: $azurermProviderVersionBase)" - $jobName2 = "$jobId2. (TF: $terraformVersion, AZ: $azurermProviderVersionLatest)" $matrixObject | Add-Member ` -NotePropertyName $jobName1 ` -NotePropertyValue @{ @@ -163,17 +139,6 @@ for ($i = 0; $i -lt $terraformVersionsCount; $i++) { TF_SUBSCRIPTION_ID_CONNECTIVITY = ($subscriptionAliasesConnectivity."csu-tf-connectivity-$jobId1") } Write-Information " Added job to matrix ($($jobName1))." -InformationAction Continue - $matrixObject | Add-Member ` - -NotePropertyName $jobName2 ` - -NotePropertyValue @{ - TF_ROOT_ID = Get-RandomId - TF_VERSION = $terraformVersion - TF_AZ_VERSION = $azurermProviderVersionLatest - TF_JOB_ID = $jobId2 - TF_SUBSCRIPTION_ID_MANAGEMENT = ($subscriptionAliasesManagement."csu-tf-management-$jobId2") - TF_SUBSCRIPTION_ID_CONNECTIVITY = ($subscriptionAliasesConnectivity."csu-tf-connectivity-$jobId2") - } - Write-Information " Added job to matrix ($($jobName2))." -InformationAction Continue } # Convert PSCustomObject to JSON. diff --git a/tests/scripts/tf-destroy.sh b/tests/scripts/tf-destroy.sh index 3dadb4a08..3febef135 100755 --- a/tests/scripts/tf-destroy.sh +++ b/tests/scripts/tf-destroy.sh @@ -24,14 +24,6 @@ status=$? if [ $status -ne 0 ]; then - echo "==> Authenticating cli..." - az login \ - --service-principal \ - --tenant "$ARM_TENANT_ID" \ - --username "$ARM_CLIENT_ID" \ - --password "$ARM_CLIENT_SECRET" \ - --query [?isDefault] - IFS=$'\n' TF_ROOT_ID=("$TF_ROOT_ID") diff --git a/tests/scripts/tf-init.sh b/tests/scripts/tf-init.sh index 97ff92d51..4d446ea8a 100755 --- a/tests/scripts/tf-init.sh +++ b/tests/scripts/tf-init.sh @@ -29,6 +29,9 @@ terraform { storage_account_name = "$STORAGE_ACCOUNT_NAME" container_name = "$STORAGE_CONTAINER_NAME" key = "terraform-$TF_ROOT_ID.tfstate" + use_azuread_auth = true + use_oidc = true + client_id = "$ARM_CERTIFICATE_CLIENT_ID" } } TFCONFIG @@ -37,30 +40,31 @@ echo "==> Creating providers_override.tf with subscription configuration and cre cat >providers_override.tf < Initializaing Terraform workspace..." +echo "==> Initializing Terraform workspace..." terraform init diff --git a/tests/scripts/tf-prepare.sh b/tests/scripts/tf-prepare.sh index 348c1d77b..8771b3e79 100755 --- a/tests/scripts/tf-prepare.sh +++ b/tests/scripts/tf-prepare.sh @@ -11,53 +11,19 @@ CREDENTIALS_WORKSPACE="$PIPELINE_WORKSPACE/s/tests" echo "==> Switching directories..." cd "$CREDENTIALS_WORKSPACE" -echo "==> Authenticating cli..." -az login \ - --service-principal \ - --tenant "$ARM_TENANT_ID" \ - --username "$ARM_CLIENT_ID" \ - --password "$ARM_CLIENT_SECRET" \ - --query [?isDefault] - echo "==> Creating SPN and Role Assignments..." SPN_NAME="ES-TestFramework-Job$TF_JOB_ID" -KEY_VAULT_NAME="$DEFAULT_PREFIX-kv" CERTIFICATE_CLIENT_ID=$( az ad sp create-for-rbac \ --name "$SPN_NAME" \ --role "Owner" \ --scope "/providers/Microsoft.Management/managementGroups/$ARM_TENANT_ID" \ - --keyvault "$KEY_VAULT_NAME" \ - --cert "$SPN_NAME" \ --only-show-errors \ --query 'appId' \ --out tsv ) -echo "==> Retrieving SPN certificate for authentication..." -az keyvault secret download \ - --file "$SPN_NAME.pem" \ - --vault-name "$KEY_VAULT_NAME" \ - --name "$SPN_NAME" - -echo "==> Generating SPN certificate password..." -CERTIFICATE_PASSWORD='estf-'"$RANDOM"'-'"$RANDOM"'-'"$RANDOM"'-'"$RANDOM"'-pwd' - -echo "==> Converting SPN certificate to PFX..." -openssl pkcs12 \ - -export \ - -in "$SPN_NAME.pem" \ - -out "$SPN_NAME.pfx" \ - -passout pass:"$CERTIFICATE_PASSWORD" - -echo "==> Deleting SPN certificate in PEM format..." -shred -uz "$SPN_NAME.pem" - -echo "==> Storing Client Certificate Details" echo "##vso[task.setvariable variable=ARM_CERTIFICATE_CLIENT_ID;]$CERTIFICATE_CLIENT_ID" -echo "##vso[task.setvariable variable=ARM_CERTIFICATE_PATH;]$CREDENTIALS_WORKSPACE/$SPN_NAME.pfx" -echo "##vso[task.setvariable variable=ARM_CERTIFICATE_PASSWORD;]$CERTIFICATE_PASSWORD" - echo "==> Terraform Variable (Root ID) - $TF_ROOT_ID" echo "==> Terraform Version - $TF_VERSION" echo "==> Terraform Provider Version - $TF_AZ_VERSION"