Skip to content

Commit 4fe843c

Browse files
Replace deploy-application code
- Use new flow - Intermediary step for testing process
1 parent 5620df4 commit 4fe843c

File tree

8 files changed

+436
-385
lines changed

8 files changed

+436
-385
lines changed

.github/workflows/deploy-application.yml

Lines changed: 128 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ on:
2525
- web
2626
- good-job
2727
default: all
28+
git_sha_to_deploy:
29+
description: The git commit SHA to deploy.
30+
required: false
31+
type: string
2832
workflow_call:
2933
inputs:
3034
environment:
@@ -38,15 +42,21 @@ on:
3842
required: true
3943
type: string
4044

41-
permissions: {}
45+
permissions: { }
4246

4347
concurrency:
44-
group: deploy-application-${{ inputs.environment }}
48+
group: deploy-mavis-${{ inputs.environment }}
4549

4650
env:
4751
aws-role: ${{ inputs.environment == 'production'
4852
&& 'arn:aws:iam::820242920762:role/GithubDeployMavisAndInfrastructure'
4953
|| 'arn:aws:iam::393416225559:role/GithubDeployMavisAndInfrastructure' }}
54+
web_codedeploy_application: mavis-${{ inputs.environment }}
55+
web_codedeploy_group: blue-green-group-${{ inputs.environment }}
56+
web_task_definition: mavis-web-task-definition-${{ inputs.environment }}
57+
cluster_name: mavis-${{ inputs.environment }}
58+
good_job_service: mavis-${{ inputs.environment }}-good-job
59+
good_job_task_definition: mavis-good-job-task-definition-${{ inputs.environment }}
5060

5161
jobs:
5262
prepare-deployment:
@@ -58,109 +68,165 @@ jobs:
5868
steps:
5969
- name: Checkout code
6070
uses: actions/checkout@v4
61-
with:
62-
ref: ${{ inputs.git_sha_to_deploy || github.sha }}
6371
- name: Configure AWS Credentials
6472
uses: aws-actions/configure-aws-credentials@v4
6573
with:
6674
role-to-assume: ${{ env.aws-role }}
6775
aws-region: eu-west-2
68-
- name: Install terraform
69-
uses: hashicorp/setup-terraform@v3
70-
with:
71-
terraform_version: 1.11.4
72-
- name: Get terraform output
73-
id: terraform-output
74-
working-directory: terraform/app
76+
- name: Get image digest from ECR
77+
id: get-image-digest
78+
run: |
79+
# Get AWS account ID and construct repository URI
80+
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
81+
REPOSITORY_URI="${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/mavis"
82+
83+
# Get the image digest for the git SHA
84+
IMAGE_DIGEST=$(aws ecr describe-images \
85+
--repository-name mavis/webapp \
86+
--image-ids imageTag=${{ inputs.git_sha_to_deploy || github.sha }} \
87+
--query 'imageDetails[0].imageDigest' \
88+
--output text)
89+
90+
NEW_IMAGE_URI="${REPOSITORY_URI}@${IMAGE_DIGEST}"
91+
echo "new-image-uri=${NEW_IMAGE_URI}" >> $GITHUB_OUTPUT
92+
echo "New image URI: ${NEW_IMAGE_URI}"
93+
- name: Populate web task definition
94+
if: inputs.server_types == 'web' || inputs.server_types == 'all'
95+
id: render-web-task-definition
7596
run: |
76-
set -e
77-
terraform init -backend-config=env/${{ inputs.environment }}-backend.hcl -reconfigure
78-
terraform output -json | jq -r '
79-
"s3_bucket=" + .s3_bucket.value,
80-
"s3_key=" + .s3_key.value,
81-
"application=" + .codedeploy_application_name.value,
82-
"application_group=" + .codedeploy_deployment_group_name.value,
83-
"cluster_name=" + .ecs_variables.value.cluster_name,
84-
"good_job_service=" + .ecs_variables.value.good_job.service_name,
85-
"good_job_task_definition=" + .ecs_variables.value.good_job.task_definition.arn
86-
' > ${{ runner.temp }}/DEPLOYMENT_ENVS
87-
- name: Upload Artifact
88-
uses: actions/upload-artifact@v4
97+
./script/populate_task_definition.sh ${{ inputs.environment }} web \
98+
-i "${{ steps.get-image-digest.outputs.new-image-uri }}" \
99+
-o web-task-definition.json
100+
- name: Populate good-job task definition
101+
if: inputs.server_types == 'good-job' || inputs.server_types == 'all'
102+
id: render-good-job-task-definition
103+
run: |
104+
./script/populate_task_definition.sh ${{ inputs.environment }} good-job \
105+
-i "${{ steps.get-image-digest.outputs.new-image-uri }}" \
106+
-o good-job-task-definition.json
107+
- name: Upload web task definition
108+
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
109+
id: upload-web-task-definition
110+
with:
111+
task-definition: web-task-definition.json
112+
- name: Upload good-job task definition
113+
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
114+
id: upload-good-job-task-definition
89115
with:
90-
name: DEPLOYMENT_ENVS-${{ inputs.environment }}
91-
path: ${{ runner.temp }}/DEPLOYMENT_ENVS
116+
task-definition: good-job-task-definition.json
117+
outputs:
118+
new-image-uri: ${{ steps.get-image-digest.outputs.new-image-uri }}
119+
web-task-definition-arn: ${{ steps.upload-web-task-definition.outputs.task-definition-arn }}
120+
good-job-task-definition-arn: ${{ steps.upload-good-job-task-definition.outputs.task-definition-arn }}
92121

93-
create-web-deployment:
94-
name: Create web deployment
122+
deploy-web:
123+
name: Deploy web service
95124
runs-on: ubuntu-latest
96-
needs: prepare-deployment
97125
if: inputs.server_types == 'web' || inputs.server_types == 'all'
126+
needs: prepare-deployment
127+
environment: ${{ inputs.environment }}
98128
permissions:
99129
id-token: write
100130
steps:
101-
- name: Download artifact
102-
uses: actions/download-artifact@v4
103-
with:
104-
name: DEPLOYMENT_ENVS-${{ inputs.environment }}
105-
path: ${{ runner.temp }}
106131
- name: Configure AWS Credentials
107132
uses: aws-actions/configure-aws-credentials@v4
108133
with:
109134
role-to-assume: ${{ env.aws-role }}
110135
aws-region: eu-west-2
111-
- name: Trigger CodeDeploy deployment
136+
- name: Download web task definition artifact
137+
uses: actions/download-artifact@v4
138+
with:
139+
name: web-task-definition
140+
path: ./artifacts
141+
- name: Create appspec.yml
142+
run: |
143+
echo "version: 0.0" > appspec.yml
144+
echo "Resources:" >> appspec.yml
145+
echo " - TargetService:" >> appspec.yml
146+
echo " Type: AWS::ECS::Service" >> appspec.yml
147+
echo " Properties:" >> appspec.yml
148+
echo " TaskDefinition: ${{ steps.render-web-task-definition.outputs.task-definition }}" >> appspec.yml
149+
echo " LoadBalancerInfo:" >> appspec.yml
150+
echo " ContainerName: web" >> appspec.yml
151+
echo " ContainerPort: 80" >> appspec.yml
152+
- name: Deploy web service with CodeDeploy
153+
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
154+
with:
155+
task-definition: ${{ steps.render-web-task-definition.outputs.task-definition }}
156+
codedeploy-appspec:
157+
codedeploy-application:
158+
codedeploy-deployment-group:
159+
- name: Deploy with CodeDeploy
112160
run: |
113-
set -e
114-
source ${{ runner.temp }}/DEPLOYMENT_ENVS
161+
# Create CodeDeploy deployment for blue-green deployment
115162
deployment_id=$(aws deploy create-deployment \
116-
--application-name "$application" --deployment-group-name "$application_group" \
117-
--s3-location bucket="$s3_bucket",key="$s3_key",bundleType=yaml | jq -r .deploymentId)
118-
echo "Deployment started: $deployment_id"
163+
--application-name ${{ env.web_codedeploy_application }} \
164+
--deployment-group-name ${{ env.web_codedeploy_group }} \
165+
--deployment-config-name CodeDeployDefault.ECSBlueGreenCanary10Percent5Minutes \
166+
--description "Deployment from GitHub Actions" \
167+
| jq -r .deploymentId)
168+
169+
echo "CodeDeploy deployment started: $deployment_id"
119170
echo "deployment_id=$deployment_id" >> $GITHUB_ENV
120-
- name: Wait up to 30 minutes for deployment to complete
171+
- name: Wait for deployment to complete
121172
run: |
122-
set -e
173+
echo "Waiting for CodeDeploy deployment $deployment_id to complete..."
123174
aws deploy wait deployment-successful --deployment-id "$deployment_id"
124175
echo "Deployment successful"
125176
126-
create-good-job-deployment:
127-
name: Create good-job deployment
177+
deploy-good-job:
178+
name: Deploy good-job service
128179
runs-on: ubuntu-latest
129-
needs: prepare-deployment
130180
if: inputs.server_types == 'good-job' || inputs.server_types == 'all'
181+
needs: prepare-deployment
182+
environment: ${{ inputs.environment }}
131183
permissions:
132184
id-token: write
133185
steps:
134-
- name: Download Artifact
135-
uses: actions/download-artifact@v4
136-
with:
137-
name: DEPLOYMENT_ENVS-${{ inputs.environment }}
138-
path: ${{ runner.temp }}
139186
- name: Configure AWS Credentials
140187
uses: aws-actions/configure-aws-credentials@v4
141188
with:
142189
role-to-assume: ${{ env.aws-role }}
143190
aws-region: eu-west-2
144-
- name: Trigger ECS Deployment
191+
- name: Download good-job task definition artifact
192+
uses: actions/download-artifact@v4
193+
with:
194+
name: good-job-task-definition
195+
path: ./artifacts
196+
- name: Register new task definition
145197
run: |
146-
set -e
147-
source ${{ runner.temp }}/DEPLOYMENT_ENVS
148-
DEPLOYMENT_ID=$(aws ecs update-service --cluster $cluster_name --service $good_job_service \
149-
--task-definition $good_job_task_definition --force-new-deployment \
150-
--query 'service.deployments[?rolloutState==`IN_PROGRESS`].[id][0]' --output text)
151-
echo "Deployment started: $DEPLOYMENT_ID"
198+
# Find the task definition file in the artifacts directory
199+
TASK_DEF_FILE=$(find ./artifacts -name "*.json" -type f | head -1)
200+
TASK_DEFINITION_ARN=$(aws ecs register-task-definition --cli-input-json file://$TASK_DEF_FILE --query 'taskDefinition.taskDefinitionArn' --output text)
201+
echo "New task definition registered: $TASK_DEFINITION_ARN"
202+
echo "task_definition_arn=$TASK_DEFINITION_ARN" >> $GITHUB_ENV
203+
- name: Update ECS service
204+
run: |
205+
# Update the good-job service with the new task definition
206+
DEPLOYMENT_ID=$(aws ecs update-service \
207+
--cluster ${{ env.cluster_name }} \
208+
--service ${{ env.good_job_service }} \
209+
--task-definition "$task_definition_arn" \
210+
--force-new-deployment \
211+
--query 'service.deployments[?rolloutState==`IN_PROGRESS`].[id][0]' \
212+
--output text)
213+
214+
echo "ECS deployment started: $DEPLOYMENT_ID"
152215
echo "deployment_id=$DEPLOYMENT_ID" >> $GITHUB_ENV
153216
- name: Wait for deployment to complete
154217
run: |
155-
set -e
156-
source ${{ runner.temp }}/DEPLOYMENT_ENVS
218+
echo "Waiting for ECS deployment $deployment_id to complete..."
157219
DEPLOYMENT_STATE=IN_PROGRESS
158220
while [ "$DEPLOYMENT_STATE" == "IN_PROGRESS" ]; do
159-
echo "Waiting for deployment to complete..."
221+
echo "Checking deployment status..."
160222
sleep 30
161-
DEPLOYMENT_STATE="$(aws ecs describe-services --cluster $cluster_name --services $good_job_service \
162-
--query "services[0].deployments[?id == \`$deployment_id\`].[rolloutState][0]" --output text)"
223+
DEPLOYMENT_STATE=$(aws ecs describe-services \
224+
--cluster ${{ env.cluster_name }} \
225+
--services ${{ env.good_job_service }} \
226+
--query "services[0].deployments[?id == \`$deployment_id\`].[rolloutState][0]" \
227+
--output text)
163228
done
229+
164230
if [ "$DEPLOYMENT_STATE" != "COMPLETED" ]; then
165231
echo "Deployment failed with state: $DEPLOYMENT_STATE"
166232
exit 1

0 commit comments

Comments
 (0)