1
1
trigger :
2
- # automatically runs on pull requests
3
- # https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#pr-triggers
4
2
branches :
5
3
include :
6
4
- dev
7
5
- test
8
6
- prod
7
+ tags :
8
+ include :
9
+ - 20??.??.?*-rc?*
10
+ - 20??.??.?*
9
11
# only run for changes to Terraform files
10
12
paths :
11
13
include :
12
14
- terraform/*
15
+
16
+ pr :
17
+ branches :
18
+ include :
19
+ - " *"
20
+ paths :
21
+ include :
22
+ - terraform/*
23
+
24
+ pool :
25
+ vmImage : ubuntu-latest
26
+
13
27
stages :
14
- - stage : terraform
15
- pool :
16
- vmImage : ubuntu-latest
28
+ - stage : TerraformPlan
17
29
jobs :
18
- - job : terraform
30
+ - job : Plan
19
31
variables :
20
32
- name : OTHER_SOURCE
21
33
value : $[variables['System.PullRequest.SourceBranch']]
22
34
- name : INDIVIDUAL_SOURCE
23
35
value : $[variables['Build.SourceBranchName']]
36
+ - name : IS_TAG
37
+ value : $[startsWith(variables['Build.SourceBranch'], 'refs/tags/')]
24
38
- name : TARGET
25
39
value : $[variables['System.PullRequest.TargetBranch']]
26
40
steps :
27
41
# set the workspace variable at runtime (rather than build time) so that all the necessary variables are available, and we can use Python
28
42
# https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-variables-scripts?view=azure-devops&tabs=bash#about-tasksetvariable
29
43
- bash : |
30
44
WORKSPACE=$(python terraform/pipeline/workspace.py)
31
- echo "##vso[task.setvariable variable=workspace]$WORKSPACE"
45
+ echo "##vso[task.setvariable variable=workspace;isOutput=true]$WORKSPACE"
46
+
47
+ TAG_TYPE=$(python terraform/pipeline/tag.py)
48
+ echo "##vso[task.setvariable variable=tag_type;isOutput=true]$TAG_TYPE"
49
+ name: setvars
32
50
displayName: Determine deployment environment
33
51
env:
34
52
REASON: $(Build.Reason)
@@ -59,7 +77,7 @@ stages:
59
77
provider : azurerm
60
78
command : custom
61
79
customCommand : workspace
62
- commandOptions : select $(workspace)
80
+ commandOptions : select $(setvars. workspace)
63
81
workingDirectory : " $(System.DefaultWorkingDirectory)/terraform"
64
82
# service connection
65
83
environmentServiceNameAzureRM : deployer
@@ -70,21 +88,88 @@ stages:
70
88
command : plan
71
89
# wait for lock to be released, in case being used by another pipeline run
72
90
# https://discuss.hashicorp.com/t/terraform-plan-wait-for-lock-to-be-released/6870/2
73
- commandOptions : -input=false -lock-timeout=5m
74
- workingDirectory : " $(System.DefaultWorkingDirectory)/terraform"
75
- # service connection
76
- environmentServiceNameAzureRM : deployer
77
- # the plan is done as part of the apply (below), so don't bother doing it twice
78
- condition : notIn(variables['Build.SourceBranchName'], 'dev', 'test', 'prod')
79
- - task : TerraformTaskV3@3
80
- displayName : Terraform apply
81
- inputs :
82
- provider : azurerm
83
- command : apply
84
- # (ditto the lock comment above)
85
- commandOptions : -input=false -lock-timeout=5m
91
+ commandOptions : -input=false -lock-timeout=5m -out=$(Build.ArtifactStagingDirectory)/tfplan
86
92
workingDirectory : " $(System.DefaultWorkingDirectory)/terraform"
87
93
# service connection
88
94
environmentServiceNameAzureRM : deployer
89
- # only run on certain branches
90
- condition : in(variables['Build.SourceBranchName'], 'dev', 'test', 'prod')
95
+ # need to publish the tfplan to used by next stage if it's going to run
96
+ - publish : " $(Build.ArtifactStagingDirectory)"
97
+ displayName : " Publish tfplan for use in TerraformApply"
98
+ artifact : savedPlan
99
+ condition : |
100
+ or(
101
+ in(variables['Build.SourceBranchName'], 'dev', 'test', 'prod'),
102
+ eq(variables['setvars.tag_type'], 'test'),
103
+ eq(variables['setvars.tag_type'], 'prod')
104
+ )
105
+ - stage : TerraformApply
106
+ dependsOn : TerraformPlan
107
+ variables :
108
+ - name : workspace
109
+ value : $[ dependencies.TerraformPlan.outputs['Plan.setvars.workspace'] ]
110
+ - name : tag_type
111
+ value : $[ dependencies.TerraformPlan.outputs['Plan.setvars.tag_type'] ]
112
+ # only run on dev, test, or prod branches OR if it's a tag for test or prod
113
+ condition : |
114
+ or(
115
+ in(variables['Build.SourceBranchName'], 'dev', 'test', 'prod'),
116
+ eq(variables['tag_type'], 'test'),
117
+ eq(variables['tag_type'], 'prod')
118
+ )
119
+ jobs :
120
+ - deployment : Apply
121
+ condition : succeeded()
122
+ environment : Approval
123
+ variables :
124
+ - name : workspace
125
+ value : $[ stageDependencies.TerraformPlan.Plan.outputs['setvars.workspace'] ]
126
+ - name : tag_type
127
+ value : $[ stageDependencies.TerraformPlan.Plan.outputs['setvars.tag_type'] ]
128
+ strategy :
129
+ runOnce :
130
+ deploy :
131
+ steps :
132
+ - checkout : self
133
+ - download : current
134
+ displayName : " Download plan file published from TerraformPlan"
135
+ artifact : savedPlan
136
+ - task : TerraformInstaller@0
137
+ displayName : Install Terraform
138
+ inputs :
139
+ terraformVersion : 1.3.1
140
+ # https://github.com/microsoft/azure-pipelines-terraform/tree/main/Tasks/TerraformTask/TerraformTaskV3#readme
141
+ - task : TerraformTaskV3@3
142
+ displayName : Terraform init
143
+ inputs :
144
+ provider : azurerm
145
+ command : init
146
+ workingDirectory : " $(System.DefaultWorkingDirectory)/terraform"
147
+ # https://developer.hashicorp.com/terraform/tutorials/automation/automate-terraform#automated-terraform-cli-workflow
148
+ commandOptions : -input=false
149
+ # service connection
150
+ backendServiceArm : deployer
151
+ # needs to match main.tf
152
+ backendAzureRmResourceGroupName : courtesy-cards-eligibility-terraform
153
+ backendAzureRmStorageAccountName : courtesycardsterraform
154
+ backendAzureRmContainerName : tfstate
155
+ backendAzureRmKey : terraform.tfstate
156
+ - task : TerraformTaskV3@3
157
+ displayName : Select environment
158
+ inputs :
159
+ provider : azurerm
160
+ command : custom
161
+ customCommand : workspace
162
+ commandOptions : select $(workspace)
163
+ workingDirectory : " $(System.DefaultWorkingDirectory)/terraform"
164
+ # service connection
165
+ environmentServiceNameAzureRM : deployer
166
+ - task : TerraformTaskV3@3
167
+ displayName : Terraform apply
168
+ inputs :
169
+ provider : azurerm
170
+ command : apply
171
+ # (ditto the lock comment above)
172
+ commandOptions : -input=false -lock-timeout=5m $(Pipeline.Workspace)/savedPlan/tfplan
173
+ workingDirectory : " $(System.DefaultWorkingDirectory)/terraform"
174
+ # service connection
175
+ environmentServiceNameAzureRM : deployer
0 commit comments