Skip to content

Commit 26ffaa2

Browse files
committed
Deploy / destroy review apps with CodeBuild
Instead of running Terraform directly in the GitHub Actions runners, we now trigger AWS CodeBuild projects to handle the deployment and destruction of review apps. This means that the repository no longer needs extensive AWS permissions in GitHub Actions, and the actual available AWS operations are limited.
1 parent 2badaf1 commit 26ffaa2

File tree

2 files changed

+45
-67
lines changed

2 files changed

+45
-67
lines changed

.github/workflows/review_apps_on_pr_change.yml

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
name: "Review apps: on PR change"
22
on:
33
pull_request:
4-
# being explicit about what to trigger on.
5-
# matches the docs for the default types
6-
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request
74
types: [opened, reopened, synchronize]
85

96
concurrency:
107
group: "review-apps-forms-runner-pr-${{ github.event.pull_request.number }}"
118
cancel-in-progress: false
9+
1210
jobs:
1311
update-review-app:
1412
runs-on: ubuntu-24.04-arm
15-
1613
permissions:
1714
id-token: write
1815
contents: read
@@ -24,63 +21,61 @@ jobs:
2421
with:
2522
role-to-assume: arn:aws:iam::842676007477:role/review-github-actions-forms-runner
2623
aws-region: eu-west-2
27-
- name: Generate container image URI
28-
run: |
29-
echo "CONTAINER_IMAGE_URI=842676007477.dkr.ecr.eu-west-2.amazonaws.com/forms-runner:pr-${{github.event.pull_request.number}}-${{github.event.pull_request.head.sha}}-$(date +%s)" >> "$GITHUB_ENV"
3024

3125
- name: Checkout code
3226
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
3327

34-
- name: Build container
28+
- name: Generate container image URI
3529
run: |
36-
docker build \
37-
--tag "${{env.CONTAINER_IMAGE_URI}}" \
38-
.
30+
echo "CONTAINER_IMAGE_URI=842676007477.dkr.ecr.eu-west-2.amazonaws.com/forms-runner:pr-${{github.event.pull_request.number}}-${{github.event.pull_request.head.sha}}-$(date +%s)" >> "$GITHUB_ENV"
31+
32+
- name: Build container
33+
run: docker build --tag "${{env.CONTAINER_IMAGE_URI}}" .
3934

4035
- name: Push container
41-
id: build-container
4236
run: |
4337
aws ecr get-login-password --region eu-west-2 \
4438
| docker login --username AWS --password-stdin 842676007477.dkr.ecr.eu-west-2.amazonaws.com
45-
46-
echo "Pushing container image"
47-
echo "${{env.CONTAINER_IMAGE_URI}}"
48-
4939
docker push "${CONTAINER_IMAGE_URI}"
5040
51-
- name: Determine Terraform version
52-
id: terraform-version
53-
run: |
54-
echo "TF_VERSION=$(< .review_apps/.terraform-version)" >> "$GITHUB_OUTPUT"
55-
56-
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
41+
- name: Deploy review app via CodeBuild
42+
id: codebuild
43+
uses: aws-actions/aws-codebuild-run-build@4d15a47425739ac2296ba5e7eee3bdd4bfbdd767 # v1.0.18
5744
with:
58-
terraform_version: ${{steps.terraform-version.outputs.TF_VERSION}}
45+
project-name: review-forms-runner-deploy
46+
env-vars-for-codebuild: |
47+
PR_NUMBER,
48+
CONTAINER_IMAGE
49+
env:
50+
PR_NUMBER: ${{ github.event.pull_request.number }}
51+
CONTAINER_IMAGE: ${{ env.CONTAINER_IMAGE_URI }}
5952

60-
- name: Deploy review app
61-
id: deploy
53+
- name: Fetch terraform outputs
54+
id: outputs
6255
run: |
63-
cd .review_apps/
56+
# Extract build UUID from ARN (format: arn:aws:codebuild:region:account:build/project:uuid)
57+
BUILD_ID="${{ steps.codebuild.outputs.aws-build-id }}"
58+
BUILD_UUID="${BUILD_ID##*:}"
6459
65-
terraform init -backend-config="key=review-apps/forms-runner/pr-${{github.event.pull_request.number}}.tfstate"
60+
# Download artifact
61+
aws s3 cp "s3://forms-review-codebuild-artifacts/${BUILD_UUID}/review-forms-runner-deploy/outputs.json" outputs.json
6662
67-
terraform apply \
68-
-var "pull_request_number=${{github.event.pull_request.number}}" \
69-
-var "forms_runner_container_image=${{env.CONTAINER_IMAGE_URI}}" \
70-
-no-color \
71-
-auto-approve
63+
# Parse outputs
64+
{
65+
echo "REVIEW_APP_URL=$(jq -r '.review_app_url.value' outputs.json)"
66+
echo "ADMIN_APP_URL=$(jq -r '.admin_app_url.value' outputs.json)"
67+
echo "ECS_CLUSTER_ID=$(jq -r '.review_app_ecs_cluster_id.value' outputs.json)"
68+
echo "ECS_SERVICE_NAME=$(jq -r '.review_app_ecs_service_name.value' outputs.json)"
69+
} >> "$GITHUB_OUTPUT"
7270
73-
# shellcheck disable=SC2129 # SC2129 is "mainly a stylistic issue" and it breaks our flow
74-
echo "REVIEW_APP_URL=$(terraform output -raw review_app_url)" >> "$GITHUB_OUTPUT"
75-
echo "ADMIN_APP_URL=$(terraform output -raw admin_app_url)" >> "$GITHUB_OUTPUT"
76-
echo "ECS_CLUSTER_ID=$(terraform output -raw review_app_ecs_cluster_id)" >> "$GITHUB_OUTPUT"
77-
echo "ECS_SERVICE_NAME=$(terraform output -raw review_app_ecs_service_name)" >> "$GITHUB_OUTPUT"
71+
# Clean up artifact
72+
aws s3 rm "s3://forms-review-codebuild-artifacts/${BUILD_UUID}/review-forms-runner-deploy/outputs.json"
7873
7974
- name: Wait for AWS ECS deployments to finish
8075
run: |
8176
aws ecs wait services-stable \
82-
--cluster "${{steps.deploy.outputs.ECS_CLUSTER_ID}}" \
83-
--services "${{steps.deploy.outputs.ECS_SERVICE_NAME}}"
77+
--cluster "${{ steps.outputs.outputs.ECS_CLUSTER_ID }}" \
78+
--services "${{ steps.outputs.outputs.ECS_SERVICE_NAME }}"
8479
8580
- name: Comment on PR
8681
env:
@@ -90,8 +85,8 @@ jobs:
9085
cat <<EOF > "${{runner.temp}}/pr-comment.md"
9186
:tada: A review copy of this PR has been deployed! It is made of up two components
9287
93-
1. [A review copy of forms-runner](${{steps.deploy.outputs.REVIEW_APP_URL}})
94-
2. [A production copy of forms-admin](${{steps.deploy.outputs.ADMIN_APP_URL}})
88+
1. [A review copy of forms-runner](${{steps.outputs.outputs.REVIEW_APP_URL}})
89+
2. [A production copy of forms-admin](${{steps.outputs.outputs.ADMIN_APP_URL}})
9590
9691
> [!IMPORTANT]
9792
> Not all of the functionality of forms-runner is present in review apps.
@@ -109,9 +104,7 @@ jobs:
109104
$COMMENT_MARKER
110105
EOF
111106
112-
# shellcheck disable=SC2016
113-
# `jq` uses single-quote characters on Unix shells
114-
old_comment_ids=$(gh api "repos/{owner}/{repo}/issues/${{github.event.pull_request.number}}/comments" --jq 'map(select((.user.login == "github-actions[bot]") and (.body | endswith($ENV.COMMENT_MARKER + "\n")))) | .[].id')
107+
old_comment_ids=$(gh api "repos/{owner}/{repo}/issues/${{github.event.pull_request.number}}/comments" --jq "map(select((.user.login == \"github-actions[bot]\") and (.body | endswith(\$ENV.COMMENT_MARKER + \"\n\")))) | .[].id")
115108
for comment_id in $old_comment_ids; do
116109
gh api -X DELETE "repos/{owner}/{repo}/issues/comments/${comment_id}"
117110
done
Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
name: "Review apps: on PR close"
22
on:
33
pull_request:
4-
# only run when a PR is closed or merged
54
types: [closed]
65

76
concurrency:
87
group: "review-apps-forms-runner-pr-${{ github.event.pull_request.number }}"
98
cancel-in-progress: false
10-
env:
11-
IMAGE_TAG: "842676007477.dkr.ecr.eu-west-2.amazonaws.com/forms-runner:pr-${{github.event.pull_request.number}}-${{github.event.pull_request.head.ref}}"
9+
1210
jobs:
1311
delete-review-app:
1412
runs-on: ubuntu-24.04-arm
@@ -22,25 +20,12 @@ jobs:
2220
with:
2321
role-to-assume: arn:aws:iam::842676007477:role/review-github-actions-forms-runner
2422
aws-region: eu-west-2
25-
- name: Checkout code
26-
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
27-
28-
- name: Determine Terraform version
29-
id: terraform-version
30-
run: |
31-
echo "TF_VERSION=$(< .review_apps/.terraform-version)" >> "$GITHUB_OUTPUT"
3223

33-
- uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
24+
- name: Destroy review app via CodeBuild
25+
uses: aws-actions/aws-codebuild-run-build@4d15a47425739ac2296ba5e7eee3bdd4bfbdd767 # v1.0.18
3426
with:
35-
terraform_version: ${{steps.terraform-version.outputs.TF_VERSION}}
36-
37-
- name: Delete review app
38-
run: |
39-
cd .review_apps/
40-
41-
terraform init -backend-config="key=review-apps/forms-runner/pr-${{github.event.pull_request.number}}.tfstate"
42-
terraform destroy \
43-
-var "pull_request_number=${{github.event.pull_request.number}}" \
44-
-var "forms_runner_container_image=${{env.IMAGE_TAG}}" \
45-
-no-color \
46-
-auto-approve
27+
project-name: review-forms-runner-destroy
28+
env-vars-for-codebuild: |
29+
PR_NUMBER
30+
env:
31+
PR_NUMBER: ${{ github.event.pull_request.number }}

0 commit comments

Comments
 (0)