Skip to content

Deploy application to poc #15

Deploy application to poc

Deploy application to poc #15

name: Deploy application
run-name: Deploy application to ${{ inputs.environment }}
on:
workflow_dispatch:
inputs:
environment:
description: Deployment environment
required: true
type: choice
options:
- qa
- poc
- copilotmigration
- test
- preview
- training
- production
image_tag:
description: Docker image tag
required: false
type: string
server_types:
description: Server types to deploy
required: true
type: choice
options:
- all
- thrust
- good-job
default: all
workflow_call:
inputs:
environment:
required: true
type: string
image_tag:
required: false
type: string
server_types:
required: true
type: string
concurrency:
group: deploy-application-${{ inputs.environment }}
env:
aws-role: ${{ inputs.environment == 'production'
&& 'arn:aws:iam::820242920762:role/GithubDeployMavisAndInfrastructure'
|| 'arn:aws:iam::393416225559:role/GithubDeployMavisAndInfrastructure' }}
terraform-working-directory: terraform/app
terraform-target-options: ${{ inputs.server_types == 'thrust'
&& '-target=aws_ecs_task_definition.task_definition -target=aws_s3_object.appspec_object'
|| inputs.server_types == 'good-job'
&& '-target=module.good-job_service.aws_ecs_task_definition.this'
|| '-target=aws_ecs_task_definition.task_definition -target=aws_s3_object.appspec_object -target=module.good-job_service.aws_ecs_task_definition.this' }}
jobs:
plan-changes:
name: Plan task definition changes
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.aws-role }}
aws-region: eu-west-2
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: pull docker image
run: |
DOCKER_IMAGE="${{ steps.login-ecr.outputs.registry }}/mavis/webapp:${{ inputs.image_tag || github.sha }}"
docker pull "$DOCKER_IMAGE"
echo "DOCKER_IMAGE=$DOCKER_IMAGE" >> $GITHUB_ENV
- name: Extract image digest
run: |
DOCKER_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$DOCKER_IMAGE")
DIGEST="${DOCKER_DIGEST#*@}"
echo "DIGEST=$DIGEST" >> $GITHUB_ENV
- name: Install terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.10.5
- name: Update the task definition
id: plan
working-directory: ${{ env.terraform-working-directory }}
run: |
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade
terraform plan ${{ env.terraform-target-options }} -var-file="env/${{ inputs.environment }}.tfvars" \
-var="image_digest=$DIGEST" -out=${{ runner.temp }}/tfplan | tee ${{ runner.temp }}/tf_stdout
- name: Validate the changes
run: |
./terraform/scripts/check_task_definition.sh ${{ runner.temp }}/tf_stdout
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: tfplan_app-${{ inputs.environment }}
path: ${{ runner.temp }}/tfplan
apply-changes:
name: Apply task definition changes
runs-on: ubuntu-latest
needs: plan-changes
environment: ${{ inputs.environment }}
permissions:
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- 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 artifact
uses: actions/download-artifact@v4
with:
name: tfplan_app-${{ inputs.environment }}
path: ${{ runner.temp }}
- name: Install terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.10.5
- name: Apply the changes
working-directory: ${{ env.terraform-working-directory }}
run: |
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade
terraform apply ${{ runner.temp }}/tfplan
echo "s3_bucket=$(terraform output -raw s3_bucket)" >> ${{ runner.temp }}/DEPLOYMENT_ENVS
echo "s3_key=$(terraform output -raw s3_key)" >> ${{ runner.temp }}/DEPLOYMENT_ENVS
echo "application=$(terraform output -raw codedeploy_application_name)" >> ${{ runner.temp }}/DEPLOYMENT_ENVS
echo "application_group=$(terraform output -raw codedeploy_deployment_group_name)" >> ${{ runner.temp }}/DEPLOYMENT_ENVS
echo "ecs_variables=$(terraform output -json ecs_variables | sed 's/\"/\\"/g')" >> ${{ runner.temp }}/DEPLOYMENT_ENVS
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: DEPLOYMENT_ENVS-${{ inputs.environment }}
path: ${{ runner.temp }}/DEPLOYMENT_ENVS
create-thrust-deployment:
name: Create thrust deployment
runs-on: ubuntu-latest
needs: apply-changes
if: inputs.server_types == 'thrust' || inputs.server_types == 'all'
environment: ${{ inputs.environment }}
permissions:
id-token: write
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: DEPLOYMENT_ENVS-${{ inputs.environment }}
path: ${{ runner.temp }}/artifact
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.aws-role }}
aws-region: eu-west-2
- name: Install AWS CLI
run: sudo snap install --classic aws-cli
- name: Trigger CodeDeploy deployment
run: |
source ${{ runner.temp }}/artifact/DEPLOYMENT_ENVS
deployment_id=$(aws deploy create-deployment \
--application-name "$application" --deployment-group-name "$application_group" \
--s3-location bucket="$s3_bucket",key="$s3_key",bundleType=yaml | jq -r .deploymentId)
echo "Deployment started: $deployment_id"
echo "deployment_id=$deployment_id" >> $GITHUB_ENV
- name: Wait up to 30 minutes for deployment to complete
run: |
aws deploy wait deployment-successful --deployment-id $deployment_id
echo "Deployment successful"
create-good-job-deployment:
name: Create good-job deployment
runs-on: ubuntu-latest
needs: apply-changes
if: inputs.server_types == 'good-job' || inputs.server_types == 'all'
environment: ${{ inputs.environment }}
permissions:
id-token: write
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: DEPLOYMENT_ENVS-${{ inputs.environment }}
path: ${{ runner.temp }}/artifact
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.aws-role }}
aws-region: eu-west-2
- name: Install AWS CLI
run: sudo snap install --classic aws-cli
- name: Trigger ECR Deployment
run: |
source ${{ runner.temp }}/artifact/DEPLOYMENT_ENVS
echo "$ecs_variables"
cluster_name=$(echo "$ecs_variables" | jq -r '.cluster_name')
service_name=$(echo "$ecs_variables" | jq -r '.good_job.service_name')
task_definition=$(echo "$ecs_variables" | jq -r '.good_job.task_definition')
DEPLOYMENT_ID=$(aws ecs update-service --cluster $cluster_name --service $service_name \
--task-definition $task_definition --force-new-deployment \
--query 'service.deployments[?rolloutState==`IN_PROGRESS`].[id][0]' --output text)
echo "Deployment started: $DEPLOYMENT_ID"
echo "deployment_id=$DEPLOYMENT_ID" >> $GITHUB_ENV
- name: Wait for deployment to complete
run: |
source ${{ runner.temp }}/artifact/DEPLOYMENT_ENVS
cluster_name=$(echo "$ecs_variables" | jq -r '.cluster_name')
service_name=$(echo "$ecs_variables" | jq -r '.good_job.service_name')
DEPLOYMENT_STATE=IN_PROGRESS
while $DEPLOYMENT_STATE=IN_PROGRESS; do
echo "Waiting for deployment to complete..."
sleep 30
DEPLOYMENT_STATE="$(aws ecs describe-services --cluster $cluster_name --services $service_name \
--query 'services[0].deployments[?id == `$deployment_id`].[rolloutState][0]' --output text)"
done
if [ "$DEPLOYMENT_STATE" != "COMPLETED" ]; then
echo "Deployment failed with state: $DEPLOYMENT_STATE"
exit 1
fi
echo "Deployment successful"