Skip to content

Commit 156ee79

Browse files
authored
Refactoring of SSM configuration (#3)
* streamlined tests and variables - use objects in favour of maps to have a more precise API and documentation (those are interchangeable from a client perspective) - use lambda fixture in all tests - streamlined examples - added deprecation comments for ssm - use `kms_key_arn` (also) as described in https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#kms_key_arn * new configuration for ssm - custom object which can be enhanced for kms_key later - adapted documentation and added example - allow `ssm:GetParameter` for spring-media users, this fixes spring-media/terraform-aws-lambda#61 and spring-media/terraform-aws-lambda#59
1 parent 807feb8 commit 156ee79

File tree

22 files changed

+280
-161
lines changed

22 files changed

+280
-161
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ terraform.tfstate.backup
44

55
bin/
66
.idea
7+
lambda.zip

README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![](https://github.com/moritzzimmer/terraform-aws-lambda/workflows/Terraform%20CI/badge.svg) [![Terraform Module Registry](https://img.shields.io/badge/Terraform%20Module%20Registry-5.3.0-blue.svg)](https://registry.terraform.io/modules/moritzzimmer/lambda/aws/5.3.0) ![Terraform Version](https://img.shields.io/badge/Terraform-0.12+-green.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44

5-
Terraform module to create AWS [Lambda](https://www.terraform.io/docs/providers/aws/r/lambda_function.html) resources with configurable event sources, IAM configuration (following the [principal of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)), VPC as well as SSM/KMS and log streaming support.
5+
Terraform module to create AWS [Lambda](https://www.terraform.io/docs/providers/aws/r/lambda_function.html) resources with configurable event sources, IAM configuration (following the [principal of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)), VPC as well as SSM and log streaming support.
66

77
The following [event sources](https://docs.aws.amazon.com/lambda/latest/dg/invoking-lambda-function.html) are supported (see [examples](#examples)):
88

@@ -15,7 +15,7 @@ The following [event sources](https://docs.aws.amazon.com/lambda/latest/dg/invok
1515

1616
Furthermore this module supports:
1717

18-
- reading configuration and secrets from [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html) including decryption of [SecureString](https://docs.aws.amazon.com/kms/latest/developerguide/services-parameter-store.html) parameters
18+
- adding IAM permissions for read access to parameters from [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html)
1919
- [CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html) Log group configuration including retention time and [subscription filters](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html) e.g. to stream logs via Lambda to Elasticsearch
2020

2121
## History
@@ -79,8 +79,9 @@ module "lambda" {
7979
module "lambda" {
8080
// see above
8181
82-
ssm_parameter_names = ["some/config/root/*"]
83-
kms_key_arn = "arn:aws:kms:eu-west-1:647379381847:key/f79f2b-04684-4ad9-f9de8a-79d72f"
82+
ssm = {
83+
parameter_names = [aws_ssm_parameter.string.name, aws_ssm_parameter.secure_string.name]
84+
}
8485
}
8586
```
8687

@@ -102,6 +103,7 @@ module "lambda" {
102103
- [example-with-s3-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-s3-event)
103104
- [example-with-sns-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-sns-event)
104105
- [example-with-sqs-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-sqs-event)
106+
- [example-with-ssm-permissions](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-ssm-permissions)
105107
- [example-with-vpc](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-vpc)
106108
- [example-without-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-without-event)
107109

@@ -137,12 +139,12 @@ MINOR, and PATCH versions on each release to indicate any incompatibilities.
137139
| Name | Description | Type | Default | Required |
138140
|------|-------------|------|---------|:--------:|
139141
| description | Description of what your Lambda Function does. | `string` | `""` | no |
140-
| environment | Environment (e.g. env variables) configuration for the Lambda function enable you to dynamically pass settings to your function code and libraries | `map(map(string))` | `{}` | no |
142+
| environment | Environment (e.g. env variables) configuration for the Lambda function enable you to dynamically pass settings to your function code and libraries | <pre>object({<br> variables = map(string)<br> })</pre> | `null` | no |
141143
| event | Event source configuration which triggers the Lambda function. Supported events: cloudwatch-scheduled-event, dynamodb, s3, sns | `map(string)` | `{}` | no |
142144
| filename | The path to the function's deployment package within the local filesystem. If defined, The s3\_-prefixed options cannot be used. | `string` | `""` | no |
143145
| function\_name | A unique name for your Lambda Function. | `any` | n/a | yes |
144146
| handler | The function entrypoint in your code. | `any` | n/a | yes |
145-
| kms\_key\_arn | The Amazon Resource Name (ARN) of the KMS key to decrypt AWS Systems Manager parameters. | `string` | `""` | no |
147+
| kms\_key\_arn | Amazon Resource Name (ARN) of the AWS Key Management Service (KMS) key that is used to encrypt environment variables. If this configuration is not provided when environment variables are in use, AWS Lambda uses a default service key. If this configuration is provided when environment variables are not in use, the AWS Lambda API does not save this configuration and Terraform will show a perpetual difference of adding the key. To fix the perpetual difference, remove this configuration. | `string` | `""` | no |
146148
| layers | List of Lambda Layer Version ARNs (maximum of 5) to attach to your Lambda Function. | `list(string)` | `[]` | no |
147149
| log\_retention\_in\_days | Specifies the number of days you want to retain log events in the specified log group. Defaults to 14. | `number` | `14` | no |
148150
| logfilter\_destination\_arn | The ARN of the destination to deliver matching log events to. Kinesis stream or Lambda function ARN. | `string` | `""` | no |
@@ -154,10 +156,11 @@ MINOR, and PATCH versions on each release to indicate any incompatibilities.
154156
| s3\_key | The S3 key of an object containing the function's deployment package. Conflicts with filename. | `string` | `""` | no |
155157
| s3\_object\_version | The object version containing the function's deployment package. Conflicts with filename. | `string` | `""` | no |
156158
| source\_code\_hash | Used to trigger updates. Must be set to a base64-encoded SHA256 hash of the package file specified with either filename or s3\_key. The usual way to set this is filebase64sha256('file.zip') where 'file.zip' is the local filename of the lambda function source archive. | `string` | `""` | no |
157-
| ssm\_parameter\_names | List of AWS Systems Manager Parameter Store parameters this Lambda will have access to. In order to decrypt secure parameters, a kms\_key\_arn needs to be provided as well. | `list` | `[]` | no |
159+
| ssm | List of AWS Systems Manager Parameter Store parameter names. The IAM role of this Lambda function will be enhanced with read permissions for those parameters. Parameters must start with a forward slash and can be encrypted with the default KMS key. | <pre>object({<br> parameter_names = list(string)<br> })</pre> | `null` | no |
160+
| ssm\_parameter\_names | DEPRECATED: use `ssm` object instead. This variable will be removed in version 6 of this module. (List of AWS Systems Manager Parameter Store parameters this Lambda will have access to. In order to decrypt secure parameters, a kms\_key\_arn needs to be provided as well.) | `list` | `[]` | no |
158161
| tags | A mapping of tags to assign to the Lambda function. | `map(string)` | `{}` | no |
159162
| timeout | The amount of time your Lambda Function has to run in seconds. Defaults to 3. | `number` | `3` | no |
160-
| vpc\_config | Provide this to allow your function to access your VPC (if both 'subnet\_ids' and 'security\_group\_ids' are empty then vpc\_config is considered to be empty or unset, see https://docs.aws.amazon.com/lambda/latest/dg/vpc.html for details). | `map(list(string))` | `{}` | no |
163+
| vpc\_config | Provide this to allow your function to access your VPC (if both 'subnet\_ids' and 'security\_group\_ids' are empty then vpc\_config is considered to be empty or unset, see https://docs.aws.amazon.com/lambda/latest/dg/vpc.html for details). | <pre>object({<br> security_group_ids = list(string)<br> subnet_ids = list(string)<br> })</pre> | `null` | no |
161164

162165
## Outputs
163166

@@ -167,3 +170,4 @@ MINOR, and PATCH versions on each release to indicate any incompatibilities.
167170
| function\_name | The unique name of your Lambda Function. |
168171
| invoke\_arn | The ARN to be used for invoking Lambda Function from API Gateway - to be used in aws\_api\_gateway\_integration's uri |
169172
| role\_name | The name of the IAM role attached to the Lambda Function. |
173+

docs/part1.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![](https://github.com/moritzzimmer/terraform-aws-lambda/workflows/Terraform%20CI/badge.svg) [![Terraform Module Registry](https://img.shields.io/badge/Terraform%20Module%20Registry-5.3.0-blue.svg)](https://registry.terraform.io/modules/moritzzimmer/lambda/aws/5.3.0) ![Terraform Version](https://img.shields.io/badge/Terraform-0.12+-green.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44

5-
Terraform module to create AWS [Lambda](https://www.terraform.io/docs/providers/aws/r/lambda_function.html) resources with configurable event sources, IAM configuration (following the [principal of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)), VPC as well as SSM/KMS and log streaming support.
5+
Terraform module to create AWS [Lambda](https://www.terraform.io/docs/providers/aws/r/lambda_function.html) resources with configurable event sources, IAM configuration (following the [principal of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)), VPC as well as SSM and log streaming support.
66

77
The following [event sources](https://docs.aws.amazon.com/lambda/latest/dg/invoking-lambda-function.html) are supported (see [examples](#examples)):
88

@@ -15,7 +15,7 @@ The following [event sources](https://docs.aws.amazon.com/lambda/latest/dg/invok
1515

1616
Furthermore this module supports:
1717

18-
- reading configuration and secrets from [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html) including decryption of [SecureString](https://docs.aws.amazon.com/kms/latest/developerguide/services-parameter-store.html) parameters
18+
- adding IAM permissions for read access to parameters from [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html)
1919
- [CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html) Log group configuration including retention time and [subscription filters](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html) e.g. to stream logs via Lambda to Elasticsearch
2020

2121
## History
@@ -79,8 +79,9 @@ module "lambda" {
7979
module "lambda" {
8080
// see above
8181
82-
ssm_parameter_names = ["some/config/root/*"]
83-
kms_key_arn = "arn:aws:kms:eu-west-1:647379381847:key/f79f2b-04684-4ad9-f9de8a-79d72f"
82+
ssm = {
83+
parameter_names = [aws_ssm_parameter.string.name, aws_ssm_parameter.secure_string.name]
84+
}
8485
}
8586
```
8687

@@ -102,6 +103,7 @@ module "lambda" {
102103
- [example-with-s3-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-s3-event)
103104
- [example-with-sns-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-sns-event)
104105
- [example-with-sqs-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-sqs-event)
106+
- [example-with-ssm-permissions](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-ssm-permissions)
105107
- [example-with-vpc](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-with-vpc)
106108
- [example-without-event](https://github.com/moritzzimmer/terraform-aws-lambda/tree/master/examples/example-without-event)
107109

docs/part2.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
| Name | Description | Type | Default | Required |
1616
|------|-------------|------|---------|:--------:|
1717
| description | Description of what your Lambda Function does. | `string` | `""` | no |
18-
| environment | Environment (e.g. env variables) configuration for the Lambda function enable you to dynamically pass settings to your function code and libraries | `map(map(string))` | `{}` | no |
18+
| environment | Environment (e.g. env variables) configuration for the Lambda function enable you to dynamically pass settings to your function code and libraries | <pre>object({<br> variables = map(string)<br> })</pre> | `null` | no |
1919
| event | Event source configuration which triggers the Lambda function. Supported events: cloudwatch-scheduled-event, dynamodb, s3, sns | `map(string)` | `{}` | no |
2020
| filename | The path to the function's deployment package within the local filesystem. If defined, The s3\_-prefixed options cannot be used. | `string` | `""` | no |
2121
| function\_name | A unique name for your Lambda Function. | `any` | n/a | yes |
2222
| handler | The function entrypoint in your code. | `any` | n/a | yes |
23-
| kms\_key\_arn | The Amazon Resource Name (ARN) of the KMS key to decrypt AWS Systems Manager parameters. | `string` | `""` | no |
23+
| kms\_key\_arn | Amazon Resource Name (ARN) of the AWS Key Management Service (KMS) key that is used to encrypt environment variables. If this configuration is not provided when environment variables are in use, AWS Lambda uses a default service key. If this configuration is provided when environment variables are not in use, the AWS Lambda API does not save this configuration and Terraform will show a perpetual difference of adding the key. To fix the perpetual difference, remove this configuration. | `string` | `""` | no |
2424
| layers | List of Lambda Layer Version ARNs (maximum of 5) to attach to your Lambda Function. | `list(string)` | `[]` | no |
2525
| log\_retention\_in\_days | Specifies the number of days you want to retain log events in the specified log group. Defaults to 14. | `number` | `14` | no |
2626
| logfilter\_destination\_arn | The ARN of the destination to deliver matching log events to. Kinesis stream or Lambda function ARN. | `string` | `""` | no |
@@ -32,10 +32,11 @@
3232
| s3\_key | The S3 key of an object containing the function's deployment package. Conflicts with filename. | `string` | `""` | no |
3333
| s3\_object\_version | The object version containing the function's deployment package. Conflicts with filename. | `string` | `""` | no |
3434
| source\_code\_hash | Used to trigger updates. Must be set to a base64-encoded SHA256 hash of the package file specified with either filename or s3\_key. The usual way to set this is filebase64sha256('file.zip') where 'file.zip' is the local filename of the lambda function source archive. | `string` | `""` | no |
35-
| ssm\_parameter\_names | List of AWS Systems Manager Parameter Store parameters this Lambda will have access to. In order to decrypt secure parameters, a kms\_key\_arn needs to be provided as well. | `list` | `[]` | no |
35+
| ssm | List of AWS Systems Manager Parameter Store parameter names. The IAM role of this Lambda function will be enhanced with read permissions for those parameters. Parameters must start with a forward slash and can be encrypted with the default KMS key. | <pre>object({<br> parameter_names = list(string)<br> })</pre> | `null` | no |
36+
| ssm\_parameter\_names | DEPRECATED: use `ssm` object instead. This variable will be removed in version 6 of this module. (List of AWS Systems Manager Parameter Store parameters this Lambda will have access to. In order to decrypt secure parameters, a kms\_key\_arn needs to be provided as well.) | `list` | `[]` | no |
3637
| tags | A mapping of tags to assign to the Lambda function. | `map(string)` | `{}` | no |
3738
| timeout | The amount of time your Lambda Function has to run in seconds. Defaults to 3. | `number` | `3` | no |
38-
| vpc\_config | Provide this to allow your function to access your VPC (if both 'subnet\_ids' and 'security\_group\_ids' are empty then vpc\_config is considered to be empty or unset, see https://docs.aws.amazon.com/lambda/latest/dg/vpc.html for details). | `map(list(string))` | `{}` | no |
39+
| vpc\_config | Provide this to allow your function to access your VPC (if both 'subnet\_ids' and 'security\_group\_ids' are empty then vpc\_config is considered to be empty or unset, see https://docs.aws.amazon.com/lambda/latest/dg/vpc.html for details). | <pre>object({<br> security_group_ids = list(string)<br> subnet_ids = list(string)<br> })</pre> | `null` | no |
3940

4041
## Outputs
4142

@@ -45,3 +46,4 @@
4546
| function\_name | The unique name of your Lambda Function. |
4647
| invoke\_arn | The ARN to be used for invoking Lambda Function from API Gateway - to be used in aws\_api\_gateway\_integration's uri |
4748
| role\_name | The name of the IAM role attached to the Lambda Function. |
49+

examples/example-with-cloudwatch-event/main.tf

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ provider "aws" {
22
region = "eu-west-1"
33
}
44

5+
module "source" {
6+
source = "../fixtures"
7+
}
8+
59
module "lambda-scheduled" {
610
source = "../../"
7-
description = "Example AWS Lambda using go with cloudwatch scheduled event trigger"
8-
filename = "${path.module}/test_function.zip"
9-
function_name = "tf-example-go-basic"
10-
handler = "example-lambda-func"
11-
runtime = "go1.x"
12-
source_code_hash = filebase64sha256("${path.module}/test_function.zip")
11+
description = "Example usage for an AWS Lambda with a CloudWatch (scheduled) event trigger."
12+
filename = module.source.output_path
13+
function_name = "example-with-cloudwatch-scheduled-event"
14+
handler = "handler"
15+
runtime = "nodejs12.x"
16+
source_code_hash = module.source.output_base64sha256
1317

1418
event = {
1519
type = "cloudwatch-event"
@@ -19,12 +23,12 @@ module "lambda-scheduled" {
1923

2024
module "lambda-pattern" {
2125
source = "../../"
22-
description = "Example AWS Lambda using go with cloudwatch event pattern trigger"
23-
filename = "${path.module}/test_function.zip"
24-
function_name = "tf-example-go-basic"
25-
handler = "example-lambda-func"
26-
runtime = "go1.x"
27-
source_code_hash = filebase64sha256("${path.module}/test_function.zip")
26+
description = "Example usage for an AWS Lambda with a CloudWatch event trigger."
27+
filename = module.source.output_path
28+
function_name = "example-with-cloudwatch-event"
29+
handler = "handler"
30+
runtime = "nodejs12.x"
31+
source_code_hash = module.source.output_base64sha256
2832

2933
event = {
3034
type = "cloudwatch-event"

examples/example-with-dynamodb-event/main.tf

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,21 @@ provider "aws" {
22
region = "eu-west-1"
33
}
44

5+
module "source" {
6+
source = "../fixtures"
7+
}
8+
59
module "lambda" {
610
source = "../../"
7-
filename = "${path.module}/test_function.zip"
8-
function_name = "my-function"
9-
handler = "my-handler"
10-
runtime = "go1.x"
11-
source_code_hash = filebase64sha256("${path.module}/test_function.zip")
11+
description = "Example usage for an AWS Lambda with a DynamoDb event trigger."
12+
filename = module.source.output_path
13+
function_name = "example-with-dynamodb-event"
14+
handler = "handler"
15+
runtime = "nodejs12.x"
16+
source_code_hash = module.source.output_base64sha256
1217

1318
event = {
1419
type = "dynamodb"
1520
event_source_arn = "arn:aws:dynamodb:eu-west-1:647379381847:table/some-table/stream/some-identifier"
1621
}
17-
18-
# optionally configure Parameter Store access with decryption
19-
ssm_parameter_names = ["some/config/root/*"]
20-
kms_key_arn = "arn:aws:kms:eu-west-1:647379381847:key/f79f2b-04684-4ad9-f9de8a-79d72f"
21-
22-
# optionally create a log subscription for streaming log events
23-
logfilter_destination_arn = "arn:aws:lambda:eu-west-1:647379381847:function:cloudwatch_logs_to_es_production"
24-
25-
tags = {
26-
key = "value"
27-
}
2822
}

0 commit comments

Comments
 (0)