diff --git a/examples/code-signing/README.md b/examples/code-signing/README.md new file mode 100644 index 00000000..01d82bdb --- /dev/null +++ b/examples/code-signing/README.md @@ -0,0 +1,15 @@ +# AWS Lambda Code Signing example + +Configuration in this directory creates AWS Lambda Function deployed with code signing profile and signed code. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. diff --git a/examples/code-signing/main.tf b/examples/code-signing/main.tf new file mode 100644 index 00000000..d0f06cda --- /dev/null +++ b/examples/code-signing/main.tf @@ -0,0 +1,100 @@ +locals { + lambda_s3_bucket = "hello-world-lambda-s3-bucket" + lambda_zip_filename = "lambda.zip" + lambda_function_name = "hello-world-lambda" +} + +# create a s3 bucket to store signed code +module "lambda_s3_bucket" { + source = "terraform-aws-modules/s3-bucket/aws" + bucket = local.lambda_s3_bucket + acl = "private" + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true + versioning = { + enabled = true + } + server_side_encryption_configuration = { + rule = { + apply_server_side_encryption_by_default = { + sse_algorithm = "AES256" + } + } + } +} + +# create a signing profile +resource "aws_signer_signing_profile" "lambda_signing_profile" { + # aws signer list-signing-platforms | jq '.platforms[].platformId' + platform_id = "AWSLambda-SHA384-ECDSA" + name = "lambda_signing_profile" + + signature_validity_period { + value = 3 + type = "MONTHS" + } +} + +# upload zipped lambda code to s3 +data "archive_file" "lambda" { + type = "zip" + source_dir = "dist" + output_path = local.lambda_zip_filename +} + +resource "aws_s3_bucket_object" "lambda" { + bucket = module.lambda_s3_bucket.s3_bucket_id + key = "unsigned/${data.archive_file.lambda.output_path}" + source = data.archive_file.lambda.output_path +} + +# code signing job +resource "aws_signer_signing_job" "build_signing_job" { + profile_name = aws_signer_signing_profile.lambda_signing_profile.name + + source { + s3 { + bucket = module.lambda_s3_bucket.s3_bucket_id + key = "unsigned/${local.lambda_zip_filename}" + version = aws_s3_bucket_object.lambda.version_id + } + } + + destination { + s3 { + bucket = module.lambda_s3_bucket.s3_bucket_id + prefix = "signed/" + } + } + + ignore_signing_job_failure = true + + depends_on = [ + aws_s3_bucket_object.lambda + ] +} + +resource "aws_lambda_code_signing_config" "lambda" { + allowed_publishers { + signing_profile_version_arns = [aws_signer_signing_profile.lambda_signing_profile.version_arn] + } + policies { + untrusted_artifact_on_deployment = "Enforce" + } +} + +module "lambda" { + source = "../../" + + function_name = local.lambda_function_name + handler = "lambda.lambda_handler" + runtime = "python3.8" + code_signing_config_arn = aws_lambda_code_signing_config.lambda.arn + create_package = false + s3_existing_package = { + bucket = module.lambda_s3_bucket.s3_bucket_id + key = "signed/${aws_signer_signing_job.build_signing_job.id}.zip" + } +} diff --git a/examples/code-signing/outputs.tf b/examples/code-signing/outputs.tf new file mode 100644 index 00000000..9dcecfdd --- /dev/null +++ b/examples/code-signing/outputs.tf @@ -0,0 +1,10 @@ +# Lambda Function +output "lambda_function_arn" { + description = "The ARN of the Lambda Function" + value = module.lambda.lambda_function_arn +} + +output "lambda_function_invoke_arn" { + description = "The Invoke ARN of the Lambda Function" + value = module.lambda.lambda_function_invoke_arn +} diff --git a/examples/code-signing/variables.tf b/examples/code-signing/variables.tf new file mode 100644 index 00000000..e69de29b diff --git a/examples/code-signing/versions.tf b/examples/code-signing/versions.tf new file mode 100644 index 00000000..629d346a --- /dev/null +++ b/examples/code-signing/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.9" + } + random = { + source = "hashicorp/random" + version = ">= 2.0" + } + } +}