-
Notifications
You must be signed in to change notification settings - Fork 22
289 lines (264 loc) · 11.7 KB
/
deploy-staging.yaml
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
name: Deploy a staging environment
on:
workflow_dispatch:
inputs:
manifest:
description: 'The manifest file to deploy (base64 encoded)'
required: true
type: string
sandbox-id:
description: 'The sandbox ID to deploy under'
required: true
type: string
with-rds:
description: 'Stage a new RDS instance'
required: false
default: 'False'
type: string
pipeline-pr:
description: Pipeline PR number to stage
required: false
default: ""
type: string
secrets:
description: 'Encrypted secrets to use for this task'
required: true
type: string
env:
region: ${{ secrets.AWS_REGION }}
permissions:
id-token: write
contents: read
jobs:
load-config:
uses: ./.github/workflows/load-config.yaml
deploy-staging:
name: Deploy staging environment
runs-on: ubuntu-20.04
needs: load-config
environment: ${{needs.load-config.outputs.domain_name}}
steps:
- id: setup-aws
name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/ci-iac-role
aws-region: ${{ env.region }}
- id: install-aws-cli
name: Install AWS CLI
uses: unfor19/install-aws-cli-action@v1
with:
version: 2
- id: checkout
name: Check out source code
uses: actions/checkout@v3
with:
token: ${{ secrets.API_TOKEN_GITHUB }}
- id: install-eksctl
name: Install eksctl
run: |-
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
- id: set-stack-name
name: Set name of the CloudFormation stacks
run: |-
BASE_NAME=biomage-rds-staging-$SANDBOX_ID
echo "rds-name=$BASE_NAME" >> $GITHUB_OUTPUT
BASE_NAME=biomage-sns-staging-$SANDBOX_ID
echo "sns-name=$BASE_NAME" >> $GITHUB_OUTPUT
BASE_NAME=biomage-userpoolclient-staging-$SANDBOX_ID
echo "userpoolclient-name=$BASE_NAME" >> $GITHUB_OUTPUT
BASE_NAME=biomage-batch-job-definition-staging-$SANDBOX_ID
echo "batch-job-definition-name=$BASE_NAME" >> $GITHUB_OUTPUT
env:
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}
- id: create-worker-fargate-profile
name: Attempt to create worker Fargate profile
uses: nick-invision/retry@v2
with:
timeout_seconds: 900
max_attempts: 30
retry_on: error
command: |
output=$(eksctl create fargateprofile --cluster biomage-staging --region ${{ secrets.AWS_REGION }} --name worker-${SANDBOX_ID} --labels type=worker --namespace worker-${SANDBOX_ID} 2>&1)
echo $output
echo $output | grep "created Fargate profile"
# Add jitter to break up correlated events.
on_retry_command: sleep $((20 + RANDOM % 10));
env:
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}
- id: create-pipeline-fargate-profile
name: Attempt to create pipeline Fargate profile
uses: nick-invision/retry@v2
with:
timeout_seconds: 900
max_attempts: 30
retry_on: error
command: |
output=$(eksctl create fargateprofile --cluster biomage-staging --region ${{ secrets.AWS_REGION }} --name pipeline-${SANDBOX_ID} --labels type=pipeline --namespace pipeline-${SANDBOX_ID} 2>&1)
echo $output
echo $output | grep "created Fargate profile"
# Add jitter to break up correlated events.
on_retry_command: sleep $((20 + RANDOM % 10))
env:
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}
- id: deploy-template-rds
# if: ${{ github.ref == 'refs/heads/master' && github.event.inputs.with-rds == 'True' }}
if: ${{ github.event.inputs.with-rds == 'True' }}
name: Deploy CloudFormation stack for RDS
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
parameter-overrides: "Environment=staging,SandboxID=${{ github.event.inputs.sandbox-id }}"
name: ${{ steps.set-stack-name.outputs.rds-name }}
template: cf/rds.yaml
no-fail-on-empty-changeset: "1"
capabilities: "CAPABILITY_IAM,CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND"
- id: rds-secrets
if: ${{ github.event.inputs.with-rds == 'True' }}
uses: t-botz/aws-secrets-manager-read-action@v2
name: Outputs RDS secrets to get into the db
with:
secret-id: aurora-staging-${{ github.event.inputs.sandbox-id }}
mask-value: true
mask-json-values: true
keys-as-outputs: true
- id: setup-rds-roles
# if: ${{ github.ref == 'refs/heads/master' && github.event.inputs.with-rds == 'True' }}
if: ${{ github.event.inputs.with-rds == 'True' }}
name: Setup RDS roles
run: |-
INSTANCE_ID=$(aws ec2 describe-instances \
--filters 'Name=tag:Name,Values=rds-staging-ssm-agent' \
--output text \
--query 'Reservations[*].Instances[*].InstanceId')
if [ -z $INSTANCE_ID ]; then
echo "Can not connect to RDS agent: No instances found for staging"
exit 1
fi
CLUSTER_NAME=aurora-cluster-staging-${SANDBOX_ID}
RDSHOST=$(aws rds describe-db-cluster-endpoints \
--region $REGION \
--db-cluster-identifier $CLUSTER_NAME \
--filter Name=db-cluster-endpoint-type,Values='writer' \
--query 'DBClusterEndpoints[0].Endpoint' \
--output text)
if [ -z $RDSHOST ]; then
echo "Failed getting RDS host with name $CLUSTER_NAME"
exit 1
fi
ENSURE_PSQL_INSTALLED_COMMAND="sudo yum -y install postgresql"
aws ssm send-command --instance-ids "$INSTANCE_ID" \
--document-name AWS-RunShellScript \
--parameters "commands='$ENSURE_PSQL_INSTALLED_COMMAND'"
SETUP_ROLES_CMD="
PGPASSWORD=\'${AURORA_STAGING_PASSWORD}\' psql \
--host=${RDSHOST} \
--port=5432 \
--username=${AURORA_STAGING_USERNAME} \
--dbname=aurora_db <<EOF
CREATE ROLE api_role WITH LOGIN;
CREATE ROLE dev_role WITH LOGIN;
GRANT USAGE ON SCHEMA public TO api_role;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public to api_role;
GRANT dev_role TO ${AURORA_STAGING_USERNAME};
ALTER DEFAULT PRIVILEGES FOR USER dev_role IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO api_role;
ALTER DEFAULT PRIVILEGES FOR USER dev_role IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO api_role;
REVOKE dev_role FROM ${AURORA_STAGING_USERNAME};
GRANT rds_iam TO api_role;
GRANT rds_iam, ${AURORA_STAGING_USERNAME} TO dev_role;
EOF"
aws ssm send-command --instance-ids "$INSTANCE_ID" \
--document-name AWS-RunShellScript \
--parameters "commands='$SETUP_ROLES_CMD'"
env:
REGION: ${{ env.region }}
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}
AURORA_STAGING_USERNAME: ${{ steps.rds-secrets.outputs.username }}
AURORA_STAGING_PASSWORD: ${{ steps.rds-secrets.outputs.password }}
- id: deploy-template-sns
name: Deploy CloudFormation stack for SNS topic
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
parameter-overrides: "Environment=staging,SandboxID=${{ github.event.inputs.sandbox-id }}"
name: ${{ steps.set-stack-name.outputs.sns-name }}
template: cf/sns.yaml
no-fail-on-empty-changeset: "1"
capabilities: "CAPABILITY_IAM,CAPABILITY_NAMED_IAM"
- id: deploy-template-userpool-client
name: Deploy CloudFormation stack for Cognito userpool clients
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
parameter-overrides: "Environment=staging,SandboxID=${{ github.event.inputs.sandbox-id }}"
name: ${{ steps.set-stack-name.outputs.userpoolclient-name }}
template: cf/userpoolclient.yaml
no-fail-on-empty-changeset: "1"
capabilities: "CAPABILITY_IAM,CAPABILITY_NAMED_IAM"
- id: deploy-template-batch-job-definition
name: Deploy CloudFormation stack for Batch job definition
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
parameter-overrides: >-
Environment=staging,
SandboxID=${{ github.event.inputs.sandbox-id }},
PipelinePRNum=${{ github.event.inputs.pipeline-pr }},
ImageAccountId=${{ needs.load-config.outputs.image_account_id }},
ImageAccountRegion=${{ needs.load-config.outputs.image_account_region }}
name: ${{ steps.set-stack-name.outputs.batch-job-definition-name }}
template: cf/batch-job-definition.yaml
no-fail-on-empty-changeset: "1"
capabilities: "CAPABILITY_IAM,CAPABILITY_NAMED_IAM"
- id: create-manifest-file
name: Create manifest file to repository.
run: |-
echo "$MANIFEST" | base64 -d > $SANDBOX_ID.yaml
env:
MANIFEST: ${{ github.event.inputs.manifest }}
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}
- id: push-deployment-to-releases
name: Push staging deployment template to releases
uses: dmnemec/[email protected]
env:
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
with:
source_file: ${{ github.event.inputs.sandbox-id }}.yaml
destination_repo: ${{ github.repository_owner }}/releases
destination_folder: staging
user_email: [email protected]
user_name: 'Biomage CI/CD'
- id: add-kubeconfig
name: Add k8s config to enable removal of Fargate profile on failure
if: ${{ failure() }}
run: |-
aws eks update-kubeconfig --name biomage-staging
- id: cleanup-pipeline-fargate-profile-if-failure
name: Remove Fargate profile for the pipelines
if: ${{ failure() }}
uses: nick-invision/retry@v2
with:
timeout_seconds: 900
max_attempts: 30
retry_on: error
command: |
output=$(eksctl delete fargateprofile --cluster biomage-staging --region ${{ secrets.AWS_REGION }} --name pipeline-${SANDBOX_ID} 2>&1)
echo $output
echo $output | egrep "deleted Fargate profile|No Fargate Profile found"
# Add jitter to break up correlated events.
on_retry_command: sleep $((20 + RANDOM % 10));
env:
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}
- id: cleanup-worker-fargate-profile-if-failure
name: Remove Fargate profile for the workers
if: ${{ failure() }}
uses: nick-invision/retry@v2
with:
timeout_seconds: 900
max_attempts: 30
retry_on: error
command: |
output=$(eksctl delete fargateprofile --cluster biomage-staging --region ${{ secrets.AWS_REGION }} --name worker-${SANDBOX_ID} 2>&1)
echo $output
echo $output | egrep "deleted Fargate profile|No Fargate Profile found"
# Add jitter to break up correlated events.
on_retry_command: sleep $((20 + RANDOM % 10));
env:
SANDBOX_ID: ${{ github.event.inputs.sandbox-id }}