Skip to content

Commit

Permalink
Add example 's3-custom-kms-key' and update documentation
Browse files Browse the repository at this point in the history
New example 's3-custom-kms-key' was added and mentioned in the main README
  • Loading branch information
joschna committed Oct 20, 2023
1 parent e427799 commit 5945ae1
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 5 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -558,31 +558,31 @@ module "lambda_function_existing_package_from_remote_url" {
```

## <a name="sam_cli_integration"></a> How to use AWS SAM CLI to test Lambda Function?
[AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html) is an open source tool that help the developers to initiate, build, test, and deploy serverless
[AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html) is an open source tool that help the developers to initiate, build, test, and deploy serverless
applications. SAM CLI tool [supports Terraform applications](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-terraform-support.html).

SAM CLI provides two ways of testing: local testing and testing on-cloud (Accelerate).

### Local Testing
Using SAM CLI, you can invoke the lambda functions defined in the terraform application locally using the [sam local invoke](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html)
command, providing the function terraform address, or function name, and to set the `hook-name` to `terraform` to tell SAM CLI that the underlying project is a terraform application.
command, providing the function terraform address, or function name, and to set the `hook-name` to `terraform` to tell SAM CLI that the underlying project is a terraform application.

You can execute the `sam local invoke` command from your terraform application root directory as following:
```
sam local invoke --hook-name terraform module.hello_world_function.aws_lambda_function.this[0]
sam local invoke --hook-name terraform module.hello_world_function.aws_lambda_function.this[0]
```
You can also pass an event to your lambda function, or overwrite its environment variables. Check [here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-invoke.html) for more information.

You can also invoke your lambda function in debugging mode, and step-through your lambda function source code locally in your preferred editor. Check [here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-debugging.html) for more information.

### Testing on-cloud (Accelerate)
You can use AWS SAM CLI to quickly test your application on your AWS development account. Using SAM Accelerate, you will be able to develop your lambda functions locally,
You can use AWS SAM CLI to quickly test your application on your AWS development account. Using SAM Accelerate, you will be able to develop your lambda functions locally,
and once you save your updates, SAM CLI will update your development account with the updated Lambda functions. So, you can test it on cloud, and if there is any bug,
you can quickly update the code, and SAM CLI will take care of pushing it to the cloud. Check [here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/accelerate.html) for more information about SAM Accelerate.

You can execute the `sam sync` command from your terraform application root directory as following:
```
sam sync --hook-name terraform --watch
sam sync --hook-name terraform --watch
```

## <a name="deployment"></a> How to deploy and manage Lambda Functions?
Expand Down Expand Up @@ -651,6 +651,7 @@ Q4: What does this error mean - `"We currently do not support adding policies fo
- [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.
- [S3 Custom KMS Key](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/examples/s3-custom-kms-key) - Upload Lambda package to S3 using a custom KMS key

# Examples by the users of this module

Expand Down Expand Up @@ -837,6 +838,7 @@ No modules.
| <a name="input_s3_acl"></a> [s3\_acl](#input\_s3\_acl) | The canned ACL to apply. Valid values are private, public-read, public-read-write, aws-exec-read, authenticated-read, bucket-owner-read, and bucket-owner-full-control. Defaults to private. | `string` | `"private"` | no |
| <a name="input_s3_bucket"></a> [s3\_bucket](#input\_s3\_bucket) | S3 bucket to store artifacts | `string` | `null` | no |
| <a name="input_s3_existing_package"></a> [s3\_existing\_package](#input\_s3\_existing\_package) | The S3 bucket object with keys bucket, key, version pointing to an existing zip-file to use | `map(string)` | `null` | no |
| <a name="input_s3_kms_key_id"></a> [s3\_kms\_key\_id](#input\_s3\_kms\_key\_id) | Specifies a custom KMS key to use for S3 object encryption. | `string` | `null` | no |
| <a name="input_s3_object_storage_class"></a> [s3\_object\_storage\_class](#input\_s3\_object\_storage\_class) | Specifies the desired Storage Class for the artifact uploaded to S3. Can be either STANDARD, REDUCED\_REDUNDANCY, ONEZONE\_IA, INTELLIGENT\_TIERING, or STANDARD\_IA. | `string` | `"ONEZONE_IA"` | no |
| <a name="input_s3_object_tags"></a> [s3\_object\_tags](#input\_s3\_object\_tags) | A map of tags to assign to S3 bucket object. | `map(string)` | `{}` | no |
| <a name="input_s3_object_tags_only"></a> [s3\_object\_tags\_only](#input\_s3\_object\_tags\_only) | Set to true to not merge tags with s3\_object\_tags. Useful to avoid breaching S3 Object 10 tag limit. | `bool` | `false` | no |
Expand Down
1 change: 1 addition & 0 deletions examples/s3-custom-kms-key/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
builds/*
69 changes: 69 additions & 0 deletions examples/s3-custom-kms-key/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# AWS Lambda Function with custom KMS key encryption in S3

Configuration in this directory creates AWS Lambda Function that is uploaded to S3 using a self-managed KMS key.

## 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) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.63 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |

## Providers

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

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_lambda_function"></a> [lambda\_function](#module\_lambda\_function) | ../../ | 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_kms_key.objects](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | 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_cloudwatch_log_group_arn"></a> [lambda\_cloudwatch\_log\_group\_arn](#output\_lambda\_cloudwatch\_log\_group\_arn) | The ARN of the Cloudwatch Log Group |
| <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_arn_static"></a> [lambda\_function\_arn\_static](#output\_lambda\_function\_arn\_static) | The static ARN of the Lambda Function. Use this to avoid cycle errors between resources (e.g., Step Functions) |
| <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_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_qualified_invoke_arn"></a> [lambda\_function\_qualified\_invoke\_arn](#output\_lambda\_function\_qualified\_invoke\_arn) | The Invoke ARN identifying your Lambda Function 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_version"></a> [lambda\_function\_version](#output\_lambda\_function\_version) | Latest published version of Lambda Function |
| <a name="output_lambda_role_arn"></a> [lambda\_role\_arn](#output\_lambda\_role\_arn) | The ARN of the IAM role created for the Lambda Function |
| <a name="output_lambda_role_name"></a> [lambda\_role\_name](#output\_lambda\_role\_name) | The name of the IAM role created for the Lambda Function |
| <a name="output_s3_object"></a> [s3\_object](#output\_s3\_object) | The map with S3 object data of zip archive deployed (if deployment was from S3) |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
57 changes: 57 additions & 0 deletions examples/s3-custom-kms-key/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
provider "aws" {
region = "eu-west-1"

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

module "lambda_function" {
source = "../../"

function_name = "${random_pet.this.id}-lambda-s3-custom-kms-key"
handler = "index.lambda_handler"
runtime = "python3.8"
source_path = "${path.module}/../fixtures/python3.8-app1"

store_on_s3 = true
s3_bucket = module.s3_bucket.s3_bucket_id
s3_prefix = "lambda-builds/"

# Upload to S3 using our self-managed KMS key
s3_kms_key_id = aws_kms_key.objects.arn
}

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

resource "aws_kms_key" "objects" {
description = "KMS key used to encrypt bucket objects"
deletion_window_in_days = 7
}

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

# Only allow uploads with specific KMS key
attach_deny_incorrect_kms_key_sse = true
allowed_kms_key_arn = aws_kms_key.objects.arn
attach_deny_unencrypted_object_uploads = true

versioning = {
enabled = true
}
}
73 changes: 73 additions & 0 deletions examples/s3-custom-kms-key/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Lambda Function
output "lambda_function_arn" {
description = "The ARN of the Lambda Function"
value = module.lambda_function.lambda_function_arn
}

output "lambda_function_arn_static" {
description = "The static ARN of the Lambda Function. Use this to avoid cycle errors between resources (e.g., Step Functions)"
value = module.lambda_function.lambda_function_arn_static
}

output "lambda_function_invoke_arn" {
description = "The Invoke ARN of the Lambda Function"
value = module.lambda_function.lambda_function_invoke_arn
}

output "lambda_function_name" {
description = "The name of the Lambda Function"
value = module.lambda_function.lambda_function_name
}

output "lambda_function_qualified_arn" {
description = "The ARN identifying your Lambda Function Version"
value = module.lambda_function.lambda_function_qualified_arn
}

output "lambda_function_qualified_invoke_arn" {
description = "The Invoke ARN identifying your Lambda Function Version"
value = module.lambda_function.lambda_function_qualified_invoke_arn
}

output "lambda_function_version" {
description = "Latest published version of Lambda Function"
value = module.lambda_function.lambda_function_version
}

output "lambda_function_last_modified" {
description = "The date Lambda Function resource was last modified"
value = module.lambda_function.lambda_function_last_modified
}

output "lambda_function_source_code_hash" {
description = "Base64-encoded representation of raw SHA-256 sum of the zip file"
value = module.lambda_function.lambda_function_source_code_hash
}

output "lambda_function_source_code_size" {
description = "The size in bytes of the function .zip file"
value = module.lambda_function.lambda_function_source_code_size
}

# IAM Role
output "lambda_role_arn" {
description = "The ARN of the IAM role created for the Lambda Function"
value = module.lambda_function.lambda_role_arn
}

output "lambda_role_name" {
description = "The name of the IAM role created for the Lambda Function"
value = module.lambda_function.lambda_role_name
}

# CloudWatch Log Group
output "lambda_cloudwatch_log_group_arn" {
description = "The ARN of the Cloudwatch Log Group"
value = module.lambda_function.lambda_cloudwatch_log_group_arn
}

# Deployment package
output "s3_object" {
description = "The map with S3 object data of zip archive deployed (if deployment was from S3)"
value = module.lambda_function.s3_object
}
Empty file.
14 changes: 14 additions & 0 deletions examples/s3-custom-kms-key/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.63"
}
random = {
source = "hashicorp/random"
version = ">= 2.0"
}
}
}
1 change: 1 addition & 0 deletions wrappers/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ module "wrapper" {
s3_bucket = try(each.value.s3_bucket, var.defaults.s3_bucket, null)
s3_acl = try(each.value.s3_acl, var.defaults.s3_acl, "private")
s3_server_side_encryption = try(each.value.s3_server_side_encryption, var.defaults.s3_server_side_encryption, null)
s3_kms_key_id = try(each.value.s3_kms_key_id, var.defaults.s3_kms_key_id, null)
source_path = try(each.value.source_path, var.defaults.source_path, null)
hash_extra = try(each.value.hash_extra, var.defaults.hash_extra, "")
build_in_docker = try(each.value.build_in_docker, var.defaults.build_in_docker, false)
Expand Down

0 comments on commit 5945ae1

Please sign in to comment.