-
Notifications
You must be signed in to change notification settings - Fork 92
453 lines (385 loc) · 13.9 KB
/
pipeline.yaml
File metadata and controls
453 lines (385 loc) · 13.9 KB
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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
name: DCE deploy to environment
on:
workflow_call:
inputs:
environment:
required: true
type: string
description: "The environment to deploy to (e.g. nonprod, prod)"
default: "nonprod"
branch:
required: false
type: string
default: master
release:
required: false
type: string
default: none
go_version:
required: false
type: string
default: "1.21.6"
terraform_version:
required: false
type: string
default: "1.7.4"
secrets:
AWS_DEFAULT_REGION:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
DCE_NONPROD_HOSTNAME:
required: true
NOTIFY_EMAIL:
required: true
jobs:
TestAndBuild:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: ${{ inputs.terraform_version }}
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: ${{ inputs.go_version }}
- name: Set up Golang CI Tools
run: ./scripts/install_ci.sh
- name: Checkout repository
uses: actions/checkout@v2
- name: Build Go executables
run: make build
- name: Publish build artifacts (bin)
uses: actions/upload-artifact@v4
with:
name: bin
path: bin
- name: Publish build artifacts (deploy_scripts)
uses: actions/upload-artifact@v4
with:
name: deploy_scripts
path: scripts
Deploy:
needs: [TestAndBuild]
runs-on: ubuntu-latest
environment: nonprod
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Configure namespace
run: |
if [[ "${{ github.event.pull_request.number }}" != "" ]]; then
NS="github-pr-${{ github.event.pull_request.number }}"
else
NS="cd"
fi
echo "Namespace is ${NS}"
echo "namespace=${NS}" >> $GITHUB_ENV
echo "${NS}" > ./namespace.txt
- name: Upload namespace file
uses: actions/upload-artifact@v4
with:
name: namespace
path: namespace.txt
- name: Configure AWS Namespace
env:
PR_NUMBER: ${{ github.event.number }}
# This is the branch name, or the git tag name
NS_BRANCH_OR_TAG: ${{ github.ref_name }}
run: |
echo "PR_NUMBER=${{ env.PR_NUMBER }}"
echo "NS_BRANCH_OR_TAG=${{ env.NS_BRANCH_OR_TAG }}"
- name: Set up the Go workspace
uses: actions/setup-go@v2
with:
go-version: ${{ inputs.go_version }}
go-path: ${{ github.workspace }}/gopath
go-bin: ${{ github.workspace }}/gopath/bin
- name: Download pipeline dependencies
run: |
set -ex
echo "${{ github.workspace }}/gopath/bin" >> $GITHUB_PATH
echo "${{ runner.tool_cache }}/go/bin" >> $GITHUB_PATH
go install github.com/jstemmer/go-junit-report@latest
# Download dce-cli
wget -q https://github.com/Optum/dce-cli/releases/download/v0.5.0/dce_linux_amd64.zip
# Validate checksum
expected_sha="cb140c743373e28a6c1bd4ba3fe1b81a7431dd538e1ad430fede3c1aff4508db"
test $(shasum -a 256 ./dce_linux_amd64.zip | awk '{print $1}') == "${expected_sha}"
unzip ./dce_linux_amd64.zip -d ./
# Lease a DCE account, to use for deploying our PR environment
# (deploy DCE in DCE)
- name: Lease DCE Account
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: us-east-1
NAMESPACE: ${{ env.namespace }}
DCE_NONPROD_HOSTNAME: ${{secrets.DCE_NONPROD_HOSTNAME}}
run: |
set -ex
echo "Principal ID is ${NAMESPACE}"
echo "Configuring the dce-cli"
echo "
api:
host: ${{ secrets.DCE_NONPROD_HOSTNAME }}
basepath: /api
region: us-east-1
" > ./dce.yml
# Check to see if there's an active lease for this PR
lease_id=$(
./dce --config=dce.yml leases list \
-p ${NAMESPACE} -s Active | \
jq -r '.[].id'
)
if [ ! "${lease_id}" ]; then
echo "No lease exists for ${NAMESPACE}. Creating one..."
created_lease=$(
./dce --config=dce.yml leases create \
--principal-id ${NAMESPACE} \
--expires-on 2d \
--budget-amount 100 --budget-currency USD \
--email noreply@example.com
)
echo "Created lease: ${created_lease}"
lease_id=$(echo "${created_lease}" | jq -r .id)
fi
echo "Using lease for PrincipalId=${NAMESPACE}, Id=${lease_id}"
echo "Logging into the DCE account"
./dce --config=dce.yml leases login ${lease_id}
# Save the lease ID to a file, so we can reference it later
# (note that we can't assign variables across jobs in different stages)
echo "${lease_id}" > ./lease_id.txt
# Install Terraform
- name: Install Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: ${{ inputs.terraform_version }}
# Configure the Terraform backend
- name: Configure Terraform Backend
run: |
lease_id=$(cat lease_id.txt)
./scripts/create-tf-backend.sh ${lease_id}
# terraform init
- name: Terraform Init/Apply
env:
NAMESPACE: ${{ env.namespace }}
NOTIFY_EMAIL: ${{secrets.NOTIFY_EMAIL }}
run: |
set -ex
cd modules
cat ./backend.tf
terraform init -input=false
terraform plan \
-var="namespace=${NAMESPACE}" \
-var="budget_notification_from_email=${NOTIFY_EMAIL}" \
-var="reset_nuke_toggle=false"
terraform apply \
-auto-approve \
-input=false \
-var="namespace=${NAMESPACE}" \
-var="budget_notification_from_email=${NOTIFY_EMAIL}" \
-var="reset_nuke_toggle=false"
# Build and Deploy Application Code to AWS
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
- name: Install dependencies
run: npm install
- name: Build artifacts
run: |
echo "Running build script"
./scripts/build.sh
# Deploy Application Code to AWS -- > TODO ARTIFACTS_BUCKET_NAME and NAMESPACE values are hardcoded as -raw flag or jq are throwing errors
- name: Deploy Application Code
run: |
echo "Running terraform output for artifacts_bucket_name"
ARTIFACTS_BUCKET_NAME=$(cd modules && terraform output artifacts_bucket_name)
echo "output bucket: ${ARTIFACTS_BUCKET_NAME}"
echo "Running terraform output for namespace"
NAMESPACE=$(cd modules && terraform output namespace)
echo "Output namespace: ${NAMESPACE}"
./scripts/deploy.sh \
/home/runner/work/dce/dce/bin/build_artifacts.zip \
cd\
000879607493-dce-artifacts-cd
# Functional Tests --> TODO need to fix the test failures
# - name: Functional Tests
# run: |
# set -euxo pipefail
# mkdir -p junit-report
# # Run functional tests
# go get github.com/jstemmer/go-junit-report
# go test -v ./tests/... -test.timeout 50m 2>&1 | tee >(go-junit-report > junit-report/functional.xml)
# Publish junit test results (for unit and functional tests) -- > TODO need to fix the test failures
# - name: Publish Test Results
# if: always()
# uses: actions/upload-artifact@v4
# with:
# name: Functional Tests
# path: ${{ github.workspace }}/junit-report/*.xml
# Publish the dce-cli executable, so we can use
# it in our Cleanup stage
- name: Upload dce-cli Artifact
uses: actions/upload-artifact@v4
with:
name: dce-cli
path: ${{ github.workspace }}/dce
- name: Upload dce-yml Artifact
uses: actions/upload-artifact@v4
with:
name: dce-yml
path: ${{ github.workspace }}/dce.yml
- name: Upload lease_id Artifact
uses: actions/upload-artifact@v4
with:
name: lease_id
path: ${{ github.workspace }}/lease_id.txt
- name: Upload backend-tf Artifact
uses: actions/upload-artifact@v4
with:
name: backend-tf
path: ${{ github.workspace }}/modules/backend.tf
- name: Checkout the git repo code
uses: actions/checkout@v2
- name: Download dce-cli artifact
uses: actions/download-artifact@v4
with:
name: dce-cli
path: ${{ github.workspace }}/dce-cli
- name: Download dce-yml artifact
uses: actions/download-artifact@v4
with:
name: dce-yml
path: ${{ github.workspace }}/dce-yml
- name: Download lease_id artifact
uses: actions/download-artifact@v4
with:
name: lease_id
path: ${{ github.workspace }}/lease_id
- name: Download namespace artifact
uses: actions/download-artifact@v4
with:
name: namespace
path: ${{ github.workspace }}/namespace
- name: Download backend-tf artifact
uses: actions/download-artifact@v4
with:
name: backend-tf
path: ${{ github.workspace }}/backend-tf
- name: Copy Artifacts to Working Dir
run: |
set -ex
# GitHub Actions wraps artifact files inside a directory
# in the github.workspace dir (which is different than our working dir...)
# Extract these out into our working dir, for easier access
cp ${{ github.workspace }}/dce-cli/dce ./
cp ${{ github.workspace }}/dce-yml/dce.yml ./
cp ${{ github.workspace }}/lease_id/lease_id.txt ./
cp ${{ github.workspace }}/namespace/namespace.txt ./
cp ${{ github.workspace }}/backend-tf/backend.tf ./modules/
chmod +x ./dce
- name: DCE Lease Login
env:
AWS_DEFAULT_REGION: us-east-1
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
set -ex
lease_id=$(cat ./lease_id.txt)
echo "Logging into lease ${lease_id}"
cat ./dce.yml
./dce --config=./dce.yml leases login ${lease_id}
# Cleanup the PR environment
# Install Terraform
- name: Install Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: ${{ inputs.terraform_version }}
- name: Terraform destroy
run: |
set -ex
export TF_VAR_namespace=$(cat ./namespace.txt)
export TF_VAR_budget_notification_from_email=${{ env.NOTIFY_EMAIL }}
cd modules
terraform init -input=false
terraform destroy -auto-approve
# End the DCE lease
- name: End DCE Lease
env:
AWS_DEFAULT_REGION: us-east-1
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
run: |
set -ex
lease_id=$(cat ./lease_id.txt)
namespace=$(cat ./namespace.txt)
leases=$(
./dce --config=dce.yml leases list -s Active \
)
account_id=$(
echo $leases | \
jq -r \
--arg Id "${lease_id}" \
'.[] | select( .id==$Id ) | .accountId'
)
echo "Ending lease ${lease_id}"
./dce --config=./dce.yml leases end \
-p ${namespace} \
-a ${account_id}
Release:
needs: [Deploy]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Fetch all tags
run: git fetch --tags
- name: Download bin artifact
uses: actions/download-artifact@v4
with:
name: bin
path: ${{ github.workspace }}/bin
- name: Download deploy_scripts artifact
uses: actions/download-artifact@v4
with:
name: deploy_scripts
path: ${{ github.workspace }}/deploy_scripts
- name: Get latest tag
id: get_latest_tag
run: |
latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)
echo "::set-output name=latest_tag::$latest_tag"
- name: Determine if prerelease
id: prerelease_check
run: |
if [ "${{ github.ref }}" == "refs/heads/master" ]; then
echo "::set-output name=prerelease::false"
else
echo "::set-output name=prerelease::true"
fi
- name: Create GitHub Release
if: github.event_name != 'pull_request'
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: "prerelease-${{ github.sha }}"
release_name: "Prerelease for ${{ github.sha }}"
draft: false
prerelease: ${{ steps.prerelease_check.outputs.prerelease }}
files: |
${{ github.workspace }}/bin/build_artifacts.zip
${{ github.workspace }}/bin/terraform_artifacts.zip
${{ github.workspace }}/deploy_scripts/deploy.sh
${{ github.workspace }}/deploy_scripts/restore_db.sh