-
Notifications
You must be signed in to change notification settings - Fork 0
312 lines (275 loc) · 11.6 KB
/
deployment.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
name: Deployment
run-name: Deploy - ${{ inputs.environment == '' && 'dev' || inputs.environment }}
on:
workflow_dispatch:
inputs:
environment:
description: Which environment is being deployed?
required: true
default: test
type: choice
options:
- dev
- test
- prod
push:
branches:
- main
paths-ignore:
- '**/README.md'
- '**/.gitignore'
- './docs/**'
permissions:
contents: read
id-token: write
env:
DEFAULT_ENV: dev
TF_VERSION: =1.7.0
jobs:
env-vars:
name: Set Env Vars as Outputs
runs-on: ubuntu-latest
outputs:
AWS_ACCOUNT_ID: ${{ steps.set-outputs.outputs.aws_account_id }}
ENVIRONMENT: ${{ steps.set-outputs.outputs.environment }}
TF_VERSION: ${{ steps.set-outputs.outputs.tf_version }}
steps:
# this sets environment variable outputs consumed by downstream jobs
# this is needed because the 'env' context is not available to reusable workflows
- name: Set Output Values
id: set-outputs
run: |
# set environment output
if [ -n "${{ inputs.environment }}" ]; then
# will use environment input value when workflow_dispatch trigger is used
echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT
else
# this will default the environment for all other triggers
echo "environment=${DEFAULT_ENV}" >> $GITHUB_OUTPUT
fi
# set AWS Account ID output based on environment
if [ "${{ inputs.environment }}" == "test" ]; then
echo "aws_account_id=${{ vars.TEST_ACCOUNT_ID }}" >> $GITHUB_OUTPUT
elif [ "${{ inputs.environment }}" == "prod" ]; then
echo "aws_account_id=${{ vars.PROD_ACCOUNT_ID }}" >> $GITHUB_OUTPUT
else
echo "aws_account_id=${{ vars.DEV_ACCOUNT_ID }}" >> $GITHUB_OUTPUT
fi
# sets terraform version output
echo "tf_version=${TF_VERSION}" >> $GITHUB_OUTPUT
###################################################################
# These first few jobs must be run before the remaining TF stacks #
###################################################################
tf-plan-oidc:
name: Terraform Plan - OIDC
needs:
- env-vars
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_plan.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
role_name: GithubActionsRole-ReadOnly
stack_name: oidc
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }}
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
tf_backend_key: ${{ github.event.repository.name }}/oidc.tfstate
tfvars_path: ./environments/${{ needs.env-vars.outputs.ENVIRONMENT }}.tfvars
working_directory: infra/tf/stacks/oidc
tf-apply-oidc:
name: Terraform Apply - OIDC
if: ${{ needs.tf-plan-oidc.outputs.CHANGES_DETECTED == 'true' }}
needs:
- env-vars
- tf-plan-oidc
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
role_name: GithubActionsRole-Write
stack_name: oidc
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }}
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
tf_backend_key: ${{ github.event.repository.name }}/oidc.tfstate
working_directory: infra/tf/stacks/oidc
tf-plan-prereqs:
name: Terraform Plan - Prerequisite Stacks
if: ${{ !cancelled() && needs.tf-apply-oidc.result != 'failure' }}
needs:
- env-vars
- tf-apply-oidc
# Using the matrix strategy here because the 'env' context is not available
# This gives us the ability to define the stack name once and use many times in the inputs,
# or define multiple stack names and have the job run against each stack.
strategy:
fail-fast: false
matrix:
STACK_NAME:
- storage
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_plan.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
role_name: GithubActionsRole-ReadOnly
stack_name: ${{ matrix.STACK_NAME }}
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }}
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate
tfvars_path: ./environments/${{ needs.env-vars.outputs.ENVIRONMENT }}.tfvars
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }}
tf-apply-prereqs-matrix:
name: Set TF Apply Matrix - Prerequisite Stacks
if: ${{ !cancelled() && needs.tf-plan-prereqs.result == 'success' }}
needs: [ tf-plan-prereqs ]
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply_matrix.yml@v1
with:
stacks_to_ignore: oidc
tf-apply-prereqs:
name: Terraform Apply - Prerequisite Stacks
if: ${{ !cancelled() && needs.tf-apply-prereqs-matrix.outputs.MATRIX != 'skip' }}
needs:
- env-vars
- tf-apply-prereqs-matrix
strategy:
# The matrix values are coming from the `tf-apply-prereqs-matrix` job. The matrix will only
# consist of those stacks from the TF Plan job that showed changes and produced artifacts.
fail-fast: false
matrix: ${{ fromJson(needs.tf-apply-prereqs-matrix.outputs.MATRIX) }}
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
role_name: GithubActionsRole-Write
stack_name: ${{ matrix.STACK_NAME }}
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }}
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }}
build:
name: Build Lambda Package
strategy:
fail-fast: false
matrix:
LAMBDA_NAME:
- DownloadImage
- ReverseImage
uses: chrisba11/terraform-feature-stacks/.github/workflows/__build_python_lambda.yml@v1
with:
aws_region: ${{ vars.AWS_REGION }}
lambda_name: ${{ matrix.LAMBDA_NAME }}
python_version: 3.11
src_directory: src/lambdas/${{ matrix.LAMBDA_NAME }}
#####################################################
# These jobs must run after the preceding TF stacks #
#####################################################
deploy:
name: Deploy Lambda Package
if: ${{ !cancelled() && needs.build.result == 'success' && needs.tf-apply-prereqs.result != 'failure' }}
needs:
- env-vars
- build
- tf-apply-prereqs
strategy:
fail-fast: false
matrix:
LAMBDA_NAME:
- DownloadImage
- ReverseImage
uses: chrisba11/terraform-feature-stacks/.github/workflows/__upload_s3_object.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
bucket_name: ${{ vars.LAMBDA_PKG_BUCKET_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
object_key: ${{ matrix.LAMBDA_NAME }}_${{ needs.env-vars.outputs.ENVIRONMENT }}.zip
object_name: ${{ matrix.LAMBDA_NAME }}.zip
role_name: GithubActionsRole-Write
tf-plan:
name: Terraform Plan - Dependent Stacks
if: |
!cancelled() && needs.deploy.result == 'success' &&
needs.tf-apply-prereqs.result != 'failure'
needs:
- env-vars
- deploy
- tf-apply-prereqs
strategy:
fail-fast: false
matrix:
STACK_NAME:
- api
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_plan.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
role_name: GithubActionsRole-ReadOnly
stack_name: ${{ matrix.STACK_NAME }}
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }}
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate
tfvars_path: ./environments/${{ needs.env-vars.outputs.ENVIRONMENT }}.tfvars
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }}
tf-apply-matrix:
name: Set TF Apply Matrix - Dependent Stacks
if: ${{ !cancelled() && needs.tf-plan.result == 'success' }}
needs: [ tf-plan ]
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply_matrix.yml@v1
with:
stacks_to_ignore: oidc,storage
tf-apply:
name: Terraform Apply - Dependent Stacks
if: ${{ !cancelled() && needs.tf-apply-matrix.outputs.MATRIX != 'skip' }}
needs:
- env-vars
- tf-apply-matrix
strategy:
# The matrix values are coming from the `tf-apply-matrix` job. The matrix will only consist
# of those stacks from the TF Plan job that showed changes and produced artifacts.
fail-fast: false
matrix: ${{ fromJson(needs.tf-apply-matrix.outputs.MATRIX) }}
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply.yml@v1
with:
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}
aws_region: ${{ vars.AWS_REGION }}
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }}
role_name: GithubActionsRole-Write
stack_name: ${{ matrix.STACK_NAME }}
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }}
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }}
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }}
update:
name: Update Lambda
if: |
!cancelled() && needs.deploy.result == 'success' &&
needs.tf-apply.result != 'failure'
runs-on: ubuntu-latest
needs:
- env-vars
- deploy
- tf-apply
strategy:
fail-fast: false
matrix:
LAMBDA_NAME:
- DownloadImage
- ReverseImage
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}:role/GithubActionsRole-Write
aws-region: ${{ vars.AWS_REGION }}
role-duration-seconds: 900
role-session-name: ${{ github.event.repository.name }}+run=${{ github.run_id }}-${{ github.run_number }}+${{ github.triggering_actor }}
- name: Update Lambda Function Code
run: |
# triggers lambda function to use new updated zip archive
aws lambda update-function-code \
--function-name ${{ matrix.LAMBDA_NAME }}_${{ needs.env-vars.outputs.ENVIRONMENT }} \
--s3-bucket ${{ vars.LAMBDA_PKG_BUCKET_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} \
--s3-key ${{ matrix.LAMBDA_NAME }}_${{ needs.env-vars.outputs.ENVIRONMENT }}.zip