Skip to content

Commit

Permalink
Add deployment step
Browse files Browse the repository at this point in the history
  • Loading branch information
jamieparkinson committed Mar 17, 2023
1 parent b37ba81 commit 57023db
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 1 deletion.
18 changes: 17 additions & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ steps:

- wait

- label: "push: API"
- label: "publish: API"
# branches: "main"
branches: "ci-deployment"
plugins:
Expand All @@ -28,3 +28,19 @@ steps:
push:
- api:756629837203.dkr.ecr.eu-west-1.amazonaws.com/weco/content-api:ref.${BUILDKITE_COMMIT}
- api:756629837203.dkr.ecr.eu-west-1.amazonaws.com/weco/content-api:latest

- wait

- label: "deploy: stage"
# branches: "main"
branches: "ci-deployment"
concurrency: 1
concurrency_group: "content-api/deploy-stage"
command: |
ENV_TAG="env.stage" ./builds/update_ecr_image_tag.sh weco/content-api
CLUSTER="content-api" ./builds/deploy_ecs_services.sh content-api-stage
agents:
queue: nano
plugins:
- wellcomecollection/aws-assume-role#v0.2.2:
role: "arn:aws:iam::756629837203:role/catalogue-ci"
54 changes: 54 additions & 0 deletions builds/deploy_ecs_services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
<<EOF
Trigger a deployment of an ECS service.
This script is mirrored in our other repos.
== How we manage ECS services ==
Our ECS services use task definitions that point to floating ECR tags,
e.g. 'env.stage'. By changing where this tag points, we can run new images
in a service without going through a whole Terraform plan/apply.
(See update_ecr_image_tag.sh for more detail on our image tags.)
Once we've updated the value of the tag, we need ECS to redeploy the services
and pick up the new images. This script does that redeployment, and waits
for services to be stable.
== Usage examples ==
CLUSTER="catalogue-api-2021-04-26" redeploy_ecs_services.sh stage-concepts-api
This will redeploy the 'stage-concepts-api' service in the
'catalogue-api-2021-04-26' cluster.
CLUSTER="catalogue-api-2021-04-26" redeploy_ecs_services.sh stage-concepts-api stage-items-api stage-search-api
This will update redeploy three services in the cluster.
More generally you can supply an arbitrary number of ECS services as
additional arguments, and they will all be redeployed.
EOF

set -o errexit
set -o nounset

for serviceName in "$@"
do
echo "Forcing a new deployment of $serviceName in $CLUSTER"
aws ecs update-service \
--cluster "$CLUSTER" \
--service "$serviceName" \
--force-new-deployment >/dev/null
done

for serviceName in "$@"
do
echo "Waiting for $serviceName to be stable"
aws ecs wait services-stable \
--cluster "$CLUSTER" \
--service "$serviceName"
echo "Done! $serviceName is stable"
done
98 changes: 98 additions & 0 deletions builds/update_ecr_image_tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
<<EOF
Retag an image in ECR.
This script is mirrored in our other repos.
== How we use ECR tags ==
We have three types of tag:
- Every image has a tag starting ref, e.g. 'ref.f37d2c5'.
This is the Git commit has that was used to build a given image.
This helps us match an image to its source code.
- The 'latest' tag points to the last image that was published to a
repository. It helps us know what the newest version of our code is.
- The env tags point to the image being used in a particular environment.
e.g. 'env.stage', 'env.prod' would be the images used in our staging
and prod environment, respectively.
These are the tags used in our ECS task definitions.
This script updates the env tags of one or more repositories to point at
whatever 'latest' is.
== Worked example ==
Suppose you had the following set of images:
image1 <-- ref.e6b6c49
image2 <-- ref.ac3ec0a, env.prod
image3 <-- ref.6b6213a, latest
If you ran this script to update the env.prod tag, it would be moved to
the image tagged 'latest':
image1 <-- ref.e6b6c49
image2 <-- ref.ac3ec0a
image3 <-- ref.6b6213a, latest, env.prod
If CI then publishes a new image, this will become latest, but the image
pointed at by 'env.prod' will be unchanged:
image1 <-- ref.e6b6c49
image2 <-- ref.ac3ec0a
image3 <-- ref.6b6213a, env.prod
image4 <-- ref.8656d3f, latest
== Usage examples ==
ENV_TAG="env.staging" update_ecr_image_tag.sh bag_replicator
This will update the 'env.staging' tag in the bag_replicator ECR
repository to point to the current value of 'latest'.
ENV_TAG="env.prod" update_ecr_image_tag.sh id_minter transformer_mets
This will update the 'env.staging' tag in the id_minter and
transformer_mets ECR repositories to point to the current value of 'latest'.
More generally you can supply an arbitrary number of ECR repos as
additional arguments, and they will all be retagged.
EOF

set -o errexit
set -o nounset

for repositoryName in "$@"
do
# These commands are based on an AWS ECR guide:
# https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-retag.html
echo "Updating the $ENV_TAG tag in $repositoryName"
LATEST_MANIFEST=$(
aws ecr batch-get-image \
--repository-name "$repositoryName" \
--image-ids imageTag=latest --output json \
| jq --raw-output --join-output '.images[0].imageManifest'
)

TAGGED_MANIFEST=$(
aws ecr batch-get-image \
--repository-name "$repositoryName" \
--image-ids imageTag="$ENV_TAG" --output json \
| jq --raw-output --join-output '.images[0].imageManifest'
)

if [[ "$LATEST_MANIFEST" != "$TAGGED_MANIFEST" ]]
then
aws ecr put-image \
--repository-name "$repositoryName" \
--image-tag "$ENV_TAG" \
--image-manifest "$LATEST_MANIFEST" >/dev/null
else
echo "Tag for $ENV_TAG is already up-to-date, skipping"
fi
done

0 comments on commit 57023db

Please sign in to comment.