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
28 changes: 17 additions & 11 deletions scripts/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/bash
# Setup mgmt and non-mgmt AWS accounts for NRLF
set -o errexit -o nounset -o pipefail

AWS_REGION_NAME="eu-west-2"
PROFILE_PREFIX="nhsd-nrlf"
Expand Down Expand Up @@ -32,18 +34,12 @@ function _check_mgmt() {
}

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

function _get_mgmt_account(){
if ! _check_mgmt; then return 1; fi
return $(aws sts get-caller-identity --query Account --output text)
}


function _bootstrap() {
local command=$1
local admin_policy_arn="arn:aws:iam::aws:policy/AdministratorAccess"
Expand All @@ -55,7 +51,7 @@ function _bootstrap() {
"create-mgmt")
_check_mgmt || return 1

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

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

cd $root/terraform/bootstrap/non-mgmt
cd terraform/bootstrap/non-mgmt
local tf_assume_role_policy
local mgmt_account_id
mgmt_account_id=$(_get_mgmt_account)

set +e
mgmt_account_id=$(aws secretsmanager get-secret-value --secret-id "${MGMT_ACCOUNT_ID_LOCATION}" --query SecretString --output text)

if [ "${mgmt_account_id}" == "" ]; then
aws secretsmanager create-secret --name "${MGMT_ACCOUNT_ID_LOCATION}"
echo "Please set ${MGMT_ACCOUNT_ID_LOCATION} in the Secrets Manager and rerun the script"
exit 1
fi
set -e

tf_assume_role_policy=$(awk "{sub(/REPLACEME/,\"${mgmt_account_id}\")}1" terraform-trust-policy.json)
aws iam create-role --role-name "${TERRAFORM_ROLE_NAME}" --assume-role-policy-document "${tf_assume_role_policy}" || return 1
aws iam attach-role-policy --policy-arn "${admin_policy_arn}" --role-name "${TERRAFORM_ROLE_NAME}" || return 1
Expand Down
158 changes: 158 additions & 0 deletions terraform/account-wide-infrastructure/dev/aws-backup.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@

# First, we create an S3 bucket for compliance reports.
resource "aws_s3_bucket" "backup_reports" {
bucket_prefix = "${local.prefix}-backup-reports"
}

resource "aws_s3_bucket_public_access_block" "backup_reports" {
bucket = aws_s3_bucket.backup_reports.id

block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}

resource "aws_s3_bucket_server_side_encryption_configuration" "backup_reports" {
bucket = aws_s3_bucket.backup_reports.bucket

rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}

resource "aws_s3_bucket_policy" "backup_reports_bucket_policy" {
bucket = aws_s3_bucket.backup_reports.id

policy = jsonencode({
Version = "2012-10-17"
Id = "backup_reports_bucket_policy"
Statement = [
{
Sid = "HTTPSOnly"
Effect = "Deny"
Principal = "*"
Action = "s3:*"
Resource = [
aws_s3_bucket.backup_reports.arn,
"${aws_s3_bucket.backup_reports.arn}/*",
]
Condition = {
Bool = {
"aws:SecureTransport" = "false"
}
}
},
]
})
}


resource "aws_s3_bucket_ownership_controls" "backup_reports" {
bucket = aws_s3_bucket.backup_reports.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}

resource "aws_s3_bucket_acl" "backup_reports" {
depends_on = [aws_s3_bucket_ownership_controls.backup_reports]

bucket = aws_s3_bucket.backup_reports.id
acl = "private"
}

# We need a key for the SNS topic that will be used for notifications from AWS Backup. This key
# will be used to encrypt the messages sent to the topic before they are sent to the subscribers,
# but isn't needed by the recipients of the messages.

# First we need some contextual data
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

# Now we can define the key itself
resource "aws_kms_key" "backup_notifications" {
description = "KMS key for AWS Backup notifications"
deletion_window_in_days = 7
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Sid = "Enable IAM User Permissions"
Principal = {
AWS = "arn:aws:iam::${var.assume_account}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Effect = "Allow"
Principal = {
Service = "sns.amazonaws.com"
}
Action = ["kms:GenerateDataKey*", "kms:Decrypt"]
Resource = "*"
},
]
})
}

# Now we can deploy the source and destination modules, referencing the resources we've created above.

module "source" {
source = "../modules/backup-source"

backup_copy_vault_account_id = jsondecode(data.aws_secretsmanager_secret_version.backup_destination_parameters.secret_string)["account-id"]
backup_copy_vault_arn = jsondecode(data.aws_secretsmanager_secret_version.backup_destination_parameters.secret_string)["vault-arn"]
environment_name = local.environment
bootstrap_kms_key_arn = aws_kms_key.backup_notifications.arn
project_name = "${local.prefix}-"
reports_bucket = aws_s3_bucket.backup_reports.bucket
terraform_role_arn = "arn:aws:iam::${var.assume_account}:role/${var.assume_role}"

notification_target_email_addresses = local.notification_emails

backup_plan_config = {
"compliance_resource_types" : [
"S3"
],
"enable" = true,
"rules" : [
{
"copy_action" : {
"delete_after" : 4
},
"lifecycle" : {
"delete_after" : 2
},
"name" : "daily_kept_for_2_days",
"schedule" : "cron(0 0 * * ? *)"
}
],
"selection_tag" : "NHSE-Enable-S3-Backup"
}

backup_plan_config_dynamodb = {
"compliance_resource_types" : [
"DynamoDB"
],
"enable" : true,
"rules" : [
{
"copy_action" : {
"delete_after" : 4
},
"lifecycle" : {
"delete_after" : 2
},
"name" : "daily_kept_for_2_days",
"schedule" : "cron(0 0 * * ? *)"
}
],
"selection_tag" : "NHSE-Enable-DDB-Backup"
}
}
2 changes: 2 additions & 0 deletions terraform/account-wide-infrastructure/dev/cloudwatch.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module "lambda_errors_cloudwatch_metric_alarm_dev" {
source = "../modules/lambda-errors-metric-alarm"
name_prefix = "nhsd-nrlf--dev"

notification_emails = local.notification_emails

evaluation_periods = 1
period = 60
threshold = 1
Expand Down
12 changes: 12 additions & 0 deletions terraform/account-wide-infrastructure/dev/data.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
data "aws_secretsmanager_secret_version" "identities_account_id" {
secret_id = aws_secretsmanager_secret.identities_account_id.name
}

data "aws_secretsmanager_secret_version" "backup_destination_parameters" {
secret_id = aws_secretsmanager_secret.backup_destination_parameters.name
}

data "aws_secretsmanager_secret" "emails" {
name = "${local.prefix}-emails"
}

data "aws_secretsmanager_secret_version" "emails" {
secret_id = data.aws_secretsmanager_secret.emails.id
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module "dev-pointers-table" {
source = "../modules/pointers-table"
name_prefix = "nhsd-nrlf--dev"
source = "../modules/pointers-table"
name_prefix = "nhsd-nrlf--dev"
enable_backups = true
}

module "dev-sandbox-pointers-table" {
Expand Down
2 changes: 2 additions & 0 deletions terraform/account-wide-infrastructure/dev/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ locals {
project = "nhsd-nrlf"
environment = terraform.workspace
prefix = "${local.project}--${local.environment}"

notification_emails = nonsensitive(toset(tolist(jsondecode(data.aws_secretsmanager_secret_version.emails.secret_string))))
}
7 changes: 7 additions & 0 deletions terraform/account-wide-infrastructure/dev/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ provider "aws" {
workspace = terraform.workspace
}
}
}

provider "awscc" {
region = local.region

assume_role = {
role_arn = "arn:aws:iam::${var.assume_account}:role/${var.assume_role}"
}
}

terraform {
Expand Down
6 changes: 4 additions & 2 deletions terraform/account-wide-infrastructure/dev/s3.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module "dev-permissions-store-bucket" {
source = "../modules/permissions-store-bucket"
name_prefix = "nhsd-nrlf--dev"
source = "../modules/permissions-store-bucket"
name_prefix = "nhsd-nrlf--dev"
enable_backups = true
}

module "dev-sandbox-permissions-store-bucket" {
Expand All @@ -12,6 +13,7 @@ module "dev-truststore-bucket" {
source = "../modules/truststore-bucket"
name_prefix = "nhsd-nrlf--dev"
server_certificate_file = "../../../truststore/server/dev.pem"
enable_backups = true
}

module "dev-sandbox-truststore-bucket" {
Expand Down
9 changes: 9 additions & 0 deletions terraform/account-wide-infrastructure/dev/secrets.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ resource "aws_secretsmanager_secret" "identities_account_id" {
name = "${local.prefix}--nhs-identities-account-id"
}

resource "aws_secretsmanager_secret" "backup_destination_parameters" {
name = "${local.prefix}--backup-destination-parameters"
description = "Parameters used to configure the backup destination"
}

resource "aws_secretsmanager_secret" "notification_email_addresses" {
name = "${local.prefix}-dev-notification-email-addresses"
}

resource "aws_secretsmanager_secret" "dev_smoke_test_apigee_app" {
name = "${local.prefix}--dev--apigee-app--smoke-test"
description = "APIGEE App used to run Smoke Tests against the DEV environment"
Expand Down
Loading