Skip to content

Commit 284e8f9

Browse files
committed
rename & tidy
1 parent 27e6987 commit 284e8f9

File tree

9 files changed

+274
-32
lines changed

9 files changed

+274
-32
lines changed

infra/environments/int/variables.tfvars

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ dspp_admin_role = "root"
77
environment = "int"
88
parent_route53_zone_name = "int.vds.platform.nhs.uk"
99
child_route53_zone_name = "imms.int.vds.platform.nhs.uk"
10+
mesh_mailbox_id = "X26OT303"
11+
mesh_dlq_mailbox_id = "X26OT304"

infra/environments/non-prod/variables.tfvars

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ dspp_admin_role = "root"
77
environment = "dev"
88
parent_route53_zone_name = "dev.vds.platform.nhs.uk"
99
child_route53_zone_name = "imms.dev.vds.platform.nhs.uk"
10+
mesh_mailbox_id = null
11+
mesh_dlq_mailbox_id = null

infra/environments/prod/variables.tfvars

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ dspp_admin_role = "root"
77
environment = "prod"
88
parent_route53_zone_name = "prod.vds.platform.nhs.uk"
99
child_route53_zone_name = "imms.prod.vds.platform.nhs.uk"
10+
mesh_mailbox_id = "X26HC138"
11+
mesh_dlq_mailbox_id = null

infra/mesh.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module "mesh" {
2+
source = "git::https://github.com/nhsdigital/terraform-aws-mesh-client.git//module?ref=v2.1.5"
3+
4+
name_prefix = "local-immunisation"
5+
mesh_env = "integration"
6+
subnet_ids = data.aws_subnets.default.ids
7+
8+
# TODO single or many mailbox ids
9+
mailbox_ids = [var.mesh_mailbox_id]
10+
dlq_mailbox_id = var.mesh_dlq_mailbox_id
11+
verify_ssl = "true"
12+
get_message_max_concurrency = 10
13+
compress_threshold = 1 * 1024 * 1024
14+
handshake_schedule = "rate(24 hours)"
15+
16+
account_id = local.immunisation_account_id
17+
# TODO these bucket names need attention - enviroment specific names to avoid conflicts
18+
mesh_bucket_name = "imms-${var.environment}-mesh-data-sources"
19+
mesh_logs_bucket_name = "imms-${var.environment}-mesh-s3logs"
20+
}

infra/mesh_processor.tf

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
# Only create MESH processor resources if MESH is configured for this environment
2+
locals {
3+
create_mesh_processor = var.mesh_mailbox_id != null
4+
}
5+
6+
# Define the directory containing the Docker image and calculate its SHA-256 hash for triggering redeployments
7+
locals {
8+
mesh_processor_lambda_dir = abspath("${path.root}/../mesh_processor")
9+
mesh_processor_lambda_files = fileset(local.mesh_processor_lambda_dir, "**")
10+
mesh_processor_lambda_dir_sha = sha1(join("", [for f in local.mesh_processor_lambda_files : filesha1("${local.mesh_processor_lambda_dir}/${f}")]))
11+
mesh_s3_bucket_name = local.create_mesh_processor ? module.mesh[0].mesh_bucket_name : null
12+
mesh_s3_logs_bucket_name = local.create_mesh_processor ? module.mesh[0].mesh_logs_bucket_name : null
13+
mesh_processor_name = "imms-${var.environment}-mesh-processor"
14+
mesh_processor_lambda_name = "${local.mesh_processor_name}-lambda"
15+
}
16+
17+
resource "aws_ecr_repository" "mesh_file_converter_lambda_repository" {
18+
count = local.create_mesh_processor ? 1 : 0
19+
20+
image_scanning_configuration {
21+
scan_on_push = true
22+
}
23+
name = "${local.mesh_processor_name}-repo"
24+
force_delete = false
25+
}
26+
27+
# Module for building and pushing Docker image to ECR
28+
module "mesh_processor_docker_image" {
29+
count = local.create_mesh_processor ? 1 : 0
30+
source = "terraform-aws-modules/lambda/aws//modules/docker-build"
31+
version = "8.0.1"
32+
33+
create_ecr_repo = false
34+
ecr_repo = aws_ecr_repository.mesh_file_converter_lambda_repository[0].name
35+
ecr_repo_lifecycle_policy = jsonencode({
36+
"rules" : [
37+
{
38+
"rulePriority" : 1,
39+
"description" : "Keep only the last 2 images",
40+
"selection" : {
41+
"tagStatus" : "any",
42+
"countType" : "imageCountMoreThan",
43+
"countNumber" : 2
44+
},
45+
"action" : {
46+
"type" : "expire"
47+
}
48+
}
49+
]
50+
})
51+
52+
platform = "linux/amd64"
53+
use_image_tag = false
54+
source_path = local.mesh_processor_lambda_dir
55+
triggers = {
56+
dir_sha = local.mesh_processor_lambda_dir_sha
57+
}
58+
}
59+
60+
# Define the lambdaECRImageRetreival policy
61+
resource "aws_ecr_repository_policy" "mesh_processor_lambda_ECRImageRetreival_policy" {
62+
count = local.create_mesh_processor ? 1 : 0
63+
repository = aws_ecr_repository.mesh_file_converter_lambda_repository[0].name
64+
65+
policy = jsonencode({
66+
Version = "2012-10-17"
67+
Statement = [
68+
{
69+
"Sid" : "LambdaECRImageRetrievalPolicy",
70+
"Effect" : "Allow",
71+
"Principal" : {
72+
"Service" : "lambda.amazonaws.com"
73+
},
74+
"Action" : [
75+
"ecr:BatchGetImage",
76+
"ecr:DeleteRepositoryPolicy",
77+
"ecr:GetDownloadUrlForLayer",
78+
"ecr:GetRepositoryPolicy",
79+
"ecr:SetRepositoryPolicy"
80+
],
81+
"Condition" : {
82+
"StringLike" : {
83+
"aws:sourceArn" : "arn:aws:lambda:eu-west-2:${var.imms_account_id}:function:${local.mesh_processor_lambda_name}"
84+
}
85+
}
86+
}
87+
]
88+
})
89+
}
90+
91+
# IAM Role for Lambda
92+
resource "aws_iam_role" "mesh_processor_lambda_exec_role" {
93+
count = local.create_mesh_processor ? 1 : 0
94+
name = "${local.mesh_processor_lambda_name}-exec-role"
95+
assume_role_policy = jsonencode({
96+
Version = "2012-10-17",
97+
Statement = [{
98+
Effect = "Allow",
99+
Sid = "",
100+
Principal = {
101+
Service = "lambda.amazonaws.com"
102+
},
103+
Action = "sts:AssumeRole"
104+
}]
105+
})
106+
}
107+
108+
# Policy for Lambda execution role
109+
resource "aws_iam_policy" "mesh_processor_lambda_exec_policy" {
110+
count = local.create_mesh_processor ? 1 : 0
111+
name = "imms-${var.environment}-mesh_processor-lambda-exec-policy"
112+
policy = jsonencode({
113+
Version = "2012-10-17",
114+
Statement = [
115+
{
116+
Effect = "Allow"
117+
Action = [
118+
"logs:CreateLogGroup",
119+
"logs:CreateLogStream",
120+
"logs:PutLogEvents"
121+
]
122+
Resource = "arn:aws:logs:${var.aws_region}:${var.imms_account_id}:log-group:/aws/lambda/${local.mesh_processor_lambda_name}:*"
123+
},
124+
{
125+
Effect = "Allow"
126+
Action = [
127+
"s3:GetObject",
128+
"s3:ListBucket",
129+
"s3:PutObject",
130+
"s3:CopyObject"
131+
]
132+
Resource = [
133+
aws_s3_bucket.batch_data_source_bucket.arn,
134+
"${aws_s3_bucket.batch_data_source_bucket.arn}/*"
135+
]
136+
},
137+
{
138+
Effect = "Allow"
139+
Action = [
140+
"s3:GetObject",
141+
"s3:ListBucket",
142+
"s3:PutObject",
143+
"s3:CopyObject",
144+
"s3:DeleteObject"
145+
]
146+
Resource = [
147+
"arn:aws:s3:::${local.mesh_s3_bucket_name}",
148+
"arn:aws:s3:::${local.mesh_s3_bucket_name}/*",
149+
"arn:aws:s3:::${local.mesh_s3_logs_bucket_name}/*",
150+
"arn:aws:s3:::local-immunisation-mesh",
151+
"arn:aws:s3:::local-immunisation-mesh/*",
152+
"arn:aws:s3:::local-immunisation-mesh-s3logs/*"
153+
]
154+
}
155+
]
156+
})
157+
}
158+
159+
resource "aws_iam_policy" "mesh_processor_lambda_kms_access_policy" {
160+
count = local.create_mesh_processor ? 1 : 0
161+
name = "${aws_lambda_function.mesh_file_converter_lambda[0].function_name}-kms-policy"
162+
description = "Allow Lambda to decrypt environment variables"
163+
164+
policy = jsonencode({
165+
Version = "2012-10-17"
166+
Statement = [
167+
{
168+
Effect = "Allow"
169+
Action = [
170+
"kms:Encrypt",
171+
"kms:Decrypt",
172+
"kms:GenerateDataKey*"
173+
]
174+
Resource = [
175+
data.aws_kms_key.mesh_s3_encryption_key.arn
176+
]
177+
}
178+
]
179+
})
180+
}
181+
182+
# Attach the execution policy to the Lambda role
183+
resource "aws_iam_role_policy_attachment" "mesh_processor_lambda_exec_policy_attachment" {
184+
count = local.create_mesh_processor ? 1 : 0
185+
role = aws_iam_role.mesh_processor_lambda_exec_role[0].name
186+
policy_arn = aws_iam_policy.mesh_processor_lambda_exec_policy[0].arn
187+
}
188+
189+
# Attach the kms policy to the Lambda role
190+
resource "aws_iam_role_policy_attachment" "mesh_processor_lambda_kms_policy_attachment" {
191+
count = local.create_mesh_processor ? 1 : 0
192+
role = aws_iam_role.mesh_processor_lambda_exec_role[0].name
193+
policy_arn = aws_iam_policy.mesh_processor_lambda_kms_access_policy[0].arn
194+
}
195+
196+
# Lambda Function with Security Group and VPC.
197+
resource "aws_lambda_function" "mesh_file_converter_lambda" {
198+
count = local.create_mesh_processor ? 1 : 0
199+
function_name = "${local.mesh_processor_name}_lambda"
200+
role = aws_iam_role.mesh_processor_lambda_exec_role[0].arn
201+
package_type = "Image"
202+
image_uri = module.mesh_processor_docker_image[0].image_uri
203+
architectures = ["x86_64"]
204+
timeout = 360
205+
206+
environment {
207+
variables = {
208+
Destination_BUCKET_NAME = aws_s3_bucket.batch_data_source_bucket.bucket
209+
MESH_FILE_PROC_LAMBDA_NAME = "${local.mesh_processor_lambda_name}"
210+
}
211+
}
212+
}
213+
214+
# Permission for S3 to invoke Lambda function
215+
resource "aws_lambda_permission" "mesh_s3_invoke_permission" {
216+
count = local.create_mesh_processor ? 1 : 0
217+
statement_id = "AllowExecutionFromS3"
218+
action = "lambda:InvokeFunction"
219+
function_name = aws_lambda_function.mesh_file_converter_lambda[0].function_name
220+
principal = "s3.amazonaws.com"
221+
source_arn = "arn:aws:s3:::${local.mesh_s3_bucket_name}"
222+
}
223+
224+
# S3 Bucket notification to trigger Lambda function
225+
resource "aws_s3_bucket_notification" "mesh_datasources_lambda_notification" {
226+
count = local.create_mesh_processor ? 1 : 0
227+
bucket = local.mesh_s3_bucket_name
228+
229+
lambda_function {
230+
lambda_function_arn = aws_lambda_function.mesh_file_converter_lambda[0].arn
231+
events = ["s3:ObjectCreated:*"]
232+
}
233+
234+
depends_on = [aws_lambda_permission.mesh_s3_invoke_permission]
235+
}
236+
237+
resource "aws_cloudwatch_log_group" "mesh_file_converter_log_group" {
238+
count = local.create_mesh_processor ? 1 : 0
239+
name = "/aws/lambda/${aws_lambda_function.mesh_file_converter_lambda[0].function_name}"
240+
retention_in_days = 30
241+
}

infra/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ variable "build_agent_account_id" {
1616
variable "environment" {
1717
default = "non-prod"
1818
}
19+
variable "mesh_mailbox_id" {
20+
default = null
21+
}
22+
variable "mesh_dlq_mailbox_id" {
23+
default = null
24+
}

terraform/configs.tf

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,5 @@ locals {
33
is_temp = length(regexall("[a-z]{2,4}-?[0-9]+", local.env)) > 0
44
dspp_core_account_id = local.environment == "prod" ? 232116723729 : 603871901111
55
immunisation_account_id = local.environment == "prod" ? 664418956997 : 345594581768
6-
7-
// MESH Mailbox IDs by environment
8-
prod_mesh_mailbox_id = "X26HC138"
9-
prod_mesh_dlq_mailbox_id = null
10-
int_mesh_mailbox_id = "X26OT303"
11-
int_mesh_dlq_mailbox_id = "X26OT304"
12-
13-
// Environment-specific MESH configuration
14-
// Note: Prod and int names are hardcoded, dev is variable
15-
mesh_mailbox_id = local.environment == "prod" ? local.prod_mesh_mailbox_id : (
16-
local.environment == "int" ? local.int_mesh_mailbox_id : var.dev_mesh_mailbox_id
17-
)
18-
19-
// DLQ Mailbox for int only - Not currently implemented TODO
20-
mesh_dlq_mailbox_id = local.environment == "prod" ? local.prod_mesh_dlq_mailbox_id : (
21-
local.environment == "int" ? local.int_mesh_dlq_mailbox_id :
22-
var.dev_mesh_dlq_mailbox_id
23-
)
246

25-
// MESH enabled if mailbox ID not null
26-
is_mesh_enabled = local.mesh_mailbox_id != null
277
}

terraform/mesh_processor.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Only create MESH processor resources if MESH is configured for this environment
22
locals {
3-
create_mesh_processor = local.is_mesh_enabled
3+
create_mesh_processor = var.me
44
}
55

66
# Define the directory containing the Docker image and calculate its SHA-256 hash for triggering redeployments

terraform/variables.tf

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,3 @@ data "aws_kms_key" "mesh_s3_encryption_key" {
9898
key_id = "alias/local-immunisation-mesh"
9999
}
100100

101-
variable "dev_mesh_mailbox_id" {
102-
description = "MESH mailbox ID for dev environment. If null, MESH is disabled. If set, MESH is enabled."
103-
type = string
104-
default = null
105-
}
106-
# Dev DLQ only used if dev mesh mailbox is set
107-
variable "dev_mesh_dlq_mailbox_id" {
108-
description = "MESH DLQ mailbox ID for dev environment. If null, MESH is disabled. If set, MESH is enabled."
109-
type = string
110-
default = null
111-
}

0 commit comments

Comments
 (0)