Skip to content

Commit a4a9fd8

Browse files
committed
[NRL-853] Move backup infrastructure TF state into S3 and add README. Fixup account bootstrap script to work on non-mgmt accounts
1 parent e18d117 commit a4a9fd8

File tree

6 files changed

+149
-31
lines changed

6 files changed

+149
-31
lines changed

scripts/bootstrap.sh

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/bin/bash
2+
# Setup mgmt and non-mgmt AWS accounts for NRLF
3+
set -o errexit -o nounset -o pipefail
24

35
AWS_REGION_NAME="eu-west-2"
46
PROFILE_PREFIX="nhsd-nrlf"
@@ -32,18 +34,12 @@ function _check_mgmt() {
3234
}
3335

3436
function _check_non_mgmt() {
35-
if [[ "$(aws iam list-account-aliases --query 'AccountAliases[0]' --output text)" != 'nhsd-ddc-spine-nrlf-mgmt' ]]; then
37+
if [[ "$(aws iam list-account-aliases --query 'AccountAliases[0]' --output text)" == 'nhsd-ddc-spine-nrlf-mgmt' ]]; then
3638
echo "Please log in as a non-mgmt account" >&2
3739
return 1
3840
fi
3941
}
4042

41-
function _get_mgmt_account(){
42-
if ! _check_mgmt; then return 1; fi
43-
return $(aws sts get-caller-identity --query Account --output text)
44-
}
45-
46-
4743
function _bootstrap() {
4844
local command=$1
4945
local admin_policy_arn="arn:aws:iam::aws:policy/AdministratorAccess"
@@ -55,7 +51,7 @@ function _bootstrap() {
5551
"create-mgmt")
5652
_check_mgmt || return 1
5753

58-
cd $root/terraform/bootstrap/mgmt
54+
cd terraform/bootstrap/mgmt
5955
aws s3api create-bucket --bucket "${truststore_bucket_name}" --region us-east-1 --create-bucket-configuration LocationConstraint="${AWS_REGION_NAME}"
6056
aws s3api create-bucket --bucket "${state_bucket_name}" --region us-east-1 --create-bucket-configuration LocationConstraint="${AWS_REGION_NAME}"
6157
aws s3api put-public-access-block --bucket "${state_bucket_name}" --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
@@ -69,7 +65,7 @@ function _bootstrap() {
6965
"delete-mgmt")
7066
_check_mgmt || return 1
7167

72-
cd $root/terraform/bootstrap/mgmt
68+
cd terraform/bootstrap/mgmt
7369
aws dynamodb delete-table --table-name "${state_lock_table_name}" || return 1
7470
local versioned_objects
7571
versioned_objects=$(aws s3api list-object-versions \
@@ -90,10 +86,20 @@ function _bootstrap() {
9086
"create-non-mgmt")
9187
_check_non_mgmt || return 1
9288

93-
cd $root/terraform/bootstrap/non-mgmt
89+
cd terraform/bootstrap/non-mgmt
9490
local tf_assume_role_policy
9591
local mgmt_account_id
96-
mgmt_account_id=$(_get_mgmt_account)
92+
93+
set +e
94+
mgmt_account_id=$(aws secretsmanager get-secret-value --secret-id "${MGMT_ACCOUNT_ID_LOCATION}" --query SecretString --output text)
95+
96+
if [ "${mgmt_account_id}" == "" ]; then
97+
aws secretsmanager create-secret --name "${MGMT_ACCOUNT_ID_LOCATION}"
98+
echo "Please set ${MGMT_ACCOUNT_ID_LOCATION} in the Secrets Manager and rerun the script"
99+
exit 1
100+
fi
101+
set -e
102+
97103
tf_assume_role_policy=$(awk "{sub(/REPLACEME/,\"${mgmt_account_id}\")}1" terraform-trust-policy.json)
98104
aws iam create-role --role-name "${TERRAFORM_ROLE_NAME}" --assume-role-policy-document "${tf_assume_role_policy}" || return 1
99105
aws iam attach-role-policy --policy-arn "${admin_policy_arn}" --role-name "${TERRAFORM_ROLE_NAME}" || return 1
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# NRLF Backup Infrastructure
2+
3+
This directory contains AWS backup terraform resources which are global to a given account.
4+
5+
Each subdirectory corresponds to each AWS account (`prod` and `test`).
6+
7+
**Backup infrastructure should be deployed manually and not be run as part of CI.**
8+
9+
## Table of Contents
10+
11+
1. [Prerequisites](#prerequisites)
12+
2. [Initialise shell environment](#initialise-shell-environment)
13+
3. [Deploy backup resources](#deploy-backup-resources)
14+
4. [Tear down backup resources](#tear-down-backup-resources)
15+
16+
## Prerequisites
17+
18+
Before deploying the NRLF backup infrastructure, you will need:
19+
20+
- An AWS backup account that have already been bootstrapped, as described in [bootstrap/README.md](../bootstrap/README.md). This is a one-time account setup step.
21+
22+
## Deploy backup resources
23+
24+
To deploy the backup resources, first login to the AWS mgmt account on the CLI.
25+
26+
Then, initialise the terraform backup workspace. For the test account:
27+
28+
```shell
29+
$ cd test
30+
$ terraform init && ( \
31+
terraform workspace new backup-infra-test || \
32+
terraform workspace select backup-infra-test )
33+
```
34+
35+
If you want to apply changes to prod, use the `prod` directory and the `backup-infra-prod` terraform workspace.
36+
37+
Once you have your workspace set, you can plan your changes with:
38+
39+
```shell
40+
$ terraform plan \
41+
-var 'source_account_id=SOURCE_ACCOUNT_ID" \
42+
-var 'assume_account=AWS_ACCOUNT_ID' \
43+
-var 'assume_role=terraform'
44+
```
45+
46+
Replacing SOURCE_ACCOUNT with the account id that will be sending backups to the backup account and AWS_ACCOUNT_ID with the AWS account id of your backup account.
47+
48+
Once you're happy with your planned changes, you can apply them with:
49+
50+
```shell
51+
$ terraform apply \
52+
-var 'source_account_id=SOURCE_ACCOUNT_ID" \
53+
-var 'assume_account=AWS_ACCOUNT_ID' \
54+
-var 'assume_role=terraform'
55+
```
56+
57+
Replacing SOURCE_ACCOUNT with the account id that will be sending backups to the backup account and AWS_ACCOUNT_ID with the AWS account id of your backup account.
58+
59+
## Tear down backup resources
60+
61+
WARNING - This action will destroy all backup resources from the AWS account. This should
62+
only be done if you are sure that this is safe and are sure that you are signed into the correct
63+
AWS account.
64+
65+
To tear down backup resources, first login to the AWS mgmt account on the CLI.
66+
67+
Then, initialise your terraform workspace. For the test account:
68+
69+
```shell
70+
$ cd test
71+
$ terraform init && ( \
72+
terraform workspace new backup-infra-test || \
73+
terraform workspace select backup-infra-test )
74+
```
75+
76+
If you want to destroy resources in prod, use the `prod` directory and the `backup-infra-prod` terraform workspace.
77+
78+
And then, to tear down:
79+
80+
```shell
81+
$ terraform destroy \
82+
-var 'source_account_id=SOURCE_ACCOUNT_ID" \
83+
-var 'assume_account=AWS_ACCOUNT_ID' \
84+
-var 'assume_role=terraform'
85+
```
86+
87+
Replacing SOURCE_ACCOUNT with the account id that will be sending backups to the backup account and AWS_ACCOUNT_ID with the AWS account id of your backup account.
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
data "aws_arn" "source_terraform_role" {
2-
arn = var.source_terraform_role_arn
3-
}
4-
51
data "aws_caller_identity" "current" {}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
locals {
22
# Adjust these as required
33
project_name = "nrlf-test-backup"
4-
environment_name = "dev"
4+
environment_name = "test"
55

6-
source_account_id = data.aws_arn.source_terraform_role.account
7-
destination_account_id = data.aws_caller_identity.current.account_id
6+
source_account_id = var.source_account_id
7+
destination_account_id = var.assume_account
88
}
Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1-
#terraform {
2-
# backend "s3" {
3-
# bucket = "project-env-backup-tf-bucket" # change this to the destination account terraform state s3 bucket name
4-
# key = "project-env-backup.tfstate" # change this to the destination account terraform state s3 key name
5-
# dynamodb_table = "project-env-backup-lock-table" # change this to the destination account terraform state dynamodb table name
6-
# region = "eu-west-2"
7-
# }
8-
#}
9-
10-
111
provider "aws" {
12-
alias = "source"
132
region = "eu-west-2"
3+
4+
assume_role {
5+
role_arn = "arn:aws:iam::${var.assume_account}:role/${var.assume_role}"
6+
}
7+
8+
default_tags {
9+
tags = {
10+
project_name = local.project_name
11+
workspace = terraform.workspace
12+
}
13+
}
14+
}
15+
16+
terraform {
17+
required_providers {
18+
aws = {
19+
source = "hashicorp/aws"
20+
version = "~> 5.76.0"
21+
}
22+
}
23+
24+
backend "s3" {
25+
region = "eu-west-2"
26+
bucket = "nhsd-nrlf--terraform-state"
27+
dynamodb_table = "nhsd-nrlf--terraform-state-lock"
28+
key = "terraform-state-dev-backup-infrastructure"
29+
workspace_key_prefix = "nhsd-nrlf"
30+
encrypt = false
31+
}
1432
}
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
variable "source_terraform_role_arn" {
2-
description = "ARN of the terraform role in the source account"
1+
variable "assume_account" {
2+
description = "The account id to deploy the infrastructure to"
3+
sensitive = true
4+
}
5+
6+
variable "assume_role" {
7+
description = "Name of the role to assume to deploy the infrastructure"
8+
type = string
9+
}
10+
11+
variable "source_account_id" {
12+
description = "The account id of the backup source account"
313
type = string
14+
sensitive = true
415
}

0 commit comments

Comments
 (0)