Skip to content

Commit cbf7080

Browse files
authored
Merge pull request #3899 from nhsuk/data_replication_improvements
Improve Data replication workflow
2 parents 4446fbb + fca17b7 commit cbf7080

2 files changed

Lines changed: 61 additions & 83 deletions

File tree

.github/workflows/data-replication-pipeline.yml

Lines changed: 51 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Data replication pipeline
2-
run-name: ${{ inputs.action }} data replication resources for ${{ inputs.environment }}
2+
run-name: ${{ inputs.deployment_type }} for data replication resources for ${{ inputs.environment }}
33

44
on:
55
workflow_dispatch:
@@ -15,18 +15,17 @@ on:
1515
- qa
1616
- sandbox-alpha
1717
- sandbox-beta
18+
deployment_type:
19+
description: Deployment type
20+
required: true
21+
type: choice
22+
options:
23+
- Deployment with DB recreation
24+
- Application only deployment
1825
image_tag:
1926
description: Docker image tag to deploy
2027
required: false
2128
type: string
22-
action:
23-
description: Action to perform on data replication env
24-
required: true
25-
type: choice
26-
options:
27-
- Destroy
28-
- Recreate
29-
default: Recreate
3029
db_snapshot_arn:
3130
description: ARN of the DB snapshot to use (optional)
3231
required: false
@@ -50,8 +49,8 @@ concurrency:
5049
group: deploy-data-replica-${{ inputs.environment }}
5150

5251
jobs:
53-
prepare:
54-
if: ${{ inputs.action == 'Recreate' }}
52+
prepare-db-replica:
53+
if: ${{ inputs.deployment_type == 'Deployment with DB recreation' }}
5554
name: Prepare data replica
5655
runs-on: ubuntu-latest
5756
permissions:
@@ -95,58 +94,13 @@ jobs:
9594
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade
9695
DB_SECRET_ARN=$(terraform output --raw db_secret_arn)
9796
echo "DB_SECRET_ARN=$DB_SECRET_ARN" >> $GITHUB_OUTPUT
98-
- name: ECR login
99-
id: login-ecr
100-
uses: aws-actions/amazon-ecr-login@v2
101-
- name: Get docker image digest
102-
id: get-docker-image-digest
103-
run: |
104-
set -e
105-
DOCKER_IMAGE="${{ steps.login-ecr.outputs.registry }}/mavis/webapp:${{ inputs.image_tag || github.sha }}"
106-
docker pull "$DOCKER_IMAGE"
107-
DOCKER_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$DOCKER_IMAGE")
108-
DIGEST="${DOCKER_DIGEST#*@}"
109-
echo "DIGEST=$DIGEST" >> $GITHUB_OUTPUT
11097
outputs:
11198
SNAPSHOT_ARN: ${{ steps.get-latest-snapshot.outputs.SNAPSHOT_ARN }}
11299
DB_SECRET_ARN: ${{ steps.get-db-secret-arn.outputs.DB_SECRET_ARN }}
113-
DOCKER_DIGEST: ${{ steps.get-docker-image-digest.outputs.DIGEST }}
114-
115-
plan-destroy:
116-
name: Plan destruction job
117-
runs-on: ubuntu-latest
118-
permissions:
119-
id-token: write
120-
steps:
121-
- name: Checkout code
122-
uses: actions/checkout@v4
123-
- name: Configure AWS Credentials
124-
uses: aws-actions/configure-aws-credentials@v4
125-
with:
126-
role-to-assume: ${{ env.aws_role }}
127-
aws-region: eu-west-2
128-
- name: Install terraform
129-
uses: hashicorp/setup-terraform@v3
130-
with:
131-
terraform_version: 1.11.4
132-
- name: Terraform Plan
133-
run: |
134-
set -e
135-
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade
136-
terraform plan -destroy -var-file="env/${{ inputs.environment }}.tfvars" -var="image_digest=filler_value" \
137-
-var="db_secret_arn=filler_value" -var="imported_snapshot=filler_value" \
138-
-out ${{ runner.temp }}/tfplan_destroy | tee ${{ runner.temp }}/tf_stdout
139-
- name: Upload artifact
140-
uses: actions/upload-artifact@v4
141-
with:
142-
name: tfplan_destroy_infrastructure-${{ inputs.environment }}
143-
path: ${{ runner.temp }}/tfplan_destroy
144100

145-
destroy:
146-
name: Destroy data replication infrastructure
101+
prepare-webapp:
102+
name: Prepare webapp
147103
runs-on: ubuntu-latest
148-
needs: plan-destroy
149-
environment: ${{ inputs.environment }}
150104
permissions:
151105
id-token: write
152106
steps:
@@ -157,32 +111,35 @@ jobs:
157111
with:
158112
role-to-assume: ${{ env.aws_role }}
159113
aws-region: eu-west-2
160-
- name: Install terraform
161-
uses: hashicorp/setup-terraform@v3
162-
with:
163-
terraform_version: 1.11.4
164-
- name: Download artifact
165-
uses: actions/download-artifact@v4
166-
with:
167-
name: tfplan_destroy_infrastructure-${{ inputs.environment }}
168-
path: ${{ runner.temp }}
169-
- name: Terraform Destroy
170-
id: destroy
114+
- name: ECR login
115+
id: login-ecr
116+
uses: aws-actions/amazon-ecr-login@v2
117+
- name: Get docker image digest
118+
id: get-docker-image-digest
171119
run: |
172120
set -e
173-
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade
174-
terraform apply ${{ runner.temp }}/tfplan_destroy
121+
DOCKER_IMAGE="${{ steps.login-ecr.outputs.registry }}/mavis/webapp:${{ inputs.image_tag || github.sha }}"
122+
docker pull "$DOCKER_IMAGE"
123+
DOCKER_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$DOCKER_IMAGE")
124+
DIGEST="${DOCKER_DIGEST#*@}"
125+
echo "DIGEST=$DIGEST" >> $GITHUB_OUTPUT
126+
outputs:
127+
DOCKER_DIGEST: ${{ steps.get-docker-image-digest.outputs.DIGEST }}
175128

176129
plan:
177130
name: Terraform plan
178131
runs-on: ubuntu-latest
179132
needs:
180-
- prepare
181-
- destroy
133+
- prepare-db-replica
134+
- prepare-webapp
135+
if: ${{ !cancelled() &&
136+
(needs.prepare-db-replica.result == 'success' || needs.prepare-db-replica.result == 'skipped') &&
137+
needs.prepare-webapp.result == 'success' }}
182138
env:
183-
SNAPSHOT_ARN: ${{ needs.prepare.outputs.SNAPSHOT_ARN }}
184-
DB_SECRET_ARN: ${{ needs.prepare.outputs.DB_SECRET_ARN }}
185-
DOCKER_DIGEST: ${{ needs.prepare.outputs.DOCKER_DIGEST }}
139+
SNAPSHOT_ARN: ${{ needs.prepare-db-replica.outputs.SNAPSHOT_ARN }}
140+
DB_SECRET_ARN: ${{ needs.prepare-db-replica.outputs.DB_SECRET_ARN || 'arn:aws:secretsmanager:eu-west-2:000000000000:secret:placeholder' }}
141+
DOCKER_DIGEST: ${{ needs.prepare-webapp.outputs.DOCKER_DIGEST }}
142+
REPLACE_DB_CLUSTER: ${{ inputs.deployment_type == 'Deployment with DB recreation' }}
186143
permissions:
187144
id-token: write
188145
steps:
@@ -200,12 +157,24 @@ jobs:
200157
- name: Terraform Plan
201158
id: plan
202159
run: |
203-
set -e
160+
set -eo pipefail
204161
terraform init -backend-config="env/${{ inputs.environment }}-backend.hcl" -upgrade
205-
terraform plan -var="image_digest=${{ env.DOCKER_DIGEST }}" -var="db_secret_arn=${{ env.DB_SECRET_ARN }}" \
206-
-var="imported_snapshot=${{ env.SNAPSHOT_ARN }}" -var-file="env/${{ inputs.environment }}.tfvars" \
207-
-var='allowed_egress_cidr_blocks=${{ inputs.egress_cidr }}' \
208-
-out ${{ runner.temp }}/tfplan | tee ${{ runner.temp }}/tf_stdout
162+
163+
CIDR_BLOCKS='${{ inputs.egress_cidr }}'
164+
PLAN_ARGS=(
165+
"plan"
166+
"-var=image_digest=${{ env.DOCKER_DIGEST }}"
167+
"-var=db_secret_arn=${{ env.DB_SECRET_ARN }}"
168+
"-var=imported_snapshot=${{ env.SNAPSHOT_ARN }}"
169+
"-var-file=env/${{ inputs.environment }}.tfvars"
170+
"-var=allowed_egress_cidr_blocks=$CIDR_BLOCKS"
171+
"-out=${{ runner.temp }}/tfplan"
172+
)
173+
174+
if [ "${{ env.REPLACE_DB_CLUSTER }}" = "true" ]; then
175+
PLAN_ARGS+=("-replace" "aws_rds_cluster.cluster")
176+
fi
177+
terraform "${PLAN_ARGS[@]}" | tee ${{ runner.temp }}/tf_stdout
209178
- name: Upload artifact
210179
uses: actions/upload-artifact@v4
211180
with:
@@ -216,6 +185,7 @@ jobs:
216185
name: Terraform apply
217186
runs-on: ubuntu-latest
218187
needs: plan
188+
if: ${{ !cancelled() && needs.plan.result == 'success' }}
219189
environment: ${{ inputs.environment }}
220190
permissions:
221191
id-token: write

terraform/data_replication/rds.tf

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ resource "aws_security_group_rule" "rds_inbound" {
1717
}
1818

1919
resource "aws_rds_cluster" "cluster" {
20-
cluster_identifier = "${local.name_prefix}-rds"
20+
cluster_identifier = "${local.name_prefix}-rds-${formatdate("hh-mm-ss", timestamp())}"
2121
engine = "aurora-postgresql"
2222
engine_mode = "provisioned"
2323
database_name = "manage_vaccinations"
@@ -34,14 +34,22 @@ resource "aws_rds_cluster" "cluster" {
3434
max_capacity = var.max_aurora_capacity_units
3535
min_capacity = 0.5
3636
}
37+
38+
lifecycle {
39+
ignore_changes = [cluster_identifier]
40+
}
3741
}
3842

3943
resource "aws_rds_cluster_instance" "instance" {
4044
cluster_identifier = aws_rds_cluster.cluster.id
41-
identifier = "${local.name_prefix}-rds-instance"
45+
identifier = "${local.name_prefix}-rds-instance-${formatdate("hh-mm-ss", timestamp())}"
4246
instance_class = "db.serverless"
4347
engine = aws_rds_cluster.cluster.engine
4448
engine_version = aws_rds_cluster.cluster.engine_version
4549
db_subnet_group_name = aws_db_subnet_group.dbsg.name
4650
promotion_tier = 1
51+
52+
lifecycle {
53+
ignore_changes = [identifier]
54+
}
4755
}

0 commit comments

Comments
 (0)