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+ }
0 commit comments