Skip to content

Commit 9e6701c

Browse files
committed
[NRL-1158] Add test and prod aws-backup infra
1 parent 15e1880 commit 9e6701c

File tree

8 files changed

+397
-2
lines changed

8 files changed

+397
-2
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
2+
resource "aws_s3_bucket" "backup_reports" {
3+
bucket_prefix = "${local.prefix}-backup-reports"
4+
}
5+
6+
resource "aws_s3_bucket_public_access_block" "backup_reports" {
7+
bucket = aws_s3_bucket.backup_reports.id
8+
9+
block_public_acls = true
10+
block_public_policy = true
11+
ignore_public_acls = true
12+
restrict_public_buckets = true
13+
}
14+
15+
resource "aws_s3_bucket_server_side_encryption_configuration" "backup_reports" {
16+
bucket = aws_s3_bucket.backup_reports.bucket
17+
18+
rule {
19+
apply_server_side_encryption_by_default {
20+
sse_algorithm = "AES256"
21+
}
22+
}
23+
}
24+
25+
resource "aws_s3_bucket_policy" "backup_reports_bucket_policy" {
26+
bucket = aws_s3_bucket.backup_reports.id
27+
28+
policy = jsonencode({
29+
Version = "2012-10-17"
30+
Id = "backup_reports_bucket_policy"
31+
Statement = [
32+
{
33+
Sid = "HTTPSOnly"
34+
Effect = "Deny"
35+
Principal = "*"
36+
Action = "s3:*"
37+
Resource = [
38+
aws_s3_bucket.backup_reports.arn,
39+
"${aws_s3_bucket.backup_reports.arn}/*",
40+
]
41+
Condition = {
42+
Bool = {
43+
"aws:SecureTransport" = "false"
44+
}
45+
}
46+
},
47+
{
48+
Sid = "AllowBackupReportsWrite"
49+
Effect = "Allow"
50+
Principal = {
51+
AWS = "arn:aws:iam::${local.account_id}:role/aws-service-role/reports.backup.amazonaws.com/AWSServiceRoleForBackupReports"
52+
}
53+
Action = "s3:PutObject"
54+
Resource = [
55+
"${aws_s3_bucket.backup_reports.arn}/*",
56+
]
57+
Condition = {
58+
StringEquals = {
59+
"s3:x-amz-acl" = "bucket-owner-full-control"
60+
}
61+
}
62+
}
63+
]
64+
})
65+
}
66+
67+
68+
resource "aws_s3_bucket_ownership_controls" "backup_reports" {
69+
bucket = aws_s3_bucket.backup_reports.id
70+
rule {
71+
object_ownership = "BucketOwnerPreferred"
72+
}
73+
}
74+
75+
resource "aws_s3_bucket_acl" "backup_reports" {
76+
depends_on = [aws_s3_bucket_ownership_controls.backup_reports]
77+
78+
bucket = aws_s3_bucket.backup_reports.id
79+
acl = "private"
80+
}
81+
82+
resource "aws_kms_key" "backup_notifications" {
83+
description = "KMS key for AWS Backup notifications"
84+
deletion_window_in_days = 7
85+
enable_key_rotation = true
86+
policy = jsonencode({
87+
Version = "2012-10-17"
88+
Statement = [
89+
{
90+
Effect = "Allow"
91+
Sid = "Enable IAM User Permissions"
92+
Principal = {
93+
AWS = "arn:aws:iam::${var.assume_account}:root"
94+
}
95+
Action = "kms:*"
96+
Resource = "*"
97+
},
98+
{
99+
Effect = "Allow"
100+
Principal = {
101+
Service = "sns.amazonaws.com"
102+
}
103+
Action = ["kms:GenerateDataKey*", "kms:Decrypt"]
104+
Resource = "*"
105+
},
106+
]
107+
})
108+
}
109+
110+
module "source" {
111+
source = "../modules/backup-source"
112+
113+
backup_copy_vault_account_id = jsondecode(data.aws_secretsmanager_secret_version.backup_destination_parameters.secret_string)["account-id"]
114+
backup_copy_vault_arn = jsondecode(data.aws_secretsmanager_secret_version.backup_destination_parameters.secret_string)["vault-arn"]
115+
environment_name = local.environment
116+
bootstrap_kms_key_arn = aws_kms_key.backup_notifications.arn
117+
project_name = "${local.prefix}-"
118+
reports_bucket = aws_s3_bucket.backup_reports.bucket
119+
terraform_role_arn = "arn:aws:iam::${var.assume_account}:role/${var.assume_role}"
120+
121+
notification_target_email_addresses = local.notification_emails
122+
123+
backup_plan_config = {
124+
"compliance_resource_types" : [
125+
"S3"
126+
],
127+
"enable" : true,
128+
"rules" : [
129+
{
130+
"copy_action" : [{
131+
"delete_after" : 4,
132+
}],
133+
"lifecycle" : {
134+
"delete_after" : 2
135+
},
136+
"name" : "daily_kept_for_2_days",
137+
"schedule" : "cron(0 0 * * ? *)"
138+
}
139+
],
140+
"selection_tag" : "NHSE-Enable-S3-Backup"
141+
}
142+
143+
backup_plan_config_dynamodb = {
144+
"compliance_resource_types" : [
145+
"DynamoDB"
146+
],
147+
"enable" : true,
148+
"rules" : [
149+
{
150+
"name" : "daily",
151+
"schedule" : "cron(0 0 * * ? *)",
152+
"copy_action" : [{
153+
"delete_after" : 4,
154+
}],
155+
156+
"lifecycle" : {
157+
"delete_after" : 2
158+
}
159+
},
160+
{
161+
"name" : "monthly"
162+
"schedule" : "cron(30 0 ? * 4#1)" # first Thursday each month from 00:30
163+
"copy_action" : [{
164+
"cold_storage_after" : 3,
165+
"delete_after" : 100 # ensures there will always be min 3
166+
}],
167+
"lifecycle" : {
168+
"delete_after" : 2
169+
}
170+
171+
},
172+
{
173+
"name" : "weekly" # overlaps with monthly
174+
"schedule" : "cron(30 0 ? * 4)" # every Thursday from 00:30 to precede releases
175+
"copy_action" : [{
176+
"cold_storage_after" : 14 # ensures 2 warm including one from previous release
177+
"delete_after" : 105
178+
}],
179+
"lifecycle" : {
180+
"delete_after" : 2
181+
}
182+
183+
}
184+
],
185+
"selection_tag" : "NHSE-Enable-DDB-Backup"
186+
}
187+
}

terraform/account-wide-infrastructure/prod/data.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
data "aws_region" "current" {}
22

3+
data "aws_caller_identity" "current" {}
4+
35
data "aws_secretsmanager_secret_version" "identities_account_id" {
46
secret_id = aws_secretsmanager_secret.identities_account_id.name
57
}
@@ -11,3 +13,7 @@ data "aws_secretsmanager_secret" "emails" {
1113
data "aws_secretsmanager_secret_version" "emails" {
1214
secret_id = data.aws_secretsmanager_secret.emails.id
1315
}
16+
17+
data "aws_secretsmanager_secret_version" "backup_destination_parameters" {
18+
secret_id = aws_secretsmanager_secret.backup_destination_parameters.name
19+
}

terraform/account-wide-infrastructure/prod/locals.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ locals {
33
project = "nhsd-nrlf"
44
environment = terraform.workspace
55
prefix = "${local.project}--${local.environment}"
6+
account_id = data.aws_caller_identity.current.account_id
67

78
notification_emails = tolist(jsondecode(data.aws_secretsmanager_secret_version.emails.secret_string))
89
}

terraform/account-wide-infrastructure/prod/secrets.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ resource "aws_secretsmanager_secret" "powerbi_gw_recovery_key" {
3030
name = "${local.project}--prod-powerbi-gw-recovery-key"
3131
description = "Recovery key for the PowerBI Gateway EC2 instance"
3232
}
33+
34+
resource "aws_secretsmanager_secret" "backup_destination_parameters" {
35+
name = "${local.prefix}--backup-destination-parameters"
36+
description = "Parameters used to configure the backup destination"
37+
}

0 commit comments

Comments
 (0)