Skip to content

Commit 18c2fec

Browse files
committed
init: id_sync_lambda.tf
1 parent b2dabcc commit 18c2fec

File tree

1 file changed

+305
-0
lines changed

1 file changed

+305
-0
lines changed

terraform/id_sync_lambda.tf

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
# Define the directory containing the Docker image and calculate its SHA-256 hash for triggering redeployments
2+
locals {
3+
redis_sync_lambda_dir = abspath("${path.root}/../redis_sync")
4+
redis_sync_lambda_files = fileset(local.redis_sync_lambda_dir, "**")
5+
redis_sync_lambda_dir_sha = sha1(join("", [for f in local.redis_sync_lambda_files : filesha1("${local.redis_sync_lambda_dir}/${f}")]))
6+
}
7+
8+
resource "aws_ecr_repository" "redis_sync_lambda_repository" {
9+
image_scanning_configuration {
10+
scan_on_push = true
11+
}
12+
name = "${local.short_prefix}-redis-sync-repo"
13+
force_delete = local.is_temp
14+
}
15+
16+
# Module for building and pushing Docker image to ECR
17+
module "redis_sync_docker_image" {
18+
source = "terraform-aws-modules/lambda/aws//modules/docker-build"
19+
version = "8.0.1"
20+
21+
create_ecr_repo = false
22+
ecr_repo = aws_ecr_repository.redis_sync_lambda_repository.name
23+
ecr_repo_lifecycle_policy = jsonencode({
24+
"rules" : [
25+
{
26+
"rulePriority" : 1,
27+
"description" : "Keep only the last 2 images",
28+
"selection" : {
29+
"tagStatus" : "any",
30+
"countType" : "imageCountMoreThan",
31+
"countNumber" : 2
32+
},
33+
"action" : {
34+
"type" : "expire"
35+
}
36+
}
37+
]
38+
})
39+
40+
platform = "linux/amd64"
41+
use_image_tag = false
42+
source_path = local.redis_sync_lambda_dir
43+
triggers = {
44+
dir_sha = local.redis_sync_lambda_dir_sha
45+
}
46+
}
47+
48+
# Define the lambdaECRImageRetreival policy
49+
resource "aws_ecr_repository_policy" "redis_sync_lambda_ECRImageRetreival_policy" {
50+
repository = aws_ecr_repository.redis_sync_lambda_repository.name
51+
52+
policy = jsonencode({
53+
Version = "2012-10-17"
54+
Statement = [
55+
{
56+
Sid : "LambdaECRImageRetrievalPolicy",
57+
Effect : "Allow",
58+
Principal : {
59+
Service : "lambda.amazonaws.com"
60+
},
61+
Action : [
62+
"ecr:BatchGetImage",
63+
"ecr:DeleteRepositoryPolicy",
64+
"ecr:GetDownloadUrlForLayer",
65+
"ecr:GetRepositoryPolicy",
66+
"ecr:SetRepositoryPolicy"
67+
],
68+
Condition : {
69+
StringLike : {
70+
"aws:sourceArn" : aws_lambda_function.redis_sync_lambda.arn
71+
}
72+
}
73+
}
74+
]
75+
})
76+
}
77+
78+
# IAM Role for Lambda
79+
resource "aws_iam_role" "redis_sync_lambda_exec_role" {
80+
name = "${local.short_prefix}-redis-sync-lambda-exec-role"
81+
assume_role_policy = jsonencode({
82+
Version = "2012-10-17",
83+
Statement = [{
84+
Effect = "Allow",
85+
Sid = "",
86+
Principal = {
87+
Service = "lambda.amazonaws.com"
88+
},
89+
Action = "sts:AssumeRole"
90+
}]
91+
})
92+
}
93+
94+
# Policy for Lambda execution role
95+
resource "aws_iam_policy" "redis_sync_lambda_exec_policy" {
96+
name = "${local.short_prefix}-redis-sync-lambda-exec-policy"
97+
policy = jsonencode({
98+
Version = "2012-10-17",
99+
Statement = [
100+
{
101+
Effect = "Allow"
102+
Action = [
103+
"logs:CreateLogGroup",
104+
"logs:CreateLogStream",
105+
"logs:PutLogEvents"
106+
]
107+
Resource = "arn:aws:logs:${var.aws_region}:${var.immunisation_account_id}:log-group:/aws/lambda/${local.short_prefix}-redis_sync_lambda:*"
108+
},
109+
{
110+
Effect = "Allow"
111+
Action = [
112+
"s3:GetObject",
113+
"s3:ListBucket",
114+
"s3:PutObject",
115+
"s3:CopyObject",
116+
"s3:DeleteObject"
117+
]
118+
Resource = [
119+
aws_s3_bucket.batch_data_source_bucket.arn,
120+
"${aws_s3_bucket.batch_data_source_bucket.arn}/*"
121+
]
122+
},
123+
{
124+
Effect = "Allow"
125+
Action = [
126+
"s3:GetObject",
127+
"s3:PutObject",
128+
"s3:ListBucket"
129+
]
130+
Resource = [
131+
aws_s3_bucket.batch_data_destination_bucket.arn,
132+
"${aws_s3_bucket.batch_data_destination_bucket.arn}/*"
133+
]
134+
},
135+
{
136+
Effect = "Allow",
137+
Action = [
138+
"ec2:CreateNetworkInterface",
139+
"ec2:DescribeNetworkInterfaces",
140+
"ec2:DeleteNetworkInterface"
141+
],
142+
Resource = "*"
143+
},
144+
{
145+
Effect = "Allow"
146+
Action = [
147+
"s3:GetObject",
148+
"s3:PutObject",
149+
"s3:ListBucket"
150+
]
151+
Resource = [
152+
local.config_bucket_arn,
153+
"${local.config_bucket_arn}/*"
154+
]
155+
},
156+
{
157+
Effect : "Allow",
158+
Action : [
159+
"firehose:PutRecord",
160+
"firehose:PutRecordBatch"
161+
],
162+
Resource : "arn:aws:firehose:*:*:deliverystream/${module.splunk.firehose_stream_name}"
163+
},
164+
{
165+
Effect = "Allow"
166+
Action = "lambda:InvokeFunction"
167+
Resource = [
168+
"arn:aws:lambda:${var.aws_region}:${var.immunisation_account_id}:function:imms-${var.sub_environment}-redis_sync_lambda",
169+
]
170+
},
171+
# NEW
172+
{
173+
Effect = "Allow",
174+
Action = [
175+
"sqs:ReceiveMessage",
176+
"sqs:DeleteMessage",
177+
"sqs:GetQueueAttributes"
178+
],
179+
Resource = "arn:aws:sqs:eu-west-2:${var.immunisation_account_id}:${local.short_prefix}-id-sync-queue"
180+
},
181+
{
182+
Effect = "Allow",
183+
Action = [
184+
"kms:Decrypt",
185+
"kms:GenerateDataKey"
186+
],
187+
Resource = data.aws_kms_key.existing_id_sync_sqs_encryption_key.arn
188+
}
189+
]
190+
})
191+
}
192+
193+
resource "aws_iam_policy" "redis_sync_lambda_kms_access_policy" {
194+
name = "${local.short_prefix}-redis-sync-lambda-kms-policy"
195+
description = "Allow Lambda to decrypt environment variables"
196+
197+
policy = jsonencode({
198+
Version = "2012-10-17"
199+
Statement = [
200+
{
201+
Effect = "Allow"
202+
Action = [
203+
"kms:Decrypt"
204+
]
205+
Resource = data.aws_kms_key.existing_lambda_encryption_key.arn
206+
},
207+
{
208+
Effect = "Allow"
209+
Action = [
210+
"kms:Encrypt",
211+
"kms:Decrypt",
212+
"kms:GenerateDataKey*"
213+
]
214+
Resource = [
215+
data.aws_kms_key.existing_s3_encryption_key.arn,
216+
]
217+
}
218+
]
219+
})
220+
}
221+
222+
# Attach the execution policy to the Lambda role
223+
resource "aws_iam_role_policy_attachment" "redis_sync_lambda_exec_policy_attachment" {
224+
role = aws_iam_role.redis_sync_lambda_exec_role.name
225+
policy_arn = aws_iam_policy.redis_sync_lambda_exec_policy.arn
226+
}
227+
228+
# Attach the kms policy to the Lambda role
229+
resource "aws_iam_role_policy_attachment" "redis_sync_lambda_kms_policy_attachment" {
230+
role = aws_iam_role.redis_sync_lambda_exec_role.name
231+
policy_arn = aws_iam_policy.redis_sync_lambda_kms_access_policy.arn
232+
}
233+
234+
# Lambda Function with Security Group and VPC.
235+
resource "aws_lambda_function" "redis_sync_lambda" {
236+
function_name = "${local.short_prefix}-redis_sync_lambda"
237+
role = aws_iam_role.redis_sync_lambda_exec_role.arn
238+
package_type = "Image"
239+
image_uri = module.redis_sync_docker_image.image_uri
240+
architectures = ["x86_64"]
241+
timeout = 360
242+
243+
vpc_config {
244+
subnet_ids = local.private_subnet_ids
245+
security_group_ids = [data.aws_security_group.existing_securitygroup.id]
246+
}
247+
248+
environment {
249+
variables = {
250+
CONFIG_BUCKET_NAME = local.config_bucket_name
251+
REDIS_HOST = data.aws_elasticache_cluster.existing_redis.cache_nodes[0].address
252+
REDIS_PORT = data.aws_elasticache_cluster.existing_redis.cache_nodes[0].port
253+
REDIS_SYNC_PROC_LAMBDA_NAME = "imms-${var.sub_environment}-redis_sync_lambda"
254+
# NEW
255+
DELTA_TABLE_NAME = aws_dynamodb_table.delta-dynamodb-table.name
256+
PDS_ENV = var.pds_environment
257+
SPLUNK_FIREHOSE_NAME = module.splunk.firehose_stream_name
258+
}
259+
}
260+
kms_key_arn = data.aws_kms_key.existing_lambda_encryption_key.arn
261+
262+
depends_on = [
263+
aws_cloudwatch_log_group.redis_sync_log_group,
264+
aws_iam_policy.redis_sync_lambda_exec_policy
265+
]
266+
}
267+
268+
resource "aws_cloudwatch_log_group" "redis_sync_log_group" {
269+
name = "/aws/lambda/${local.short_prefix}-redis_sync_lambda"
270+
retention_in_days = 30
271+
}
272+
273+
# S3 Bucket notification to trigger Lambda function for config bucket
274+
resource "aws_s3_bucket_notification" "config_lambda_notification" {
275+
276+
bucket = aws_s3_bucket.batch_config_bucket.bucket
277+
278+
lambda_function {
279+
lambda_function_arn = aws_lambda_function.redis_sync_lambda.arn
280+
events = ["s3:ObjectCreated:*"]
281+
}
282+
}
283+
284+
# Permission for the new S3 bucket to invoke the Lambda function
285+
resource "aws_lambda_permission" "new_s3_invoke_permission" {
286+
287+
statement_id = "AllowExecutionFromNewS3"
288+
action = "lambda:InvokeFunction"
289+
function_name = aws_lambda_function.redis_sync_lambda.function_name
290+
principal = "s3.amazonaws.com"
291+
source_arn = local.config_bucket_arn
292+
}
293+
294+
# NEW
295+
resource "aws_lambda_event_source_mapping" "id_sync_sqs_trigger" {
296+
event_source_arn = "arn:aws:sqs:eu-west-2:${local.immunisation_account_id}:${local.short_prefix}-id-sync-queue"
297+
function_name = aws_lambda_function.redis_sync_lambda.arn # TODO
298+
299+
# Optional: Configure batch size and other settings
300+
batch_size = 10
301+
maximum_batching_window_in_seconds = 5
302+
303+
# Optional: Configure error handling
304+
function_response_types = ["ReportBatchItemFailures"]
305+
}

0 commit comments

Comments
 (0)