Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions .github/workflows/deploy-account-wide-infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: Deploy Account-wide infrastructure
run-name: Account-wide infra deployment to ${{ inputs.environment }} of ${{ inputs.branch_name }} by ${{ github.actor }}

on:
workflow_dispatch:
inputs:
environment:
description: "Account to deploy to"
required: true
default: "account-dev"
type: environment
branch_name:
description: Branch to deploy
required: true

permissions:
id-token: write
contents: read
actions: write

jobs:
check-selected-environment:
name: Check Workflow Env
runs-on: codebuild-nhsd-nrlf-ci-build-project-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- name: Validate environment
env:
IS_VALID_ENV: ${{ startsWith(inputs.environment, 'account-') }}
run: |
echo "valid workflow environment selected:" $IS_VALID_ENV
if [[ $IS_VALID_ENV == true ]]; then
exit 0
fi
echo "This workflow can only be run with 'account-*' environments as it deploys account-specific infrastructure"
exit 1

terraform-plan:
name: Terraform Plan - ${{ inputs.environment }}
environment: ${{ inputs.environment }}
needs: [check-selected-environment]
runs-on: codebuild-nhsd-nrlf-ci-build-project-${{ github.run_id }}-${{ github.run_attempt }}

steps:
- name: Git clone - ${{ inputs.branch_name }}
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch_name }}

- name: Setup environment
run: |
echo "${HOME}/.asdf/bin" >> $GITHUB_PATH
poetry install --no-root

- name: Configure Management Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a #v4.3.1
with:
aws-region: eu-west-2
role-to-assume: ${{ secrets.MGMT_ROLE_ARN }}
role-session-name: github-actions-ci-${{ inputs.environment }}-${{ github.run_id }}

- name: Retrieve Server Certificates
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: |
make truststore-pull-all-for-account ACCOUNT=${ACCOUNT_NAME}

- name: Terraform Init
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: |
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} init
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} workspace new ${ACCOUNT_NAME} || \
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} workspace select ${ACCOUNT_NAME}

- name: Terraform Plan
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
run: |
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} plan \
-var assume_account=${ACCOUNT_ID} \
-var assume_role=terraform \
-out tfplan

- name: Save Terraform Plan
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: |
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} show -no-color tfplan > terraform/account-wide-infrastructure/$ACCOUNT_NAME/tfplan.txt

aws s3 cp terraform/account-wide-infrastructure/$ACCOUNT_NAME/tfplan s3://nhsd-nrlf--mgmt--github-ci-logging/acc-$ACCOUNT_NAME/${{ github.run_id }}/tfplan
aws s3 cp terraform/account-wide-infrastructure/$ACCOUNT_NAME/tfplan.txt s3://nhsd-nrlf--mgmt--github-ci-logging/acc-$ACCOUNT_NAME/${{ github.run_id }}/tfplan.txt

terraform-apply:
name: Terraform Apply - ${{ inputs.environment }}
needs: [terraform-plan]
runs-on: codebuild-nhsd-nrlf-ci-build-project-${{ github.run_id }}-${{ github.run_attempt }}
environment: ${{ inputs.environment }}

steps:
- name: Git clone - ${{ inputs.branch_name }}
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch_name }}

- name: Setup environment
run: |
echo "${HOME}/.asdf/bin" >> $GITHUB_PATH
poetry install --no-root

- name: Configure Management Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a #v4.3.1
with:
aws-region: eu-west-2
role-to-assume: ${{ secrets.MGMT_ROLE_ARN }}
role-session-name: github-actions-ci-${{ inputs.environment }}-${{ github.run_id}}

- name: Download Terraform Plan artifact
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: aws s3 cp s3://nhsd-nrlf--mgmt--github-ci-logging/acc-$ACCOUNT_NAME/${{ github.run_id }}/tfplan terraform/account-wide-infrastructure/${ACCOUNT_NAME}/tfplan

- name: Retrieve Server Certificates
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: |
make truststore-pull-all-for-account ACCOUNT=${ACCOUNT_NAME}

- name: Terraform Init
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: |
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} init
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} workspace new ${ACCOUNT_NAME} || \
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} workspace select ${ACCOUNT_NAME}

- name: Terraform Apply
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
run: |
terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} apply tfplan

- name: Update environment config version
env:
ACCOUNT_NAME: ${{ vars.ACCOUNT_NAME }}
run: |
deployed_version=$(terraform -chdir=terraform/account-wide-infrastructure/${ACCOUNT_NAME} output --raw version)
echo $deployed_version
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SMOKE_TEST_ARGS ?=
FEATURE_TEST_ARGS ?= ./tests/features --format progress2
TF_WORKSPACE_NAME ?= $(shell terraform -chdir=terraform/infrastructure workspace show)
ENV ?= dev
ACCOUNT ?= dev
APP_ALIAS ?= default
HOST ?= $(TF_WORKSPACE_NAME).api.record-locator.$(ENV).national.nhs.uk
ENV_TYPE ?= $(ENV)
Expand Down Expand Up @@ -201,6 +202,9 @@ truststore-build-ca: check-warn ## Build a CA (Certificate Authority)
truststore-build-cert: check-warn ## Build a certificate
@./scripts/truststore.sh build-cert "$(CA_NAME)" "$(CERT_NAME)" "$(CERT_SUBJECT)"

truststore-pull-all-for-account: check-warn ## Pull all certificates for each environment in a given account
@./scripts/truststore.sh pull-all-for-account "$(ACCOUNT)"

truststore-pull-all: check-warn ## Pull all certificates
@./scripts/truststore.sh pull-all "$(ENV)"

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ As a short guideline about profiles to assume for a typical workflow:
### Set up NRLF certificates

In order to execute make commands that need AWS access, you will need to pull the NRLF certificates.
In order to do this, make sure you have AWS CLI installed and configured, then run:
In order to do this, make sure you have AWS CLI installed and configured, assume the mgmt account, then run:

```
make ENV=env truststore-pull-all
Expand Down
28 changes: 28 additions & 0 deletions scripts/get-envs-for-account.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
# Get the names of all environments in a provided NRL AWS account
set -o errexit -o nounset -o pipefail

if [[ $# -ne 1 ]]; then
echo "Usage: get-envs-for-account.sh <account>"
exit 1
fi

account="$1"

case "${account}" in
dev)
envs_array=("dev" "dev-sandbox")
echo ${envs_array[@]}
;;
test)
envs_array=("qa" "perftest" "ref" "int" "int-sandbox") # "qa-sandbox" currently broken
echo ${envs_array[@]}
;;
prod)
envs_array=("prod")
echo ${envs_array[@]}
;;
*)
echo "Unknown account ${account}"
exit 1
esac
21 changes: 21 additions & 0 deletions scripts/truststore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ function _truststore_pull_server() {

function _truststore_pull_all() {
env=$1

_truststore_pull_ca $env
_truststore_pull_client $env
_truststore_pull_server $env
Expand All @@ -311,6 +312,25 @@ function _truststore_pull_all() {
return 0
}

function _truststore_pull_all_for_account() {
account=$1

# sets envs_array
source ./scripts/get-envs-for-account.sh $account

echo "Pulling certs for environments ${envs_array[@]} in ${account} account"

for env in ${envs_array[@]}; do
echo "⏳ Pulling ${env} truststore certs"
_truststore_pull_ca $env
_truststore_pull_client $env
_truststore_pull_server $env
done

echo -e "✅ Successfully pulled all ${account} truststore files from s3://${BUCKET}"
return 0
}

function _truststore_push_all() {
env=$1

Expand Down Expand Up @@ -364,6 +384,7 @@ function _truststore() {
"build-ca") _truststore_build_ca $args ;;
"build-cert") _truststore_build_cert $args ;;
"pull-all") _truststore_pull_all $args ;;
"pull-all-for-account") _truststore_pull_all_for_account $args ;;
"pull-server") _truststore_pull_server $args ;;
"pull-client") _truststore_pull_client $args ;;
"pull-ca") _truststore_pull_ca $args ;;
Expand Down
4 changes: 2 additions & 2 deletions terraform/account-wide-infrastructure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Each subdirectory corresponds to each AWS account (`mgmt`, `prod`, `test` and `d
Before deploying the NRLF account-wide infrastructure, you will need:

- AWS accounts that have already been bootstrapped, as described in [bootstrap/README.md](../bootstrap/README.md). This is a one-time account setup step.
- The required packages to build NRLF, see [the Setup section in README.md](../../README.md#setup).
- The required packages to build NRLF, see [the Setup section in README.md](../../README.md#before-you-begin).

## Deploy mgmt resources

Expand All @@ -45,7 +45,7 @@ terraform apply

### If you get "Error: creating CodeBuild Webhook"

If you see this erro:
If you see this error:

```
│ Error: creating CodeBuild Webhook (nhsd-nrlf-ci-build-project): operation error CodeBuild: CreateWebhook, https response error StatusCode: 400, RequestID: , ResourceNotFoundException: Access token not found in CodeBuild project for server type github
Expand Down
7 changes: 7 additions & 0 deletions terraform/account-wide-infrastructure/dev/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ data "aws_secretsmanager_secret" "emails" {
data "aws_secretsmanager_secret_version" "emails" {
secret_id = data.aws_secretsmanager_secret.emails.id
}

data "external" "current-info" {
program = [
"bash",
"../../../scripts/get-current-info.sh",
]
}
4 changes: 4 additions & 0 deletions terraform/account-wide-infrastructure/dev/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ output "athena_kms_key_arn" {
description = "KMS key ARN for Athena encryption"
value = var.enable_reporting ? module.dev-athena[0].kms_key_arn : null
}

output "version" {
value = data.external.current-info.result.version
}
7 changes: 7 additions & 0 deletions terraform/account-wide-infrastructure/prod/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ data "aws_secretsmanager_secret_version" "emails" {
data "aws_secretsmanager_secret_version" "backup_destination_parameters" {
secret_id = aws_secretsmanager_secret.backup_destination_parameters.name
}

data "external" "current-info" {
program = [
"bash",
"../../../scripts/get-current-info.sh",
]
}
4 changes: 4 additions & 0 deletions terraform/account-wide-infrastructure/prod/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ output "athena_kms_key_arn" {
description = "KMS key ARN for Athena encryption"
value = var.enable_reporting ? module.prod-athena[0].kms_key_arn : null
}

output "version" {
value = data.external.current-info.result.version
}
7 changes: 7 additions & 0 deletions terraform/account-wide-infrastructure/test/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ data "aws_secretsmanager_secret_version" "emails" {
data "aws_secretsmanager_secret_version" "backup_destination_parameters" {
secret_id = aws_secretsmanager_secret.backup_destination_parameters.name
}

data "external" "current-info" {
program = [
"bash",
"../../../scripts/get-current-info.sh",
]
}
4 changes: 4 additions & 0 deletions terraform/account-wide-infrastructure/test/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ output "athena_kms_key_arn" {
description = "KMS key ARN for Athena encryption"
value = var.enable_reporting ? module.test-athena[0].kms_key_arn : null
}

output "version" {
value = data.external.current-info.result.version
}
2 changes: 1 addition & 1 deletion terraform/bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The setup creates AWS resources to enable terraform deployments to AWS accounts.
Before you begin deploying NRLF bootstrap components, you will need:

- Four AWS accounts created. These will be assigned as: mgmt, prod, test and dev
- The required packages to build NRLF, see [the Setup section in README.md](../../README.md#setup).
- The required packages to build NRLF, see [the Setup section in README.md](../../README.md#before-you-begin).

## Bootstrapping the environments

Expand Down
2 changes: 1 addition & 1 deletion terraform/infrastructure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ CI pipeline creates infrastructure in the dev AWS account. These will have works
Before you begin deploying NRLF infrastructure, you will need:

- An NRLF-enabled AWS account, ideally `dev`. See [bootstrap](../bootstrap/README.md) for details on setting up a new account.
- The required packages to build NRLF, see [the Setup section in README.md](../../README.md#setup).
- The required packages to build NRLF, see [the Setup section in README.md](../../README.md#before-you-begin).
- To be logged into the AWS mgmt account on the CLI that you are deploying from.

If infrastructure changes require account wide AWS resources. Please deploy the corresponding [NRLF account wide infrastructure](../account-wide-infrastructure/README.md) first.
Expand Down