Deployment with DB recreation for data replication resources for production #211
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Data replication pipeline | |
run-name: ${{ inputs.deployment_type }} for data replication resources for ${{ inputs.environment }} | |
on: | |
workflow_dispatch: | |
inputs: | |
environment: | |
description: Deployment environment | |
required: true | |
type: choice | |
options: | |
- training | |
- production | |
- test | |
- qa | |
- sandbox-alpha | |
- sandbox-beta | |
deployment_type: | |
description: Deployment type | |
required: true | |
type: choice | |
options: | |
- Deployment with DB recreation | |
- Application only deployment | |
image_tag: | |
description: Docker image tag to deploy | |
required: false | |
type: string | |
db_snapshot_arn: | |
description: ARN of the DB snapshot to use (optional) | |
required: false | |
type: string | |
egress_cidr: | |
description: CIDR blocks to allow egress traffic. | |
type: string | |
required: true | |
default: "[]" | |
take_db_snapshot: | |
description: Take a new DB snapshot before creating the environment | |
type: boolean | |
default: false | |
env: | |
aws_role: ${{ inputs.environment == 'production' | |
&& 'arn:aws:iam::820242920762:role/GithubDeployDataReplicationInfrastructure' | |
|| 'arn:aws:iam::393416225559:role/GithubDeployDataReplicationInfrastructure' }} | |
db_snapshot_role: ${{ inputs.environment == 'production' | |
&& 'arn:aws:iam::820242920762:role/DatabaseSnapshotRole' | |
|| 'arn:aws:iam::393416225559:role/DatabaseSnapshotRole' }} | |
defaults: | |
run: | |
working-directory: terraform/data_replication | |
concurrency: | |
group: deploy-data-replica-${{ inputs.environment }} | |
jobs: | |
prepare-db-replica: | |
if: ${{ inputs.deployment_type == 'Deployment with DB recreation' }} | |
name: Prepare data replica | |
runs-on: ubuntu-latest | |
permissions: | |
id-token: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Assume DB Snapshot role | |
if: inputs.take_db_snapshot | |
uses: aws-actions/configure-aws-credentials@v5 | |
with: | |
role-to-assume: ${{ env.db_snapshot_role }} | |
aws-region: eu-west-2 | |
- name: Take DB snapshot | |
if: inputs.take_db_snapshot | |
run: | | |
set -e | |
snapshot_identifier=snapshot-for-data-replication-$(date +"%Y-%m-%d-%H-%M-%S") | |
aws rds create-db-cluster-snapshot --db-cluster-identifier mavis-${{ inputs.environment }} --db-cluster-snapshot-identifier $snapshot_identifier | |
echo "Waiting for snapshot to be available. This can take a while." | |
aws rds wait db-cluster-snapshot-available --db-cluster-snapshot-identifier $snapshot_identifier | |
echo "New snapshot is now available" | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v5 | |
with: | |
role-to-assume: ${{ env.aws_role }} | |
aws-region: eu-west-2 | |
- name: Get latest snapshot | |
id: get-latest-snapshot | |
run: | | |
set -e | |
if [ -z "${{ inputs.db_snapshot_arn }}" ]; then | |
echo "No snapshot ARN provided, fetching the latest snapshot" | |
SNAPSHOT_ARN=$(aws rds describe-db-cluster-snapshots \ | |
--query "DBClusterSnapshots[?DBClusterIdentifier=='mavis-${{ inputs.environment }}'].[DBClusterSnapshotArn, SnapshotCreateTime]" \ | |
--output text | sort -k2 -r | head -n 1 | cut -f1) | |
if [ -z "$SNAPSHOT_ARN" ]; then | |
echo "No snapshots found for mavis-${{ inputs.environment }}" | |
exit 1 | |
fi | |
else | |
echo "Using provided snapshot ARN: ${{ inputs.db_snapshot_arn }}" | |
SNAPSHOT_ARN="${{ inputs.db_snapshot_arn }}" | |
fi | |
echo "Using snapshot ARN: $SNAPSHOT_ARN" | |
echo "SNAPSHOT_ARN=$SNAPSHOT_ARN" >> $GITHUB_OUTPUT | |
- name: Install terraform | |
uses: hashicorp/setup-terraform@v3 | |
with: | |
terraform_version: 1.11.4 | |
outputs: | |
SNAPSHOT_ARN: ${{ steps.get-latest-snapshot.outputs.SNAPSHOT_ARN }} | |
prepare-webapp: | |
name: Prepare webapp | |
runs-on: ubuntu-latest | |
permissions: | |
id-token: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v5 | |
with: | |
role-to-assume: ${{ env.aws_role }} | |
aws-region: eu-west-2 | |
- name: ECR login | |
id: login-ecr | |
uses: aws-actions/amazon-ecr-login@v2 | |
- name: Get docker image digest | |
id: get-docker-image-digest | |
run: | | |
set -e | |
DOCKER_IMAGE="${{ steps.login-ecr.outputs.registry }}/mavis/webapp:${{ inputs.image_tag || github.sha }}" | |
docker pull "$DOCKER_IMAGE" | |
DOCKER_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$DOCKER_IMAGE") | |
DIGEST="${DOCKER_DIGEST#*@}" | |
echo "DIGEST=$DIGEST" >> $GITHUB_OUTPUT | |
outputs: | |
DOCKER_DIGEST: ${{ steps.get-docker-image-digest.outputs.DIGEST }} | |
plan: | |
name: Terraform plan | |
runs-on: ubuntu-latest | |
needs: | |
- prepare-db-replica | |
- prepare-webapp | |
if: ${{ !cancelled() && | |
(needs.prepare-db-replica.result == 'success' || needs.prepare-db-replica.result == 'skipped') && | |
needs.prepare-webapp.result == 'success' }} | |
env: | |
SNAPSHOT_ARN: ${{ needs.prepare-db-replica.outputs.SNAPSHOT_ARN }} | |
DB_SECRET_ARN: ${{ needs.prepare-db-replica.outputs.DB_SECRET_ARN || 'arn:aws:secretsmanager:eu-west-2:000000000000:secret:placeholder' }} | |
DOCKER_DIGEST: ${{ needs.prepare-webapp.outputs.DOCKER_DIGEST }} | |
REPLACE_DB_CLUSTER: ${{ inputs.deployment_type == 'Deployment with DB recreation' }} | |
permissions: | |
id-token: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v5 | |
with: | |
role-to-assume: ${{ env.aws_role }} | |
aws-region: eu-west-2 | |
- name: Install terraform | |
uses: hashicorp/setup-terraform@v3 | |
with: | |
terraform_version: 1.11.4 | |
- name: Get db secret arn | |
id: get-db-secret-arn | |
working-directory: terraform/app | |
run: | | |
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade | |
DB_SECRET_ARN=$(terraform output --raw db_secret_arn) | |
echo "DB_SECRET_ARN=$DB_SECRET_ARN" >> $GITHUB_OUTPUT | |
- name: Terraform Plan | |
id: plan | |
run: | | |
set -eo pipefail | |
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade | |
CIDR_BLOCKS='${{ inputs.egress_cidr }}' | |
PLAN_ARGS=( | |
"plan" | |
"-var=image_digest=${{ env.DOCKER_DIGEST }}" | |
"-var=db_secret_arn=${{ steps.get-db-secret-arn.outputs.DB_SECRET_ARN }}" | |
"-var=imported_snapshot=${{ env.SNAPSHOT_ARN }}" | |
"-var-file=env/${{ inputs.environment }}.tfvars" | |
"-var=allowed_egress_cidr_blocks=$CIDR_BLOCKS" | |
"-out=${{ runner.temp }}/tfplan" | |
) | |
if [ "${{ env.REPLACE_DB_CLUSTER }}" = "true" ]; then | |
PLAN_ARGS+=("-replace" "aws_rds_cluster.cluster") | |
fi | |
terraform "${PLAN_ARGS[@]}" | tee ${{ runner.temp }}/tf_stdout | |
- name: Upload artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: tfplan_infrastructure-${{ inputs.environment }} | |
path: ${{ runner.temp }}/tfplan | |
apply: | |
name: Terraform apply | |
runs-on: ubuntu-latest | |
needs: plan | |
if: ${{ !cancelled() && needs.plan.result == 'success' }} | |
environment: ${{ inputs.environment }} | |
permissions: | |
id-token: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v5 | |
with: | |
role-to-assume: ${{ env.aws_role }} | |
aws-region: eu-west-2 | |
- name: Download artifact | |
uses: actions/download-artifact@v5 | |
with: | |
name: tfplan_infrastructure-${{ inputs.environment }} | |
path: ${{ runner.temp }} | |
- name: Install terraform | |
uses: hashicorp/setup-terraform@v3 | |
with: | |
terraform_version: 1.11.4 | |
- name: Apply the changes | |
run: | | |
set -e | |
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade | |
terraform apply ${{ runner.temp }}/tfplan | |
- name: Deploy db-access-service | |
run: | | |
task_definition_arn=$(terraform output -raw task_definition_arn) | |
aws ecs update-service \ | |
--cluster mavis-${{ inputs.environment }}-data-replication \ | |
--service mavis-${{ inputs.environment }}-data-replication \ | |
--task-definition $task_definition_arn |