Skip to content

Commit

Permalink
feat: Added support for Code Signing Configuration (#351)
Browse files Browse the repository at this point in the history
Co-authored-by: Bryant Biggs <[email protected]>
Co-authored-by: Anton Babenko <[email protected]>
  • Loading branch information
3 people authored Oct 22, 2022
1 parent 62cdf74 commit dd40178
Show file tree
Hide file tree
Showing 12 changed files with 281 additions and 37 deletions.
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

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

0 comments on commit dd40178

Please sign in to comment.