Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added support for Code Signing Configuration #351

Merged
Merged
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.71.0
rev: v1.76.0
hooks:
- id: terraform_fmt
- id: terraform_validate
Expand All @@ -23,7 +23,7 @@ repos:
- '--args=--only=terraform_standard_module_structure'
- '--args=--only=terraform_workspace_remote'
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
rev: v4.3.0
hooks:
- id: check-merge-conflict
- id: end-of-file-fixer
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ Q4: What does this error mean - `"We currently do not support adding policies fo
- [Multiple regions](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/multiple-regions) - Create the same Lambda Function in multiple regions with non-conflicting IAM roles and policies.
- [Event Source Mapping](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/event-source-mapping) - Create Lambda Function with event source mapping configuration (SQS, DynamoDB, Amazon MQ, and Kinesis).
- [Triggers](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/triggers) - Create Lambda Function with some triggers (eg, Cloudwatch Events, EventBridge).
- [Code Signing](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/code-signing) - Create Lambda Function with code signing configuration.

# Examples by the users of this module

Expand Down Expand Up @@ -695,6 +696,7 @@ No modules.
| <a name="input_cloudwatch_logs_kms_key_id"></a> [cloudwatch\_logs\_kms\_key\_id](#input\_cloudwatch\_logs\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data. | `string` | `null` | no |
| <a name="input_cloudwatch_logs_retention_in_days"></a> [cloudwatch\_logs\_retention\_in\_days](#input\_cloudwatch\_logs\_retention\_in\_days) | Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. | `number` | `null` | no |
| <a name="input_cloudwatch_logs_tags"></a> [cloudwatch\_logs\_tags](#input\_cloudwatch\_logs\_tags) | A map of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_code_signing_config_arn"></a> [code\_signing\_config\_arn](#input\_code\_signing\_config\_arn) | Amazon Resource Name (ARN) for a Code Signing Configuration | `string` | `null` | no |
| <a name="input_compatible_architectures"></a> [compatible\_architectures](#input\_compatible\_architectures) | A list of Architectures Lambda layer is compatible with. Currently x86\_64 and arm64 can be specified. | `list(string)` | `null` | no |
| <a name="input_compatible_runtimes"></a> [compatible\_runtimes](#input\_compatible\_runtimes) | A list of Runtimes this layer is compatible with. Up to 5 runtimes can be specified. | `list(string)` | `[]` | no |
| <a name="input_cors"></a> [cors](#input\_cors) | CORS settings to be used by the Lambda Function URL | `any` | `{}` | no |
Expand Down Expand Up @@ -798,6 +800,8 @@ No modules.
| <a name="output_lambda_function_last_modified"></a> [lambda\_function\_last\_modified](#output\_lambda\_function\_last\_modified) | The date Lambda Function resource was last modified |
| <a name="output_lambda_function_name"></a> [lambda\_function\_name](#output\_lambda\_function\_name) | The name of the Lambda Function |
| <a name="output_lambda_function_qualified_arn"></a> [lambda\_function\_qualified\_arn](#output\_lambda\_function\_qualified\_arn) | The ARN identifying your Lambda Function Version |
| <a name="output_lambda_function_signing_job_arn"></a> [lambda\_function\_signing\_job\_arn](#output\_lambda\_function\_signing\_job\_arn) | ARN of the signing job |
| <a name="output_lambda_function_signing_profile_version_arn"></a> [lambda\_function\_signing\_profile\_version\_arn](#output\_lambda\_function\_signing\_profile\_version\_arn) | ARN of the signing profile version |
| <a name="output_lambda_function_source_code_hash"></a> [lambda\_function\_source\_code\_hash](#output\_lambda\_function\_source\_code\_hash) | Base64-encoded representation of raw SHA-256 sum of the zip file |
| <a name="output_lambda_function_source_code_size"></a> [lambda\_function\_source\_code\_size](#output\_lambda\_function\_source\_code\_size) | The size in bytes of the function .zip file |
| <a name="output_lambda_function_url"></a> [lambda\_function\_url](#output\_lambda\_function\_url) | The URL of the Lambda Function URL |
Expand Down
62 changes: 62 additions & 0 deletions examples/code-signing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# AWS Lambda Code Signing example
tsoe77 marked this conversation as resolved.
Show resolved Hide resolved

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.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.9 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.9 |
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_lambda"></a> [lambda](#module\_lambda) | ../../ | n/a |
| <a name="module_s3_bucket"></a> [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 3.0 |

## Resources

| Name | Type |
|------|------|
| [aws_lambda_code_signing_config.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_code_signing_config) | resource |
| [aws_s3_object.unsigned](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
| [aws_signer_signing_job.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_job) | resource |
| [aws_signer_signing_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/signer_signing_profile) | resource |
| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |

## Inputs

No inputs.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_lambda_function_arn"></a> [lambda\_function\_arn](#output\_lambda\_function\_arn) | The ARN of the Lambda Function |
| <a name="output_lambda_function_invoke_arn"></a> [lambda\_function\_invoke\_arn](#output\_lambda\_function\_invoke\_arn) | The Invoke ARN of the Lambda Function |
| <a name="output_lambda_function_signing_job_arn"></a> [lambda\_function\_signing\_job\_arn](#output\_lambda\_function\_signing\_job\_arn) | ARN of the signing job |
| <a name="output_lambda_function_signing_profile_version_arn"></a> [lambda\_function\_signing\_profile\_version\_arn](#output\_lambda\_function\_signing\_profile\_version\_arn) | ARN of the signing profile version |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
120 changes: 120 additions & 0 deletions examples/code-signing/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
provider "aws" {
region = "eu-west-1"

# Make it faster by skipping something
skip_get_ec2_platforms = true
skip_metadata_api_check = true
skip_region_validation = true
skip_credentials_validation = true
skip_requesting_account_id = true
}

################################################################################
# Lambda Function
################################################################################

module "lambda" {
source = "../../"

function_name = random_pet.this.id
handler = "index.lambda_handler"
runtime = "python3.8"
code_signing_config_arn = aws_lambda_code_signing_config.this.arn
create_package = false

s3_existing_package = {
bucket = aws_signer_signing_job.this.signed_object[0].s3[0].bucket
key = aws_signer_signing_job.this.signed_object[0].s3[0].key
}
}

################################################################################
# Lambda Code Signing
################################################################################

resource "aws_s3_object" "unsigned" {
bucket = module.s3_bucket.s3_bucket_id
key = "unsigned/existing_package.zip"
source = "${path.module}/../fixtures/python3.8-zip/existing_package.zip"

# Making sure that S3 versioning configuration is propagated properly
depends_on = [
module.s3_bucket
]
}

resource "aws_signer_signing_profile" "this" {
platform_id = "AWSLambda-SHA384-ECDSA"
# invalid value for name (must be alphanumeric with max length of 64 characters)
name = replace(random_pet.this.id, "-", "")

signature_validity_period {
value = 3
type = "MONTHS"
}
}

resource "aws_signer_signing_job" "this" {
profile_name = aws_signer_signing_profile.this.name

source {
s3 {
bucket = module.s3_bucket.s3_bucket_id
key = aws_s3_object.unsigned.id
version = aws_s3_object.unsigned.version_id
}
}

destination {
s3 {
bucket = module.s3_bucket.s3_bucket_id
prefix = "signed/"
}
}

ignore_signing_job_failure = true
}

resource "aws_lambda_code_signing_config" "this" {
allowed_publishers {
signing_profile_version_arns = [aws_signer_signing_profile.this.version_arn]
}

policies {
untrusted_artifact_on_deployment = "Enforce"
}
}

################################################################################
# Supporting Resources
################################################################################

resource "random_pet" "this" {
length = 2
}

module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 3.0"

bucket_prefix = "${random_pet.this.id}-"
force_destroy = true

# S3 bucket-level Public Access Block configuration
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"
}
}
}
}
19 changes: 19 additions & 0 deletions examples/code-signing/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "lambda_function_signing_job_arn" {
description = "ARN of the signing job"
value = module.lambda.lambda_function_signing_job_arn
}

output "lambda_function_signing_profile_version_arn" {
description = "ARN of the signing profile version"
value = module.lambda.lambda_function_signing_profile_version_arn
}

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
}
Empty file.
14 changes: 14 additions & 0 deletions examples/code-signing/versions.tf
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
2 changes: 1 addition & 1 deletion examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Note that this example may create resources which cost money. Run `terraform des
| <a name="module_lambda_layer_with_package_deploying_externally"></a> [lambda\_layer\_with\_package\_deploying\_externally](#module\_lambda\_layer\_with\_package\_deploying\_externally) | ../../ | n/a |
| <a name="module_lambda_with_mixed_trusted_entities"></a> [lambda\_with\_mixed\_trusted\_entities](#module\_lambda\_with\_mixed\_trusted\_entities) | ../../ | n/a |
| <a name="module_lambda_with_provisioned_concurrency"></a> [lambda\_with\_provisioned\_concurrency](#module\_lambda\_with\_provisioned\_concurrency) | ../../ | n/a |
| <a name="module_s3_bucket"></a> [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | n/a |
| <a name="module_s3_bucket"></a> [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 3.0 |

## Resources

Expand Down
76 changes: 42 additions & 34 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -105,36 +105,37 @@ module "lambda_function" {
}

attach_policy_json = true
policy_json = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:GetSamplingStatisticSummaries"
],
"Resource": ["*"]
}
]
}
EOF
policy_json = <<-EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:GetSamplingStatisticSummaries"
],
"Resource": ["*"]
}
]
}
EOT

attach_policy_jsons = true
policy_jsons = [<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:*"
],
"Resource": ["*"]
}
]
}
EOF
policy_jsons = [
<<-EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:*"
],
"Resource": ["*"]
}
]
}
EOT
]
number_of_policy_jsons = 1

Expand All @@ -159,10 +160,6 @@ EOF
}
}

###########################
# END: Additional policies
###########################

tags = {
Module = "lambda1"
}
Expand Down Expand Up @@ -379,10 +376,21 @@ resource "random_pet" "this" {
}

module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
source = "terraform-aws-modules/s3-bucket/aws"
version = "~> 3.0"

bucket = "${random_pet.this.id}-bucket"
bucket_prefix = "${random_pet.this.id}-"
force_destroy = true

# S3 bucket-level Public Access Block configuration
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true

versioning = {
enabled = true
}
}

resource "aws_sqs_queue" "dlq" {
Expand Down
1 change: 1 addition & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ resource "aws_lambda_function" "this" {
image_uri = var.image_uri
package_type = var.package_type
architectures = var.architectures
code_signing_config_arn = var.code_signing_config_arn

/* ephemeral_storage is not supported in gov-cloud region, so it should be set to `null` */
dynamic "ephemeral_storage" {
Expand Down
10 changes: 10 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ output "lambda_function_source_code_size" {
value = try(aws_lambda_function.this[0].source_code_size, "")
}

output "lambda_function_signing_job_arn" {
description = "ARN of the signing job"
value = try(aws_lambda_function.this[0].signing_job_arn, "")
}

output "lambda_function_signing_profile_version_arn" {
description = "ARN of the signing profile version"
value = try(aws_lambda_function.this[0].signing_profile_version_arn, "")
}

# Lambda Function URL
output "lambda_function_url" {
description = "The URL of the Lambda Function URL"
Expand Down
Loading