-
-
Notifications
You must be signed in to change notification settings - Fork 127
291 lines (247 loc) · 11.9 KB
/
deploy.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
name: Deploy to Amazon ECS
env:
aws_region: eu-west-2
webservers_cluster_name: webservers
sidekiq_cluster_name: sidekiq
website_task_definition_name: website
website_service_name: website
api_task_definition_name: api
api_service_name: api
anycable_task_definition_name: anycable
anycable_service_name: anycable
sidekiq_task_definition_name: sidekiq
sidekiq_service_name: sidekiq
ecr_repository_rails: "webserver-rails"
dockerfile_rails: "docker/rails.Dockerfile"
ecr_repository_nginx: "webserver-nginx"
dockerfile_nginx: "docker/nginx.Dockerfile"
ecr_repository_anycable_go: "anycable-go"
dockerfile_anycable_go: "docker/anycable-go.Dockerfile"
# TODO: (Required) Move this to be a secret
s3_bucket: "exercism-v3-assets"
on:
push:
branches: [main]
workflow_dispatch:
schedule:
- cron: 0 */2 * * *
jobs:
deploy:
if: github.repository == 'exercism/website-deployer'
name: Upload images to ECR, assets to S3, and definition to ECS
runs-on: self-hosted
steps:
###############
###############
# Setup Steps #
###############
###############
- name: Checkout
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@e1e17a757e536f70e52b5a12b2e8d1d1c60e04ef
with:
aws-access-key-id: ${{ secrets.AWS_DEPLOY_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_DEPLOY_SECRET_ACCESS_KEY }}
aws-region: ${{ env.aws_region }}
- name: Login to Amazon ECR
id: login_to_ecr
uses: aws-actions/amazon-ecr-login@2f9f10ea3fa2eed41ac443fee8bfbd059af2d0a4
#########################
#########################
# Build the Rails image #
#########################
#########################
- name: Build and Push Rails Docker
id: build_rails
env:
ECR_REGISTRY: ${{ steps.login_to_ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ecr_repository_rails }}
IMAGE_NAME: "${{ steps.login_to_ecr.outputs.registry}}/${{ env.ecr_repository_rails }}:${{ github.sha }}"
DOCKERFILE: ${{ env.dockerfile_rails }}
GEOIP_LICENSE_KEY: ${{ secrets.GEOIP_LICENSE_KEY }}
GEOIP_ACCOUNT_ID: ${{ secrets.GEOIP_ACCOUNT_ID }}
run: |
# Build a docker container and push it to ECR
docker build -t $IMAGE_NAME -f $DOCKERFILE \
--build-arg GEOIP_LICENSE_KEY=$GEOIP_LICENSE_KEY \
--build-arg GEOIP_ACCOUNT_ID=$GEOIP_ACCOUNT_ID \
--build-arg GEOIP_CACHE_BUSTER=$(date -d "`date +%Y%m01`" +%Y-%m-%d) \
--build-arg BUNDLER_VERSION=$(awk '/BUNDLED WITH/ {getline;$1=$1;print}' Gemfile.lock) \
.
docker push $IMAGE_NAME
# Retag this as the latest
docker tag $IMAGE_NAME $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
# Retag it as website below because the `:` hurts us otherwise
docker tag $IMAGE_NAME website
# Save the output for writing to the task definiton
echo "image=${IMAGE_NAME}" >> $GITHUB_OUTPUT
##################################
##################################
# Extact and upload assets to s3 #
##################################
##################################
- name: Copy assets from Dockerfile
run: |
container_id=$(docker create website)
docker cp ${container_id}:/opt/exercism/website/public/assets assets
docker rm ${container_id}
- name: Upload assets to s3
run: |
aws s3 sync assets s3://${{ env.s3_bucket }}/assets --acl public-read --no-progress --cache-control max-age=31536000
#########################
#########################
# Build the Nginx image #
#########################
#########################
- name: Build and Push Nginx Docker
id: build_nginx
env:
ECR_REGISTRY: ${{ steps.login_to_ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ecr_repository_nginx }}
IMAGE_NAME: "${{ steps.login_to_ecr.outputs.registry}}/${{ env.ecr_repository_nginx }}:${{ github.sha }}"
DOCKERFILE: ${{ env.dockerfile_nginx }}
run: |
# Build a docker container and push it to ECR
docker build -t $IMAGE_NAME -f $DOCKERFILE .
docker push $IMAGE_NAME
# Retag this as the latest
docker tag $IMAGE_NAME $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
# Save the output for writing to the task definiton
echo "image=${IMAGE_NAME}" >> $GITHUB_OUTPUT
##################################
##################################
# Update website Task definition #
##################################
##################################
# We get the existing task definition to update
# Note that this is passed into the first update action
# but then chained from action to action for the others.
- name: Download website task definition
run: |
aws ecs describe-task-definition --task-definition ${{ env.website_task_definition_name }} --query taskDefinition > website-task-definition.json
- name: Update website | puma container
id: update_definition_for_website_puma
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: website-task-definition.json
container-name: puma
image: "${{ steps.build_rails.outputs.image }}"
- name: Update website | nginx container
id: update_definition_for_website_nginx
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: ${{ steps.update_definition_for_website_puma.outputs.task-definition }}
container-name: nginx
image: "${{ steps.build_nginx.outputs.image }}"
# Push the new definition up to ECS and deploy the new service from it
- name: Deploy Website
uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
with:
task-definition: ${{ steps.update_definition_for_website_nginx.outputs.task-definition }}
service: ${{ env.website_service_name }}
cluster: ${{ env.webservers_cluster_name }}
wait-for-service-stability: false
##############################
##############################
# Update api Task definition #
##############################
##############################
# We get the existing task definition to update
# Note that this is passed into the first update action
# but then chained from action to action for the others.
- name: Download api task definition
run: |
aws ecs describe-task-definition --task-definition ${{ env.api_task_definition_name }} --query taskDefinition > api-task-definition.json
- name: Update api | puma container
id: update_definition_for_api_puma
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: api-task-definition.json
container-name: puma
image: "${{ steps.build_rails.outputs.image }}"
- name: Update api | nginx container
id: update_definition_for_api_nginx
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: ${{ steps.update_definition_for_api_puma.outputs.task-definition }}
container-name: nginx
image: "${{ steps.build_nginx.outputs.image }}"
# Push the new definition up to ECS and deploy the new service from it
- name: Deploy API
uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
with:
task-definition: ${{ steps.update_definition_for_api_nginx.outputs.task-definition }}
service: ${{ env.api_service_name }}
cluster: ${{ env.webservers_cluster_name }}
wait-for-service-stability: false
##################################
##################################
# Update anycable Task definition #
##################################
##################################
# We get the existing task definition to update
# Note that this is passed into the first update action
# but then chained from action to action for the others.
- name: Download anycable task definition
run: |
aws ecs describe-task-definition --task-definition ${{ env.anycable_task_definition_name }} --query taskDefinition > anycable-task-definition.json
- name: Update anycable | anycable_ruby container
id: update_definition_for_anycable_ruby
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: anycable-task-definition.json
container-name: anycable_ruby
image: "${{ steps.build_rails.outputs.image }}"
- name: Update anycable | anycable_go container
id: update_definition_for_anycable_go
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: ${{ steps.update_definition_for_anycable_ruby.outputs.task-definition }}
container-name: anycable_go
image: "${{ steps.login_to_ecr.outputs.registry}}/anycable-go-pro:latest"
- name: Update anycable | nginx container
id: update_definition_for_anycable_nginx
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: ${{ steps.update_definition_for_anycable_go.outputs.task-definition }}
container-name: nginx
image: "${{ steps.build_nginx.outputs.image }}"
# Push the new definition up to ECS and deploy the new service from it
- name: Deploy Anycable
uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
with:
task-definition: ${{ steps.update_definition_for_anycable_nginx.outputs.task-definition }}
service: ${{ env.anycable_service_name }}
cluster: ${{ env.webservers_cluster_name }}
wait-for-service-stability: false
##################################
##################################
# Update Sidekiq Task definition #
##################################
##################################
# We get the existing task definition to update
# Note that this is passed into the first update action
# but then chained from action to action for the others.
- name: Download sidekiq task definition
run: |
aws ecs describe-task-definition --task-definition ${{ env.sidekiq_task_definition_name }} --query taskDefinition > sidekiq-task-definition.json
# Set puma to rails
- name: Update the sidekiq definition
id: update_definition_for_sidekiq
uses: aws-actions/amazon-ecs-render-task-definition@61b0c00c3743b70987a73a1faf577f0d167d1574
with:
task-definition: sidekiq-task-definition.json
container-name: sidekiq
image: "${{ steps.build_rails.outputs.image }}"
# Push the new definition up to ECS and deploy a new service from it.
- name: Deploy Sidekiq
uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
with:
# Ensure this is the final step in the daisy-chain above
task-definition: ${{ steps.update_definition_for_sidekiq.outputs.task-definition }}
service: ${{ env.sidekiq_service_name }}
cluster: ${{ env.sidekiq_cluster_name }}
wait-for-service-stability: true