Skip to content

Commit c974502

Browse files
authored
Merge pull request #109 from NHSDigital/feature/terb-ELID-131-automated-deployment-networking-api
Feature/terb elid 131 automated deployment networking api
2 parents 2718f5f + a5a5477 commit c974502

File tree

5 files changed

+192
-46
lines changed

5 files changed

+192
-46
lines changed

.github/workflows/cicd-1-pull-request.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ jobs:
3939
echo "nodejs_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
4040
echo "python_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
4141
echo "terraform_version=$(grep "^terraform" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
42-
echo "version=$(head -n 1 .version 2> /dev/null || echo unknown)" >> $GITHUB_OUTPUT
42+
echo "version=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT
43+
# echo "version=$(head -n 1 .version 2> /dev/null || echo unknown)" >> $GITHUB_OUTPUT
4344
- name: "Check if pull request exists for this branch"
4445
id: pr_exists
4546
env:

.github/workflows/cicd-2-publish.yaml

Lines changed: 90 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1+
# Description: Deploys merged code to the dev environment.
2+
# Triggered on push to main. Tags the commit with a dev-<timestamp> label.
3+
# Does not create GitHub Releases or production tags (v1.x.x).
4+
15
name: "CI/CD publish"
26

37
on:
4-
pull_request:
5-
types: [closed]
8+
push:
69
branches:
710
- main
811

912
jobs:
1013
metadata:
1114
name: "Set CI/CD metadata"
1215
runs-on: ubuntu-latest
13-
if: github.event.pull_request.merged == true
1416
timeout-minutes: 1
1517
outputs:
1618
build_datetime: ${{ steps.variables.outputs.build_datetime }}
@@ -23,6 +25,7 @@ jobs:
2325
steps:
2426
- name: "Checkout code"
2527
uses: actions/checkout@v4
28+
2629
- name: "Set CI/CD variables"
2730
id: variables
2831
run: |
@@ -33,52 +36,105 @@ jobs:
3336
echo "nodejs_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
3437
echo "python_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
3538
echo "terraform_version=$(grep "^terraform" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
36-
# TODO: Get the version, but it may not be the .version file as this should come from the CI/CD Pull Request Workflow
37-
echo "version=$(head -n 1 .version 2> /dev/null || echo unknown)" >> $GITHUB_OUTPUT
39+
echo "version=dev-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT
40+
3841
- name: "List variables"
3942
run: |
40-
export BUILD_DATETIME="${{ steps.variables.outputs.build_datetime }}"
41-
export BUILD_TIMESTAMP="${{ steps.variables.outputs.build_timestamp }}"
42-
export BUILD_EPOCH="${{ steps.variables.outputs.build_epoch }}"
43-
export NODEJS_VERSION="${{ steps.variables.outputs.nodejs_version }}"
44-
export PYTHON_VERSION="${{ steps.variables.outputs.python_version }}"
45-
export TERRAFORM_VERSION="${{ steps.variables.outputs.terraform_version }}"
46-
export VERSION="${{ steps.variables.outputs.version }}"
47-
make list-variables
43+
echo "Deploying to: DEV"
44+
echo "VERSION=${{ steps.variables.outputs.version }}"
45+
4846
publish:
49-
name: "Publish packages"
47+
name: "Publish to dev"
5048
runs-on: ubuntu-latest
5149
needs: [metadata]
52-
if: github.event.pull_request.merged == true
53-
timeout-minutes: 3
50+
timeout-minutes: 10
51+
permissions:
52+
id-token: write
53+
contents: read
5454
steps:
55-
- name: "Checkout code"
55+
- name: "Setup Terraform"
56+
uses: hashicorp/setup-terraform@v3
57+
with:
58+
terraform_version: ${{ needs.metadata.outputs.terraform_version }}
59+
60+
- name: "Set up Python"
61+
uses: actions/setup-python@v5
62+
with:
63+
python-version: '3.13'
64+
65+
- name: "Checkout Repository"
5666
uses: actions/checkout@v4
57-
- name: "Get the artefacts"
67+
68+
- name: "Build lambda artefact"
5869
run: |
59-
echo "Getting the artefacts created by the build stage ..."
60-
# TODO: Use either action/cache or action/upload-artifact
61-
- name: "Create release"
62-
id: create_release
63-
uses: actions/create-release@v1
64-
env:
65-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
70+
make dependencies install-python
71+
make build
72+
73+
- name: "Upload lambda artefact"
74+
uses: actions/upload-artifact@v4
75+
with:
76+
name: lambda
77+
path: dist/lambda.zip
78+
79+
- name: "Download Built Lambdas"
80+
uses: actions/download-artifact@v4
6681
with:
67-
tag_name: ${{ needs.metadata.outputs.version }}
68-
release_name: Release ${{ needs.metadata.outputs.version }}
69-
body: |
70-
Release of ${{ needs.metadata.outputs.version }}
71-
draft: false
72-
prerelease: false
82+
name: lambda
83+
path: ./build
84+
85+
- name: "Configure AWS Credentials"
86+
uses: aws-actions/configure-aws-credentials@v4
87+
with:
88+
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/service-roles/github-actions-dev-deployment-role
89+
aws-region: eu-west-2
90+
91+
- name: "Terraform Plan Stacks"
92+
env:
93+
ENVIRONMENT: dev
94+
WORKSPACE: "default"
95+
TF_VAR_API_CA_CERT: ${{ secrets.API_CA_CERT }}
96+
TF_VAR_API_CLIENT_CERT: ${{ secrets.API_CLIENT_CERT }}
97+
TF_VAR_API_PRIVATE_KEY_CERT: ${{ secrets.API_PRIVATE_KEY_CERT }}
98+
99+
# just planning for now for safety and until review
100+
run: |
101+
mkdir -p ./build
102+
echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=networking tf-command=plan"
103+
make terraform env=$ENVIRONMENT stack=networking tf-command=plan workspace=$WORKSPACE
104+
echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=api-layer tf-command=plan"
105+
make terraform env=$ENVIRONMENT stack=api-layer tf-command=plan workspace=$WORKSPACE
106+
working-directory: ./infrastructure
107+
108+
- name: "Tag the dev deployment"
109+
run: |
110+
git config user.name "github-actions"
111+
git config user.email "[email protected]"
112+
git tag ${{ needs.metadata.outputs.version }}
113+
git push origin ${{ needs.metadata.outputs.version }}
114+
115+
# --- Keeping these just in case: Uncomment to release to GitHub ---
116+
# - name: "Create release"
117+
# id: create_release
118+
# uses: actions/create-release@v1
119+
# env:
120+
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
121+
# with:
122+
# tag_name: ${{ needs.metadata.outputs.version }}
123+
# release_name: Release ${{ needs.metadata.outputs.version }}
124+
# body: |
125+
# Release of ${{ needs.metadata.outputs.version }}
126+
# draft: false
127+
# prerelease: true
128+
73129
# - name: "Upload release asset"
74130
# uses: actions/upload-release-asset@v1
75131
# env:
76132
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77133
# with:
78134
# upload_url: "${{ steps.create_release.outputs.upload_url }}"
79-
# asset_path: ./*
80-
# asset_name: repository-template-${{ needs.metadata.outputs.version }}.tar.gz
81-
# asset_content_type: "application/gzip"
135+
# asset_path: ./build/lambda.zip
136+
# asset_name: lambda-${{ needs.metadata.outputs.version }}.zip
137+
# asset_content_type: application/zip
82138
success:
83139
name: "Success notification"
84140
runs-on: ubuntu-latest

.github/workflows/cicd-3-deploy.yaml

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1+
# Deploys a given tag to a given environment and tags for semantic versioning
2+
# creates semantic release
3+
14
name: "CI/CD deploy"
25

36
on:
47
workflow_dispatch:
58
inputs:
69
tag:
7-
description: "This is the tag that is oging to be deployed"
10+
description: "This is the tag that is going to be deployed"
811
required: true
912
default: "latest"
13+
environment:
14+
description: "Target environment (e.g., test, preprod or prod)"
15+
required: true
16+
type: choice
17+
options:
18+
- test
19+
- preprod
20+
- prod
1021

1122
jobs:
1223
metadata:
@@ -23,8 +34,11 @@ jobs:
2334
version: ${{ steps.variables.outputs.version }}
2435
tag: ${{ steps.variables.outputs.tag }}
2536
steps:
26-
- name: "Checkout code"
37+
- name: "Checkout tag"
2738
uses: actions/checkout@v4
39+
with:
40+
ref: ${{ github.event.inputs.tag }}
41+
2842
- name: "Set CI/CD variables"
2943
id: variables
3044
run: |
@@ -52,12 +66,85 @@ jobs:
5266
deploy:
5367
name: "Deploy to an environment"
5468
runs-on: ubuntu-latest
55-
needs: [metadata]
69+
needs: [ metadata ]
5670
timeout-minutes: 10
71+
permissions:
72+
id-token: write
73+
contents: read
5774
steps:
58-
- name: "Checkout code"
59-
uses: actions/checkout@v4
60-
# TODO: More jobs or/and steps here
75+
- name: "Setup Terraform"
76+
uses: hashicorp/setup-terraform@v3
77+
with:
78+
terraform_version: ${{ needs.metadata.outputs.terraform_version }}
79+
80+
- name: "Set up Python"
81+
uses: actions/setup-python@v5
82+
with:
83+
python-version: '3.13'
84+
85+
- name: "Download Built Lambdas"
86+
uses: actions/download-artifact@v4
87+
with:
88+
name: lambda
89+
path: ./build
90+
91+
- name: "Configure AWS Credentials"
92+
uses: aws-actions/configure-aws-credentials@v4
93+
with:
94+
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/service-roles/github-actions-dev-deployment-role
95+
aws-region: eu-west-2
96+
97+
- name: "Terraform Apply"
98+
env:
99+
ENVIRONMENT: ${{ inputs.environment }}
100+
WORKSPACE: "default"
101+
TF_VAR_API_CA_CERT: ${{ secrets.API_CA_CERT }}
102+
TF_VAR_API_CLIENT_CERT: ${{ secrets.API_CLIENT_CERT }}
103+
TF_VAR_API_PRIVATE_KEY_CERT: ${{ secrets.API_PRIVATE_KEY_CERT }}
104+
105+
# just planning for now for safety and until review
106+
run: |
107+
mkdir -p ./build
108+
echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=networking tf-command=plan"
109+
make terraform env=$ENVIRONMENT stack=networking tf-command=plan workspace=$WORKSPACE
110+
echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=api-layer tf-command=plan"
111+
make terraform env=$ENVIRONMENT stack=api-layer tf-command=plan workspace=$WORKSPACE
112+
working-directory: ./infrastructure
113+
114+
- name: "Tag the deployment using incremental semantic versioning"
115+
id: next_tag
116+
run: |
117+
# Fetch all tags and sort them semantically
118+
git fetch --tags
119+
latest_tag=$(git tag --list 'v*' | sort -V | tail -n 1)
120+
echo "Latest tag: $latest_tag"
121+
122+
if [[ -z "$latest_tag" ]]; then
123+
next_tag="v0.1.0"
124+
else
125+
# Extract the version numbers
126+
IFS='.' read -r major minor patch <<< "${latest_tag#v}"
127+
patch=$((patch + 1))
128+
next_tag="v${major}.${minor}.${patch}"
129+
fi
130+
131+
echo "Next tag: $next_tag"
132+
echo "tag=$next_tag" >> $GITHUB_OUTPUT
133+
134+
- name: "Create GitHub Release"
135+
uses: actions/create-release@v1
136+
env:
137+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
138+
with:
139+
tag_name: ${{ steps.next_tag.outputs.next_tag }}
140+
release_name: Release ${{ steps.next_tag.outputs.next_tag }}
141+
body: |
142+
Auto-release created during deployment.
143+
draft: false
144+
prerelease: ${{ inputs.environment == 'ref' }}
145+
146+
147+
# TODO: complete notify step
61148
# success:
62149
# name: "Success notification"
63150
# runs-on: ubuntu-latest

.github/workflows/manual-terraform-plan.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Github OIDC test
1+
name: Manual Terraform Plan
22

33
on:
44
workflow_dispatch:
@@ -35,6 +35,7 @@ jobs:
3535
run: |
3636
make dependencies install-python
3737
make build
38+
3839
- name: "Upload lambda artefact"
3940
uses: actions/upload-artifact@v4
4041
with:
@@ -55,16 +56,16 @@ jobs:
5556

5657
- name: "Terraform Plan Stacks"
5758
env:
58-
ENVIRONMENT: "dev"
59-
WORKSPACE: "default"
59+
ENVIRONMENT: ${{ inputs.environment }}
60+
WORKSPACE: ${{ inputs.environment }}
6061
TF_VAR_API_CA_CERT: ${{ secrets.API_CA_CERT }}
6162
TF_VAR_API_CLIENT_CERT: ${{ secrets.API_CLIENT_CERT }}
6263
TF_VAR_API_PRIVATE_KEY_CERT: ${{ secrets.API_PRIVATE_KEY_CERT }}
6364

6465
run: |
6566
mkdir -p ./build
66-
echo "Running: make terraform env=$ENVIRONMENT workspace=$ENVIRONMENT stack=networking tf-command=plan args=\"-auto-approve\""
67-
make terraform env=$ENVIRONMENT stack=networking tf-command=plan workspace=$ENVIRONMENT
67+
echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=networking tf-command=plan args=\"-auto-approve\""
68+
make terraform env=$ENVIRONMENT stack=networking tf-command=plan workspace=$WORKSPACE
6869
echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=api-layer tf-command=plan args=\"-auto-approve\""
6970
make terraform env=$ENVIRONMENT stack=api-layer tf-command=plan workspace=$WORKSPACE
7071

infrastructure/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ terraform-workspace-delete: guard-env guard-stack
3737
terraform: guard-env guard-stack guard-tf-command terraform-init terraform-workspace
3838
terraform -chdir=./stacks/$(stack) $(tf-command) $(args) $(if $(filter $(tf-command),init),,--parallelism=30)
3939
rm -f ./terraform_outputs_$(stack).json || true
40+
mkdir -p ./build
4041
terraform -chdir=./stacks/$(stack) output -json > ./build/terraform_outputs_$(stack).json
4142

4243
###################

0 commit comments

Comments
 (0)