Deploy application to sandbox-beta #101
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: Deploy application | |
run-name: Deploy application to ${{ inputs.environment }} | |
on: | |
workflow_dispatch: | |
inputs: | |
environment: | |
description: Deployment environment | |
required: true | |
type: choice | |
options: | |
- qa | |
- test | |
- preview | |
- training | |
- production | |
- sandbox-alpha | |
- sandbox-beta | |
server_types: | |
description: Server types to deploy | |
required: true | |
type: choice | |
options: | |
- all | |
- web | |
- good-job | |
- sidekiq | |
default: all | |
git_sha_to_deploy: | |
description: The git commit SHA to deploy. | |
required: false | |
type: string | |
workflow_call: | |
inputs: | |
environment: | |
required: true | |
type: string | |
server_types: | |
required: true | |
type: string | |
git_sha_to_deploy: | |
description: The git commit SHA to deploy. | |
required: true | |
type: string | |
app_version: | |
description: The git ref to deploy (branch, tag, or commit SHA). | |
required: false | |
type: string | |
permissions: {} | |
concurrency: | |
group: deploy-application-${{ inputs.environment }} | |
env: | |
aws-role: ${{ inputs.environment == 'production' | |
&& 'arn:aws:iam::820242920762:role/GithubDeployECSService' | |
|| 'arn:aws:iam::393416225559:role/GithubDeployECSService' }} | |
aws_account_id: ${{ inputs.environment == 'production' && '820242920762' || '393416225559' }} | |
cluster_name: mavis-${{ inputs.environment }} | |
app_version: ${{ inputs.app_version == '' && 'unknown' || inputs.app_version }} | |
jobs: | |
prepare-deployment: | |
name: Prepare deployment | |
runs-on: ubuntu-latest | |
permissions: | |
id-token: write | |
strategy: | |
fail-fast: true | |
matrix: | |
service: ${{ inputs.server_types == 'all' && fromJSON('["web", "good-job", "sidekiq"]') || fromJSON(format('["{0}"]', inputs.server_types)) }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
with: | |
ref: ${{ inputs.git_sha_to_deploy || github.sha }} | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: ${{ env.aws-role }} | |
aws-region: eu-west-2 | |
- name: Setup python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: 3.12.3 | |
cache: pip | |
- name: Install Python dependencies | |
run: python3 -m pip install -r script/requirements.txt | |
- name: Get image digest | |
id: get-image-digest | |
run: | | |
digest=$(aws ecr describe-images \ | |
--repository-name mavis/webapp \ | |
--image-ids imageTag=${{ inputs.git_sha_to_deploy || github.sha }} \ | |
--query 'imageDetails[0].imageDigest' \ | |
--output text) | |
echo "digest=$digest" >> $GITHUB_OUTPUT | |
- name: Parse environment variables | |
id: parse-environment-variables | |
run: | | |
parsed_env_vars=$(yq -r '.environments.${{ inputs.environment }} | to_entries | .[] | .key + "=" + .value' config/container_variables.yml) | |
{ | |
echo 'parsed_env_vars<<EOF' | |
echo "$parsed_env_vars" | |
echo 'EOF' | |
} >> "$GITHUB_OUTPUT" | |
- name: Populate web task definition | |
id: create-task-definition | |
uses: aws-actions/amazon-ecs-render-task-definition@v1 | |
with: | |
task-definition-family: "mavis-${{ matrix.service }}-task-definition-${{ inputs.environment }}-template" | |
container-name: "application" | |
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 }}/${{ matrix.service }}-task-definition.json | |
- name: Populate SSM parameters for ${{ matrix.service }} service | |
run: | | |
python3 script/populate_ssm_parameters.py ${{ inputs.environment }} ${{ matrix.service }} --app-version ${{ env.app_version }} | |
- name: Upload artifact for ${{ matrix.service }} task definition | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ${{ inputs.environment }}-${{ matrix.service }}-task-definition | |
path: ${{ runner.temp }}/${{ matrix.service }}-task-definition.json | |
approve-deployments: | |
name: Wait for approval if required | |
runs-on: ubuntu-latest | |
needs: prepare-deployment | |
environment: ${{ inputs.environment }} | |
steps: | |
- run: echo "Proceeding with deployment to ${{ inputs.environment }} environment" | |
deploy-web: | |
name: Deploy web service | |
runs-on: ubuntu-latest | |
if: ${{ inputs.server_types == 'web' || inputs.server_types == 'all' }} | |
needs: [ prepare-deployment, approve-deployments ] | |
permissions: | |
id-token: write | |
steps: | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: ${{ env.aws-role }} | |
aws-region: eu-west-2 | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Download web task definition artifact | |
uses: actions/download-artifact@v4 | |
with: | |
path: ${{ runner.temp }} | |
name: ${{ inputs.environment }}-web-task-definition | |
- name: Change family of task definition | |
run: | | |
file_path="${{ runner.temp }}/web-task-definition.json" | |
family_name="mavis-web-task-definition-${{ inputs.environment }}" | |
echo "$(jq --arg f "$family_name" '.family = $f' "$file_path")" > "$file_path" | |
- name: Register web task definition | |
uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | |
with: | |
task-definition: ${{ runner.temp }}/web-task-definition.json | |
- name: Deploy web service with CodeDeploy | |
id: deploy-web-service | |
uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | |
with: | |
task-definition: ${{ runner.temp }}/web-task-definition.json | |
codedeploy-appspec: config/templates/appspec.yaml | |
cluster: ${{ env.cluster_name }} | |
service: mavis-${{ inputs.environment }}-web | |
codedeploy-application: mavis-${{ inputs.environment }} | |
codedeploy-deployment-group: blue-green-group-${{ inputs.environment }} | |
- name: Wait for deployment to complete | |
run: | | |
echo "Waiting for CodeDeploy deployment ${{ steps.deploy-web-service.outputs.codedeploy-deployment-id }} to complete..." | |
aws deploy wait deployment-successful --deployment-id "${{ steps.deploy-web-service.outputs.codedeploy-deployment-id }}" | |
echo "Deployment successful" | |
deploy-good-job: | |
name: Deploy good-job service | |
runs-on: ubuntu-latest | |
if: ${{ inputs.server_types == 'good-job' || inputs.server_types == 'all' }} | |
needs: [ prepare-deployment, approve-deployments ] | |
permissions: | |
id-token: write | |
steps: | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: ${{ env.aws-role }} | |
aws-region: eu-west-2 | |
- name: Download good-job task definition artifact | |
uses: actions/download-artifact@v5 | |
with: | |
path: ${{ runner.temp }} | |
name: ${{ inputs.environment }}-good-job-task-definition | |
- name: Change family of task definition | |
run: | | |
file_path="${{ runner.temp }}/good-job-task-definition.json" | |
family_name="mavis-good-job-task-definition-${{ inputs.environment }}" | |
echo "$(jq --arg f "$family_name" '.family = $f' "$file_path")" > "$file_path" | |
- name: Deploy good-job service | |
uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | |
with: | |
task-definition: ${{ runner.temp }}/good-job-task-definition.json | |
cluster: ${{ env.cluster_name }} | |
service: mavis-${{ inputs.environment }}-good-job | |
force-new-deployment: true | |
wait-for-service-stability: true | |
create-sidekiq-deployment: | |
name: Create sidekiq deployment | |
runs-on: ubuntu-latest | |
if: ${{ inputs.server_types == 'sidekiq' || inputs.server_types == 'all' }} | |
needs: [ prepare-deployment, approve-deployments ] | |
permissions: | |
id-token: write | |
steps: | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: ${{ env.aws-role }} | |
aws-region: eu-west-2 | |
- name: Download sidekiq task definition artifact | |
uses: actions/download-artifact@v4 | |
with: | |
path: ${{ runner.temp }} | |
name: ${{ inputs.environment }}-sidekiq-task-definition | |
- name: Change family of task definition | |
run: | | |
file_path="${{ runner.temp }}/sidekiq-task-definition.json" | |
family_name="mavis-sidekiq-task-definition-${{ inputs.environment }}" | |
echo "$(jq --arg f "$family_name" '.family = $f' "$file_path")" > "$file_path" | |
- name: Deploy sidekiq service | |
uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | |
with: | |
task-definition: ${{ runner.temp }}/sidekiq-task-definition.json | |
cluster: ${{ env.cluster_name }} | |
service: mavis-${{ inputs.environment }}-sidekiq | |
force-new-deployment: true | |
wait-for-service-stability: true | |