-
Notifications
You must be signed in to change notification settings - Fork 0
181 lines (159 loc) · 6.52 KB
/
sahil-website.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
name: Docker image build and publish for WEBSITE
on:
workflow_dispatch:
inputs:
path_to_dockerfile:
description: Path to the dockerfile (default = 'Dockerfile')
default: "infra/docker/Dockerfile.website"
type: string
docker_build_dir:
description: Docker build directory (default = '.')
default: "."
type: string
image_tag:
description: Tag to apply to images.
type: string
default: sahil-website
lifecycle_policy_file:
description: Path to the lifecycle policy JSON file (default = 'policy.json')
default: "policy.json"
type: string
backend_s3_bucket:
description: Name of the S3bucket for Terraform backend
default: "sahil-terraform-state-bucket"
type: string
backend_iam_role:
description: Name of the Terraform backend assumable IAM Role
default: "workload-assumable-role"
type: string
github_iam_role:
description: Name of the IAM Role for adding access to ECR repo
default: "github-actions-role"
type: string
aws_account_id:
description: AWS Account ID
default: "060795911441"
type: string
aws_region:
description: Target AWS Region
default: "eu-west-1"
type: string
backend_dynamodb_table:
description: DynamoDB table for State lock
default: "sahil-terraform-table-locks"
type: string
push:
branches: ["develop", "main"]
env:
PATH_TO_DOCKERFILE: infra/docker/Dockerfile.website
DOCKER_BUILD_DIR: .
IMAGE_TAG: sahil-website
LIFECYCLE_POLICY_FILE: policy.json
BACKEND_S3_BUCKET: sahil-terraform-state-bucket
BACKEND_IAM_ROLE: workload-assumable-role
GITHUB_IAM_ROLE: github-actions-role
AWS_ACCOUNT_ID: 060795911441
AWS_REGION: eu-west-1
BACKEND_DYNAMODB_TABLE: sahil-terraform-table-locks
# concurrency required to avoid terraform lock contention during ECR provisioning
concurrency: ci-${{ github.repository }}-website-docker-pipeline
jobs:
docker:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
outputs:
image_tag: ${{ steps.build-publish.outputs.image_tag }}
version_tag: ${{ steps.build-publish.outputs.version_tag }}
full_image: ${{ steps.build-publish.outputs.full_image }}
steps:
- uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/sahil-deployment-role
aws-region: ${{ inputs.aws_region }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_wrapper: false
- name: prepare ECR repo name based on the Github repository
shell: bash
run: |
set -eux
# lowercase the name
repo="${GITHUB_REPOSITORY,,}"
# replace / with _
echo "ECR_REPO_NAME=${repo//\//_}" >> $GITHUB_ENV
- name: TF init
shell: bash
run: |
set -eux
terraform init -upgrade -reconfigure \
-backend-config='skip_metadata_api_check=true' \
-backend-config='skip_region_validation=true' \
-backend-config='skip_credentials_validation=true' \
-backend-config='region=${{ inputs.aws_region }}' \
-backend-config='bucket=${{ inputs.backend_s3_bucket }}' \
-backend-config='key=docker-ecr/terraform-${{ env.ECR_REPO_NAME }}.tfstate' \
-backend-config='dynamodb_table=${{ inputs.backend_dynamodb_table }}' \
-backend-config='assume_role={ role_arn = "arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.backend_iam_role }}" }'
working-directory: infra/terraform
- name: Create ECR repo [TF apply]
shell: bash
run: |
set -eux
terraform apply \
-var 'repository_name=${{ env.ECR_REPO_NAME }}' \
-var 'lifecycle_policy=${{ inputs.lifecycle_policy_file }}' \
-var 'iam_role=arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.github_iam_role }}' \
-var 'aws_account_id=${{ inputs.aws_account_id }}' \
-auto-approve
working-directory: infra/terraform
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
registries: ${{ inputs.aws_account_id }}
- name: Build, tag, and push image to Amazon ECR
id: build-publish
shell: bash
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPO_NAME }}
IMAGE_TAG: ${{ inputs.image_tag }}
run: |
# Get the current latest image digest (if it exists)
PREVIOUS_IMAGE_MANIFEST=$(aws ecr batch-get-image \
--repository-name $ECR_REPOSITORY \
--image-ids imageTag=$IMAGE_TAG \
--output text \
--query 'images[].imageManifest' || echo "")
# Build the new image
docker build "${{ inputs.docker_build_dir }}" -f "${{ inputs.path_to_dockerfile }}" -t "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
# Push the new image as latest
docker push "$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
# If there was a previous image, tag it as v1, v2, etc.
if [ ! -z "$PREVIOUS_IMAGE_MANIFEST" ]; then
# Get the current highest version number
CURRENT_VERSION=$(aws ecr describe-images \
--repository-name $ECR_REPOSITORY \
--query 'imageDetails[].imageTags[?starts_with(@, `v`)]' \
--output text | grep -o 'v[0-9]*' | sed 's/v//' | sort -n | tail -1)
# Calculate next version number
if [ -z "$CURRENT_VERSION" ]; then
NEW_VERSION="v1"
else
NEW_VERSION="v$((CURRENT_VERSION + 1))"
fi
# Tag the previous image with the new version
aws ecr put-image \
--repository-name $ECR_REPOSITORY \
--image-tag $NEW_VERSION \
--image-manifest "$PREVIOUS_IMAGE_MANIFEST"
echo "Previous image tagged as $NEW_VERSION"
echo "version_tag=$NEW_VERSION" >> $GITHUB_OUTPUT
fi
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "full_image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT