From 15588b9d6d1b8a7f20afe6cc002ac60609d05785 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 21:16:20 -0400 Subject: [PATCH 01/26] temporarily disable condition for apply step --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index d560a00..837b6b3 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -156,5 +156,5 @@ jobs: # On push to "main", build or change infrastructure according to Terraform configuration files # Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks - name: Terraform Apply - if: github.ref == 'refs/heads/main' + #if: github.ref == 'refs/heads/main' run: terraform apply -auto-approve -input=false \ No newline at end of file From 139a209cd0dbc689c9a91166fc69bd465fe024d2 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 21:17:21 -0400 Subject: [PATCH 02/26] added conditional logic to sequence resource provisioning steps --- lambda.tf | 1 + lambda_signer_job.tf | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 lambda_signer_job.tf diff --git a/lambda.tf b/lambda.tf index 497a21e..2a8cd27 100644 --- a/lambda.tf +++ b/lambda.tf @@ -36,6 +36,7 @@ resource "aws_lambda_function" "lambda_run" { code_signing_config_arn = aws_lambda_code_signing_config.configuration.arn reserved_concurrent_executions = 5 #checkov:skip=CKV_AWS_50: Not applicable in this use case: X-Ray tracing is enabled for Lambda + depends_on = [null_resource.sign_lambda_code] } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule resource "aws_cloudwatch_event_rule" "lambda_trigger" { diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf new file mode 100644 index 0000000..dfc2536 --- /dev/null +++ b/lambda_signer_job.tf @@ -0,0 +1,16 @@ +# Sign the Lambda function code using AWS Signer +resource "null_resource" "sign_lambda_code" { + depends_on = [ + data.archive_file.python_file, + aws_signer_signing_profile.lambda_signing_profile + ] + + # Use standard shell for Linux + provisioner "local-exec" { + command = "aws signer start-signing-job --source s3=bucket=${var.name}-lambda-code,key=lambda_function.zip --destination s3=bucket=${var.name}-lambda-code,key=lambda_function_signed.zip --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" + } + + triggers = { + source_code_hash = data.archive_file.python_file.output_base64sha256 + } +} \ No newline at end of file From 2fc759b31edbd6f4c619fb34fc776be4c41de3b0 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 21:19:26 -0400 Subject: [PATCH 03/26] format --- lambda.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lambda.tf b/lambda.tf index 2a8cd27..da4fb82 100644 --- a/lambda.tf +++ b/lambda.tf @@ -36,7 +36,7 @@ resource "aws_lambda_function" "lambda_run" { code_signing_config_arn = aws_lambda_code_signing_config.configuration.arn reserved_concurrent_executions = 5 #checkov:skip=CKV_AWS_50: Not applicable in this use case: X-Ray tracing is enabled for Lambda - depends_on = [null_resource.sign_lambda_code] + depends_on = [null_resource.sign_lambda_code] } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule resource "aws_cloudwatch_event_rule" "lambda_trigger" { From e346d2a155f462dfecd9c78d98ffc31ff99bb47f Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 21:23:27 -0400 Subject: [PATCH 04/26] converted to read zip file from local workspace --- lambda_signer_job.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index dfc2536..87efff7 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -5,9 +5,9 @@ resource "null_resource" "sign_lambda_code" { aws_signer_signing_profile.lambda_signing_profile ] - # Use standard shell for Linux + # Use local-exec with interpreter for OS-agnostic execution provisioner "local-exec" { - command = "aws signer start-signing-job --source s3=bucket=${var.name}-lambda-code,key=lambda_function.zip --destination s3=bucket=${var.name}-lambda-code,key=lambda_function_signed.zip --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" + command = "aws signer start-signing-job --source file://${path.module}/lambda_function/lambda_function.zip --destination file://${path.module}/lambda_function/lambda_function_signed.zip --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" } triggers = { From 9a74aa7ac828d3d4036b0a54ce65f8acb9be4221 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 22:19:00 -0400 Subject: [PATCH 05/26] documentation --- data.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/data.tf b/data.tf index 4a339a7..3c8f9bc 100644 --- a/data.tf +++ b/data.tf @@ -1,3 +1,4 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity data "aws_caller_identity" "current" {} locals { principal_root_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" From 1a1ce0798fca832a3559373454587ac42f94a8ae Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 22:19:32 -0400 Subject: [PATCH 06/26] added s3 resources for code signing --- lambda_signer_job.tf | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 87efff7..0716c0f 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -1,16 +1,47 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket +# Create S3 bucket for Lambda source code +resource "aws_s3_bucket" "lambda_source" { + bucket_prefix = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" + force_destroy = true +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning +# Enable versioning on the source S3 bucket (required for signing) +resource "aws_s3_bucket_versioning" "lambda_source" { + bucket = aws_s3_bucket.lambda_source.id + versioning_configuration { + status = "Enabled" + } +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket +# Create S3 bucket for Lambda source code +resource "aws_s3_bucket" "lambda_destination" { + bucket_prefix = "${var.name}-lambda-destination-${data.aws_caller_identity.current.account_id}" + force_destroy = true +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning +# Enable versioning on the source S3 bucket (required for signing) +resource "aws_s3_bucket_versioning" "lambda_destination" { + bucket = aws_s3_bucket.lambda_destination.id + versioning_configuration { + status = "Enabled" + } +} +#https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource +# Sign the Lambda function code using AWS Signer +#https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource # Sign the Lambda function code using AWS Signer resource "null_resource" "sign_lambda_code" { depends_on = [ - data.archive_file.python_file, + aws_s3_object.lambda_zip, aws_signer_signing_profile.lambda_signing_profile ] - # Use local-exec with interpreter for OS-agnostic execution + # Use AWS Signer with S3 source and destination - correct syntax provisioner "local-exec" { - command = "aws signer start-signing-job --source file://${path.module}/lambda_function/lambda_function.zip --destination file://${path.module}/lambda_function/lambda_function_signed.zip --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" + command = "aws signer start-signing-job --source '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_source.bucket}\",\"key\":\"lambda_function.zip\"}}' --destination '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_destination.bucket}\",\"key\":\"lambda_function_signed.zip\"}}' --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" } triggers = { source_code_hash = data.archive_file.python_file.output_base64sha256 } -} \ No newline at end of file +} From 74d26f871b8b01df25f095daca3b5da70f6a2342 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 22:21:18 -0400 Subject: [PATCH 07/26] converted lambda to consume zip file from an s3 bucket --- lambda.tf | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lambda.tf b/lambda.tf index da4fb82..5cdb974 100644 --- a/lambda.tf +++ b/lambda.tf @@ -4,9 +4,18 @@ data "archive_file" "python_file" { source_dir = "${path.module}/lambda_function/" output_path = "${path.module}/lambda_function/lambda_function.zip" } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object +#Upload Lambda code to source S3 bucket +resource "aws_s3_object" "lambda_zip" { + bucket = aws_s3_bucket.lambda_source.bucket + key = "lambda_function.zip" + source = data.archive_file.python_file.output_path + etag = filemd5(data.archive_file.python_file.output_path) +} #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function resource "aws_lambda_function" "lambda_run" { - filename = "${path.module}/lambda_function/lambda_function.zip" + s3_bucket = aws_s3_bucket.lambda_destination.bucket + s3_key = "lambda_function_signed.zip" source_code_hash = data.archive_file.python_file.output_base64sha256 function_name = var.name role = aws_iam_role.lambda_role.arn @@ -36,6 +45,7 @@ resource "aws_lambda_function" "lambda_run" { code_signing_config_arn = aws_lambda_code_signing_config.configuration.arn reserved_concurrent_executions = 5 #checkov:skip=CKV_AWS_50: Not applicable in this use case: X-Ray tracing is enabled for Lambda + # Ensure Lambda function is created after the code signing process depends_on = [null_resource.sign_lambda_code] } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule From ebe54a8bb7890828db66bbd030187edc18ee76ad Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 22:26:31 -0400 Subject: [PATCH 08/26] corrected signer parameters --- lambda_signer_job.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 0716c0f..4b25d81 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -38,7 +38,7 @@ resource "null_resource" "sign_lambda_code" { # Use AWS Signer with S3 source and destination - correct syntax provisioner "local-exec" { - command = "aws signer start-signing-job --source '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_source.bucket}\",\"key\":\"lambda_function.zip\"}}' --destination '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_destination.bucket}\",\"key\":\"lambda_function_signed.zip\"}}' --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" + command = "aws signer start-signing-job --source '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_source.bucket}\",\"key\":\"lambda_function.zip\",\"version\":\"null\"}}' --destination '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_destination.bucket}\",\"prefix\":\"lambda_function_signed.zip\"}}' --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" } triggers = { From 328d289c9e2c530b7d96c3363e3ae8dac7857d11 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Tue, 27 May 2025 22:34:54 -0400 Subject: [PATCH 09/26] more fixes --- lambda_signer_job.tf | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 4b25d81..41a6257 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -1,7 +1,7 @@ #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket # Create S3 bucket for Lambda source code resource "aws_s3_bucket" "lambda_source" { - bucket_prefix = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" + bucket = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" force_destroy = true } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning @@ -15,7 +15,7 @@ resource "aws_s3_bucket_versioning" "lambda_source" { #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket # Create S3 bucket for Lambda source code resource "aws_s3_bucket" "lambda_destination" { - bucket_prefix = "${var.name}-lambda-destination-${data.aws_caller_identity.current.account_id}" + bucket = "${var.name}-lambda-destination-${data.aws_caller_identity.current.account_id}" force_destroy = true } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning @@ -38,7 +38,21 @@ resource "null_resource" "sign_lambda_code" { # Use AWS Signer with S3 source and destination - correct syntax provisioner "local-exec" { - command = "aws signer start-signing-job --source '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_source.bucket}\",\"key\":\"lambda_function.zip\",\"version\":\"null\"}}' --destination '{\"s3\":{\"bucketName\":\"${aws_s3_bucket.lambda_destination.bucket}\",\"prefix\":\"lambda_function_signed.zip\"}}' --profile-name ${aws_signer_signing_profile.lambda_signing_profile.name}" + command = < Date: Wed, 28 May 2025 08:35:16 -0400 Subject: [PATCH 10/26] updated resource dependency --- lambda_signer_job.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 41a6257..1c4111e 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -28,12 +28,12 @@ resource "aws_s3_bucket_versioning" "lambda_destination" { } #https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource # Sign the Lambda function code using AWS Signer -#https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource -# Sign the Lambda function code using AWS Signer resource "null_resource" "sign_lambda_code" { depends_on = [ aws_s3_object.lambda_zip, - aws_signer_signing_profile.lambda_signing_profile + aws_signer_signing_profile.lambda_signing_profile, + aws_s3_bucket.lambda_source, + aws_s3_bucket.lambda_destination ] # Use AWS Signer with S3 source and destination - correct syntax @@ -58,4 +58,4 @@ resource "null_resource" "sign_lambda_code" { triggers = { source_code_hash = data.archive_file.python_file.output_base64sha256 } -} +} \ No newline at end of file From 40f15b864cadfff843321c684ba831b1eb8aa135 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 08:48:40 -0400 Subject: [PATCH 11/26] signer profile names cannot be reused --- lambda_signer.tf | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lambda_signer.tf b/lambda_signer.tf index e237632..95c66cb 100644 --- a/lambda_signer.tf +++ b/lambda_signer.tf @@ -1,7 +1,14 @@ +# Generate a random string to use as a suffix +#https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string +resource "random_string" "suffix" { + length = 8 + special = false + upper = false +} #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_profile resource "aws_signer_signing_profile" "lambda_signing_profile" { platform_id = "AWSLambda-SHA384-ECDSA" - name = "${replace(var.name, "-", "_")}_lambda_signing_profile" + name = "${replace(var.name, "-", "_")}_lambda_signing_profile_${random_string.suffix.result}" } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_code_signing_config resource "aws_lambda_code_signing_config" "configuration" { From 43339160c825a048c69784b17afa5a49377fc4fa Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 10:03:58 -0400 Subject: [PATCH 12/26] updated with version id information --- lambda_signer_job.tf | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 1c4111e..916f455 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -38,20 +38,30 @@ resource "null_resource" "sign_lambda_code" { # Use AWS Signer with S3 source and destination - correct syntax provisioner "local-exec" { + command = < Date: Wed, 28 May 2025 10:34:51 -0400 Subject: [PATCH 13/26] reading signed file into variable --- lambda_signer_job.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 916f455..1bad4ed 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -38,7 +38,7 @@ resource "null_resource" "sign_lambda_code" { # Use AWS Signer with S3 source and destination - correct syntax provisioner "local-exec" { - + command = < signing_job_id.txt EOT } From be17cd0e3449feaec7f083ad22a4e4f83525d1a3 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 13:52:03 -0400 Subject: [PATCH 14/26] added permissions to lambda --- iam_role.tf | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/iam_role.tf b/iam_role.tf index 713b1ef..c4456b5 100644 --- a/iam_role.tf +++ b/iam_role.tf @@ -54,6 +54,31 @@ resource "aws_iam_policy" "lambda_policy" { "kms:Decrypt" ] Resource = [aws_kms_key.encryption.arn] + }, + # Add S3 permissions for accessing signed code + { + Effect = "Allow", + Action = [ + "s3:GetObject", + "s3:GetObjectVersion" + ], + Resource = [ + "${aws_s3_bucket.lambda_source.arn}/*" + ] + }, + # Add code signing verification permissions + { + Effect = "Allow", + Action = [ + "lambda:GetCodeSigningConfig", + "lambda:GetFunctionCodeSigningConfig", + "lambda:VerifyCodeSignature", + "lambda:*", + "signer:GetSigningProfile", + "signer:DescribeSigningJob", + "signer:*" + ], + Resource = "*" } ] }) From f3ae2ba9fa8e964fe5ced3f235b468618ced1472 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 13:53:41 -0400 Subject: [PATCH 15/26] adding signer orchestration --- lambda.tf | 11 +++++---- lambda_signer.tf | 22 +++++++++++++++++ lambda_signer_job.tf | 59 -------------------------------------------- 3 files changed, 28 insertions(+), 64 deletions(-) diff --git a/lambda.tf b/lambda.tf index 5cdb974..2822b20 100644 --- a/lambda.tf +++ b/lambda.tf @@ -4,7 +4,7 @@ data "archive_file" "python_file" { source_dir = "${path.module}/lambda_function/" output_path = "${path.module}/lambda_function/lambda_function.zip" } -#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object +# #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object #Upload Lambda code to source S3 bucket resource "aws_s3_object" "lambda_zip" { bucket = aws_s3_bucket.lambda_source.bucket @@ -14,8 +14,9 @@ resource "aws_s3_object" "lambda_zip" { } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function resource "aws_lambda_function" "lambda_run" { - s3_bucket = aws_s3_bucket.lambda_destination.bucket - s3_key = "lambda_function_signed.zip" + s3_bucket = aws_signer_signing_job.build_signing_job.signed_object[0].s3[0].bucket + s3_key = aws_signer_signing_job.build_signing_job.signed_object[0].s3[0].key + #filename = data.archive_file.python_file.output_path source_code_hash = data.archive_file.python_file.output_base64sha256 function_name = var.name role = aws_iam_role.lambda_role.arn @@ -45,8 +46,8 @@ resource "aws_lambda_function" "lambda_run" { code_signing_config_arn = aws_lambda_code_signing_config.configuration.arn reserved_concurrent_executions = 5 #checkov:skip=CKV_AWS_50: Not applicable in this use case: X-Ray tracing is enabled for Lambda - # Ensure Lambda function is created after the code signing process - depends_on = [null_resource.sign_lambda_code] + # Ensure the code signing config is created before the Lambda function + depends_on = [aws_lambda_code_signing_config.configuration, aws_signer_signing_job.build_signing_job, aws_iam_role_policy_attachment.lambda_policy_attachement] } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule resource "aws_cloudwatch_event_rule" "lambda_trigger" { diff --git a/lambda_signer.tf b/lambda_signer.tf index 95c66cb..2e901cd 100644 --- a/lambda_signer.tf +++ b/lambda_signer.tf @@ -9,6 +9,10 @@ resource "random_string" "suffix" { resource "aws_signer_signing_profile" "lambda_signing_profile" { platform_id = "AWSLambda-SHA384-ECDSA" name = "${replace(var.name, "-", "_")}_lambda_signing_profile_${random_string.suffix.result}" + signature_validity_period { + value = 135 + type = "MONTHS" + } } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_code_signing_config resource "aws_lambda_code_signing_config" "configuration" { @@ -19,4 +23,22 @@ resource "aws_lambda_code_signing_config" "configuration" { policies { untrusted_artifact_on_deployment = "Enforce" } +} +resource "aws_signer_signing_job" "build_signing_job" { + profile_name = aws_signer_signing_profile.lambda_signing_profile.name + + source { + s3 { + bucket = aws_s3_bucket.lambda_source.bucket + key = aws_s3_object.lambda_zip.key + version = aws_s3_object.lambda_zip.version_id + } + } + + destination { + s3 { + bucket = aws_s3_bucket.lambda_source.bucket + prefix = "signed/" + } + } } \ No newline at end of file diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf index 1bad4ed..285780f 100644 --- a/lambda_signer_job.tf +++ b/lambda_signer_job.tf @@ -11,63 +11,4 @@ resource "aws_s3_bucket_versioning" "lambda_source" { versioning_configuration { status = "Enabled" } -} -#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket -# Create S3 bucket for Lambda source code -resource "aws_s3_bucket" "lambda_destination" { - bucket = "${var.name}-lambda-destination-${data.aws_caller_identity.current.account_id}" - force_destroy = true -} -#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning -# Enable versioning on the source S3 bucket (required for signing) -resource "aws_s3_bucket_versioning" "lambda_destination" { - bucket = aws_s3_bucket.lambda_destination.id - versioning_configuration { - status = "Enabled" - } -} -#https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource -# Sign the Lambda function code using AWS Signer -resource "null_resource" "sign_lambda_code" { - depends_on = [ - aws_s3_object.lambda_zip, - aws_signer_signing_profile.lambda_signing_profile, - aws_s3_bucket.lambda_source, - aws_s3_bucket.lambda_destination - ] - - # Use AWS Signer with S3 source and destination - correct syntax - provisioner "local-exec" { - - command = < signing_job_id.txt - EOT - } - - triggers = { - source_code_hash = data.archive_file.python_file.output_base64sha256 - } } \ No newline at end of file From a570657a09a7ff50ec8de001d7c877349deffc42 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 15:28:58 -0400 Subject: [PATCH 16/26] removed blank --- cloudwatch.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/cloudwatch.tf b/cloudwatch.tf index e6f9afb..787424f 100644 --- a/cloudwatch.tf +++ b/cloudwatch.tf @@ -4,7 +4,6 @@ resource "aws_cloudwatch_log_group" "lambda_log" { retention_in_days = 365 kms_key_id = aws_kms_key.encryption.arn } -# #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_stream resource "aws_cloudwatch_log_stream" "log_stream" { name = "${var.name}-lambda-log-stream" From 15fe914294a6e767727948e2b78559c8b7ebafad Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 16:08:02 -0400 Subject: [PATCH 17/26] converted to version arn from arn --- lambda_signer.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lambda_signer.tf b/lambda_signer.tf index 2e901cd..63d8498 100644 --- a/lambda_signer.tf +++ b/lambda_signer.tf @@ -17,13 +17,15 @@ resource "aws_signer_signing_profile" "lambda_signing_profile" { #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_code_signing_config resource "aws_lambda_code_signing_config" "configuration" { allowed_publishers { - signing_profile_version_arns = [aws_signer_signing_profile.lambda_signing_profile.arn] + signing_profile_version_arns = [aws_signer_signing_profile.lambda_signing_profile.version_arn] } policies { untrusted_artifact_on_deployment = "Enforce" } + description = "Code signing configuration for ${var.name} Lambda function" } +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_job resource "aws_signer_signing_job" "build_signing_job" { profile_name = aws_signer_signing_profile.lambda_signing_profile.name From 427650d051b7629174ea19a6ab8de9884846c005 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 20:15:31 -0400 Subject: [PATCH 18/26] added condition back --- .github/workflows/terraform.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 837b6b3..d560a00 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -156,5 +156,5 @@ jobs: # On push to "main", build or change infrastructure according to Terraform configuration files # Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks - name: Terraform Apply - #if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' run: terraform apply -auto-approve -input=false \ No newline at end of file From b7c05af33beec70124e8010dc75da45939878213 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 21:14:57 -0400 Subject: [PATCH 19/26] removed redudant permission policy --- iam_role.tf | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/iam_role.tf b/iam_role.tf index c4456b5..01bb9ef 100644 --- a/iam_role.tf +++ b/iam_role.tf @@ -65,20 +65,6 @@ resource "aws_iam_policy" "lambda_policy" { Resource = [ "${aws_s3_bucket.lambda_source.arn}/*" ] - }, - # Add code signing verification permissions - { - Effect = "Allow", - Action = [ - "lambda:GetCodeSigningConfig", - "lambda:GetFunctionCodeSigningConfig", - "lambda:VerifyCodeSignature", - "lambda:*", - "signer:GetSigningProfile", - "signer:DescribeSigningJob", - "signer:*" - ], - Resource = "*" } ] }) From 33008ec93fb98370da568e0471a85028069d145d Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Wed, 28 May 2025 21:15:20 -0400 Subject: [PATCH 20/26] added encryption for storage --- kms_storage.tf | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 kms_storage.tf diff --git a/kms_storage.tf b/kms_storage.tf new file mode 100644 index 0000000..7325b0c --- /dev/null +++ b/kms_storage.tf @@ -0,0 +1,65 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key +resource "aws_kms_key" "encrypt_storage" { + enable_key_rotation = true + description = "Key to encrypt S3 bucket in ${var.name}." + deletion_window_in_days = 7 +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias +resource "aws_kms_alias" "encrypt_storage" { + name = "alias/${var.name}-encrypt-storage" + target_key_id = aws_kms_key.encrypt_storage.key_id +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document +data "aws_iam_policy_document" "encrypt_storage_policy" { + statement { + sid = "Enable IAM User Permissions" + effect = "Allow" + principals { + type = "AWS" + identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"] + } + actions = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:DescribeKey", + "kms:Create*", + "kms:Enable*", + "kms:List*", + "kms:Put*", + "kms:Update*", + "kms:Revoke*", + "kms:Disable*", + "kms:Get*", + "kms:Delete*", + "kms:ScheduleKeyDeletion", + "kms:CancelKeyDeletion", + "kms:TagResource", + "kms:UntagResource" + ] + resources = [aws_kms_key.encrypt_storage.arn] + } + statement { + sid = "Allow S3 to use the key" + effect = "Allow" + principals { + type = "Service" + identifiers = ["s3.amazonaws.com"] + } + actions = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:DescribeKey", + "kms:CreateGrant" + ] + resources = [aws_kms_key.encrypt_storage.arn] + } +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy +resource "aws_kms_key_policy" "encrypt_storage" { + key_id = aws_kms_key.encrypt_storage.id + policy = data.aws_iam_policy_document.encrypt_storage_policy.json +} \ No newline at end of file From bec669968ee09abe3b504367a65460010f8e2bdb Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Thu, 29 May 2025 09:52:28 -0400 Subject: [PATCH 21/26] updated filename --- lambda_signer.tf | 2 +- lambda_signer_job.tf | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 lambda_signer_job.tf diff --git a/lambda_signer.tf b/lambda_signer.tf index 63d8498..2591b4d 100644 --- a/lambda_signer.tf +++ b/lambda_signer.tf @@ -23,7 +23,7 @@ resource "aws_lambda_code_signing_config" "configuration" { policies { untrusted_artifact_on_deployment = "Enforce" } - description = "Code signing configuration for ${var.name} Lambda function" + description = "Code signing configuration for ${var.name} Lambda function." } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_job resource "aws_signer_signing_job" "build_signing_job" { diff --git a/lambda_signer_job.tf b/lambda_signer_job.tf deleted file mode 100644 index 285780f..0000000 --- a/lambda_signer_job.tf +++ /dev/null @@ -1,14 +0,0 @@ -#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket -# Create S3 bucket for Lambda source code -resource "aws_s3_bucket" "lambda_source" { - bucket = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" - force_destroy = true -} -#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning -# Enable versioning on the source S3 bucket (required for signing) -resource "aws_s3_bucket_versioning" "lambda_source" { - bucket = aws_s3_bucket.lambda_source.id - versioning_configuration { - status = "Enabled" - } -} \ No newline at end of file From f2330951c7bdc63af535c841a5ddd50f9d7c05fa Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Thu, 29 May 2025 09:53:17 -0400 Subject: [PATCH 22/26] set dependency to manage deployment sequence --- cloudwatch.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/cloudwatch.tf b/cloudwatch.tf index 787424f..1341b54 100644 --- a/cloudwatch.tf +++ b/cloudwatch.tf @@ -3,6 +3,7 @@ resource "aws_cloudwatch_log_group" "lambda_log" { name = "${var.log_group_prefix}${var.name}" retention_in_days = 365 kms_key_id = aws_kms_key.encryption.arn + depends_on = [ aws_kms_key.encryption ] } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_stream resource "aws_cloudwatch_log_stream" "log_stream" { From bab19287b4bb2b6525f6300ef9b9d0b332ef4545 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Thu, 29 May 2025 09:54:00 -0400 Subject: [PATCH 23/26] s3 configuration to store lambda code to enable code signing --- storage.tf | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 storage.tf diff --git a/storage.tf b/storage.tf new file mode 100644 index 0000000..c79d033 --- /dev/null +++ b/storage.tf @@ -0,0 +1,47 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket +# Create S3 bucket for Lambda source code +resource "aws_s3_bucket" "lambda_source" { + bucket = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" + force_destroy = true +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning +# Enable versioning on the source S3 bucket (required for signing) +resource "aws_s3_bucket_versioning" "lambda_source" { + bucket = aws_s3_bucket.lambda_source.id + versioning_configuration { + status = "Enabled" + } +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block +resource "aws_s3_bucket_public_access_block" "lambda_source" { + bucket = aws_s3_bucket.lambda_source.id + block_public_acls = true + block_public_policy = true + restrict_public_buckets = true + ignore_public_acls = true +} +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration +resource "aws_s3_bucket_server_side_encryption_configuration" "lambda_source" { + bucket = aws_s3_bucket.lambda_source.id + + rule { + apply_server_side_encryption_by_default { + kms_master_key_id = aws_kms_key.encrypt_storage.arn + sse_algorithm = "aws:kms" + } + } +} + +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration +resource "aws_s3_bucket_lifecycle_configuration" "lambda_source" { + bucket = aws_s3_bucket.lambda_source.id + + rule { + id = "cleanup-old-versions" + status = "Enabled" + + noncurrent_version_expiration { + noncurrent_days = 90 + } + } +} \ No newline at end of file From a61fed90e85755e0d541127f0ce6e12dec267006 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Thu, 29 May 2025 09:55:27 -0400 Subject: [PATCH 24/26] fix format --- cloudwatch.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudwatch.tf b/cloudwatch.tf index 1341b54..f64f215 100644 --- a/cloudwatch.tf +++ b/cloudwatch.tf @@ -3,7 +3,7 @@ resource "aws_cloudwatch_log_group" "lambda_log" { name = "${var.log_group_prefix}${var.name}" retention_in_days = 365 kms_key_id = aws_kms_key.encryption.arn - depends_on = [ aws_kms_key.encryption ] + depends_on = [aws_kms_key.encryption] } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_stream resource "aws_cloudwatch_log_stream" "log_stream" { From 83b68a3726a64ff45155cbbdf98ea250abf31c8f Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Thu, 29 May 2025 09:59:22 -0400 Subject: [PATCH 25/26] fix for CKV_AWS_300 --- storage.tf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/storage.tf b/storage.tf index c79d033..4628937 100644 --- a/storage.tf +++ b/storage.tf @@ -36,6 +36,14 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "lambda_source" { resource "aws_s3_bucket_lifecycle_configuration" "lambda_source" { bucket = aws_s3_bucket.lambda_source.id + rule { + id = "abort-multipart-uploads" + status = "Enabled" + + abort_incomplete_multipart_upload { + days_after_initiation = 3 + } + } rule { id = "cleanup-old-versions" status = "Enabled" @@ -44,4 +52,5 @@ resource "aws_s3_bucket_lifecycle_configuration" "lambda_source" { noncurrent_days = 90 } } + } \ No newline at end of file From 4a695e9bd54860eab4d70871027c23923ba6db70 Mon Sep 17 00:00:00 2001 From: Sourav Kundu Date: Thu, 29 May 2025 10:06:47 -0400 Subject: [PATCH 26/26] checkov finding suppress messages --- storage.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage.tf b/storage.tf index 4628937..f55e67e 100644 --- a/storage.tf +++ b/storage.tf @@ -3,6 +3,12 @@ resource "aws_s3_bucket" "lambda_source" { bucket = "${var.name}-lambda-source-${data.aws_caller_identity.current.account_id}" force_destroy = true + #checkov:skip=CKV_AWS_18: AWS Access logging not enabled on S3 buckets + #checkov:skip=CKV_AWS_144: Region replication not enabled on S3 bucket + #checkov:skip=CKV2_AWS_62: Ensure S3 buckets should have event notifications enabled + # These security controls are suppressed as this bucket is only used temporarily for Lambda code signing + # and is not intended for long-term storage or public access. The bucket has other security measures + # like encryption and public access blocking enabled. } #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning # Enable versioning on the source S3 bucket (required for signing)