Skip to content

Deploy data replication from next to production #413

Deploy data replication from next to production

Deploy data replication from next to production #413

name: Deploy data replication
run-name: >-
Deploy data replication from ${{ inputs.git_ref_to_deploy || github.ref_name }} to ${{
inputs.environment }}
on:
workflow_dispatch:
inputs:
environment:
description: Deployment environment
required: true
type: choice
options:
- training
- production
- test
- qa
- sandbox-alpha
- sandbox-beta
git_ref_to_deploy:
description: | # Use blank unicode character (U+2800) to force line-break
Use code from: ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
(Git ref to deploy, for example, a tag, branch name or commit SHA. Will use workflow ref
if not provided.)
type: string
workflow_call:
inputs:
environment:
description: Deployment environment
required: true
type: string
git_ref_to_deploy:
description: Git ref to deploy, for example, a tag, branch name or commit SHA
type: string
required: true
permissions: {}
env:
environment: ${{ inputs.environment }}
git_ref_to_deploy: ${{ inputs.git_ref_to_deploy || github.sha }}
aws_role:
${{ inputs.environment == 'production' &&
'arn:aws:iam::820242920762:role/GithubDeployDataReplicationInfrastructure' ||
'arn:aws:iam::393416225559:role/GithubDeployDataReplicationInfrastructure' }}
aws_account_id: ${{ inputs.environment == 'production' && '820242920762' || '393416225559' }}
concurrency:
group: deploy-data-replica-${{ inputs.environment }}
jobs:
validate-inputs:
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Validate inputs
run: |
if [[ "$environment" == "preview" || "$environment" == "production" ]]; then
if [[ -z "$git_ref_to_deploy" ]]; then
echo "Error: git_ref_to_deploy is required for preview and production environments."
exit 1
fi
fi
determine-git-sha:
runs-on: ubuntu-latest
permissions: {}
needs: validate-inputs
outputs:
git-sha: ${{ steps.get-git-sha.outputs.git-sha }}
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.git_ref_to_deploy }}
- name: Get git sha
id: get-git-sha
run: echo "git-sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
build-and-push-image:
permissions:
id-token: write
needs: determine-git-sha
uses: ./.github/workflows/build-and-push-image.yml
with:
git_sha: ${{ needs.determine-git-sha.outputs.git-sha }}
prepare-deployment:
name: Prepare deployment
runs-on: ubuntu-latest
needs: [build-and-push-image, determine-git-sha]
permissions:
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.git_ref_to_deploy }}
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0
with:
role-to-assume: ${{ env.aws_role }}
aws-region: eu-west-2
- name: Get image digest
id: get-image-digest
run: |
digest=$(aws ecr describe-images \
--repository-name mavis/webapp \
--image-ids imageTag=${{ needs.determine-git-sha.outputs.git-sha }} \
--query 'imageDetails[0].imageDigest' \
--output text)
echo "digest=$digest" >> "$GITHUB_OUTPUT"
- name: Parse environment variables
id: parse-environment-variables
env:
MAVIS__PDS__RATE_LIMIT_PER_SECOND: ${{ inputs.environment == 'production' && 50 || 5 }}
run: |
{
echo 'parsed_env_vars<<EOF'
echo "MAVIS__SPLUNK__ENABLED=false"
echo "MAVIS__CIS2__ENABLED=false"
echo "MAVIS__PDS__ENQUEUE_BULK_UPDATES=false"
echo "MAVIS__PDS__RATE_LIMIT_PER_SECOND=$MAVIS__PDS__RATE_LIMIT_PER_SECOND"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Populate web task definition
id: create-task-definition
uses: aws-actions/amazon-ecs-render-task-definition@77954e213ba1f9f9cb016b86a1d4f6fcdea0d57e # v1.8.4
with:
task-definition-family:
mavis-data-replication-task-definition-${{ inputs.environment }}-template
container-name: application
# yamllint disable-line rule:line-length
image:
${{ env.aws_account_id }}.dkr.ecr.eu-west-2.amazonaws.com/mavis/webapp@${{
steps.get-image-digest.outputs.digest }}
environment-variables: ${{ steps.parse-environment-variables.outputs.parsed_env_vars }}
- name: Rename task definition file
run: >-
mv ${{ steps.create-task-definition.outputs.task-definition }} ${{ runner.temp
}}/data-replication-task-definition.json
- name: Upload artifact for data-replication task definition
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ inputs.environment }}-data-replication-task-definition
path: ${{ runner.temp }}/data-replication-task-definition.json
notify-approval-required:
name: Notify on approval required
runs-on: ubuntu-latest
needs: prepare-deployment
if: ${{ inputs.environment == 'production' && github.event_name == 'workflow_dispatch' }}
steps:
- name: Notify pending approval
if: inputs.environment == 'production'
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95
with:
webhook: ${{ secrets.SLACK_MAVIS_TECH_WEBHOOK_URL }}
webhook-type: incoming-webhook
# yamllint disable rule:line-length
payload: |
text: ":hourglass: Approval required :hourglass:"
blocks:
- type: "section"
text:
type: "mrkdwn"
text: "${{ github.workflow }} requires approval"
- type: "section"
fields:
- type: "mrkdwn"
text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View workflow run>"
- type: "mrkdwn"
text: "*Triggered by:*\n${{ github.actor }}"
# yamllint enable rule:line-length
approve-deployments:
name: Wait for approval if required
runs-on: ubuntu-latest
needs: prepare-deployment
environment: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || null }}
steps:
- run: echo "Proceeding with deployment to $environment environment"
deploy-data-replication:
name: Deploy data-replication service
runs-on: ubuntu-latest
needs: [prepare-deployment, approve-deployments]
permissions:
id-token: write
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0
with:
role-to-assume: ${{ env.aws_role }}
aws-region: eu-west-2
- name: Download data-replication task definition artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ${{ runner.temp }}
name: ${{ inputs.environment }}-data-replication-task-definition
- name: Change family of task definition
run: |
file_path="${{ runner.temp }}/data-replication-task-definition.json"
family_name="mavis-data-replication-task-definition-$environment"
jq --arg f "$family_name" '.family = $f' "$file_path" > tmpfile && mv tmpfile "$file_path"
- name: Deploy data-replication service
id: ecs-deploy
uses: aws-actions/amazon-ecs-deploy-task-definition@fc8fc60f3a60ffd500fcb13b209c59d221ac8c8c # v2.6.1
with:
task-definition: ${{ runner.temp }}/data-replication-task-definition.json
cluster: mavis-${{ inputs.environment }}-data-replication
service: mavis-${{ inputs.environment }}-data-replication
force-new-deployment: true
wait-for-service-stability: true
- name: Check if deployment was successful
# yamllint disable rule:line-length
run: |
current_task_definition_arn=$(aws ecs describe-services --cluster "mavis-$environment-data-replication" --services "mavis-$environment-data-replication" --query services[0].deployments[0].taskDefinition | jq -r ".")
new_task_definition_arn=${{ steps.ecs-deploy.outputs.task-definition-arn }}
echo "Current task definition arn: $current_task_definition_arn"
echo "Expected task definition arn after deployment: $new_task_definition_arn"
if [ "$current_task_definition_arn" != "$new_task_definition_arn" ]; then
echo "Task definition arns don't match, likely due to a rollback to the previous version. Deployment failed."
exit 1
fi
# yamllint enable rule:line-length