From fc5abc2c60a0966f3fc8a60438234c9a420ce6f3 Mon Sep 17 00:00:00 2001 From: Angela Tran Date: Thu, 31 Aug 2023 00:31:07 +0000 Subject: [PATCH] refactor: split out pipeline into two stages second stage requires environment with approval check --- terraform/pipeline/azure-pipelines.yml | 93 +++++++++++++++++++++----- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/terraform/pipeline/azure-pipelines.yml b/terraform/pipeline/azure-pipelines.yml index 9ec60c77..80b7e172 100644 --- a/terraform/pipeline/azure-pipelines.yml +++ b/terraform/pipeline/azure-pipelines.yml @@ -10,12 +10,13 @@ trigger: paths: include: - terraform/* +pool: + vmImage: ubuntu-latest + stages: - - stage: terraform - pool: - vmImage: ubuntu-latest + - stage: TerraformPlan jobs: - - job: terraform + - job: Plan variables: - name: OTHER_SOURCE value: $[variables['System.PullRequest.SourceBranch']] @@ -28,7 +29,8 @@ stages: # https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-variables-scripts?view=azure-devops&tabs=bash#about-tasksetvariable - bash: | WORKSPACE=$(python terraform/pipeline/workspace.py) - echo "##vso[task.setvariable variable=workspace]$WORKSPACE" + echo "##vso[task.setvariable variable=workspace;isOutput=true]$WORKSPACE" + name: setvars displayName: Determine deployment environment env: REASON: $(Build.Reason) @@ -59,7 +61,7 @@ stages: provider: azurerm command: custom customCommand: workspace - commandOptions: select $(workspace) + commandOptions: select $(setvars.workspace) workingDirectory: "$(System.DefaultWorkingDirectory)/terraform" # service connection environmentServiceNameAzureRM: deployer @@ -70,21 +72,76 @@ stages: command: plan # wait for lock to be released, in case being used by another pipeline run # https://discuss.hashicorp.com/t/terraform-plan-wait-for-lock-to-be-released/6870/2 - commandOptions: -input=false -lock-timeout=5m + commandOptions: -input=false -lock-timeout=5m -out=$(Build.ArtifactStagingDirectory)/tfplan workingDirectory: "$(System.DefaultWorkingDirectory)/terraform" # service connection environmentServiceNameAzureRM: deployer # the plan is done as part of the apply (below), so don't bother doing it twice condition: notIn(variables['Build.SourceBranchName'], 'dev', 'test', 'prod') - - task: TerraformTaskV3@3 - displayName: Terraform apply - inputs: - provider: azurerm - command: apply - # (ditto the lock comment above) - commandOptions: -input=false -lock-timeout=5m - workingDirectory: "$(System.DefaultWorkingDirectory)/terraform" - # service connection - environmentServiceNameAzureRM: deployer - # only run on certain branches + # need to publish the tfplan to used by next stage if it's going to run + - publish: "$(Build.ArtifactStagingDirectory)" + displayName: "Publish tfplan for use in TerraformApply" + artifact: savedPlan condition: in(variables['Build.SourceBranchName'], 'dev', 'test', 'prod') + - stage: TerraformApply + dependsOn: TerraformPlan + variables: + - name: workspace + value: $[ dependencies.TerraformPlan.outputs['Plan.setvars.workspace'] ] + # only run on dev, test, or prod branches + condition: in(variables['Build.SourceBranchName'], 'dev', 'test', 'prod') + jobs: + - deployment: Apply + condition: succeeded() + environment: Approval + variables: + - name: workspace + value: $[ stageDependencies.TerraformPlan.Plan.outputs['setvars.workspace'] ] + strategy: + runOnce: + deploy: + steps: + - checkout: self + # https://github.com/microsoft/azure-pipelines-terraform/tree/main/Tasks/TerraformTask/TerraformTaskV3#readme + - download: current + displayName: "Download plan file published from TerraformPlan" + artifact: savedPlan + - task: TerraformInstaller@0 + displayName: Install Terraform + inputs: + terraformVersion: 1.3.1 + - task: TerraformTaskV3@3 + displayName: Terraform init + inputs: + provider: azurerm + command: init + workingDirectory: "$(System.DefaultWorkingDirectory)/terraform" + # https://developer.hashicorp.com/terraform/tutorials/automation/automate-terraform#automated-terraform-cli-workflow + commandOptions: -input=false + # service connection + backendServiceArm: deployer + # needs to match main.tf + backendAzureRmResourceGroupName: courtesy-cards-eligibility-terraform + backendAzureRmStorageAccountName: courtesycardsterraform + backendAzureRmContainerName: tfstate + backendAzureRmKey: terraform.tfstate + - task: TerraformTaskV3@3 + displayName: Select environment + inputs: + provider: azurerm + command: custom + customCommand: workspace + commandOptions: select $(workspace) + workingDirectory: "$(System.DefaultWorkingDirectory)/terraform" + # service connection + environmentServiceNameAzureRM: deployer + - task: TerraformTaskV3@3 + displayName: Terraform apply + inputs: + provider: azurerm + command: apply + # (ditto the lock comment above) + commandOptions: -input=false -lock-timeout=5m $(Pipeline.Workspace)/savedPlan/tfplan + workingDirectory: "$(System.DefaultWorkingDirectory)/terraform" + # service connection + environmentServiceNameAzureRM: deployer