Skip to content

Commit bfcd34c

Browse files
feat: Add SAM Metadata resources to enable the integration with SAM CLI tool (#325)
Co-authored-by: Anton Babenko <anton@antonbabenko.com>
1 parent 90bc484 commit bfcd34c

File tree

5 files changed

+111
-0
lines changed

5 files changed

+111
-0
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ This Terraform module is the part of [serverless.tf framework](https://github.co
1111
3. Create, update, and publish AWS Lambda Function and Lambda Layer - [see usage](#usage).
1212
4. Create static and dynamic aliases for AWS Lambda Function - [see usage](#usage), see [modules/alias](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/modules/alias).
1313
5. Do complex deployments (eg, rolling, canary, rollbacks, triggers) - [read more](#deployment), see [modules/deploy](https://github.com/terraform-aws-modules/terraform-aws-lambda/tree/master/modules/deploy).
14+
6. Use AWS SAM CLI to test Lambda Function - [read more](#sam_cli_integration).
1415

1516
## Features
1617

@@ -551,6 +552,35 @@ module "lambda_function_existing_package_from_remote_url" {
551552
}
552553
```
553554

555+
## <a name="sam_cli_integration"></a> How to use AWS SAM CLI to test Lambda Function?
556+
[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
557+
applications. Currently, SAM CLI tool only supports CFN applications, but SAM CLI team is working on a feature to extend the testing capabilities to support terraform applications (check this [Github issue](https://github.com/aws/aws-sam-cli/issues/3154)
558+
to be updated about the incoming releases, and features included in each release for the Terraform support feature).
559+
560+
SAM CLI provides two ways of testing: local testing and testing on-cloud (Accelerate).
561+
562+
### Local Testing
563+
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)
564+
command, providing the function terraform address, or function name, and to set the `hook-package-id` to `terraform` to tell SAM CLI that the underlying project is a terraform application.
565+
566+
You can execute the `sam local invoke` command from your terraform application root directory as following:
567+
```
568+
sam local invoke --hook-package-id terraform module.hello_world_function.aws_lambda_function.this[0]
569+
```
570+
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.
571+
572+
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.
573+
574+
### Testing on-cloud (Accelerate)
575+
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,
576+
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,
577+
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.
578+
579+
You can execute the `sam sync` command from your terraform application root directory as following:
580+
```
581+
sam sync --hook-package-id terraform --watch
582+
```
583+
554584
## <a name="deployment"></a> How to deploy and manage Lambda Functions?
555585

556586
### Simple deployments
@@ -682,6 +712,8 @@ No modules.
682712
| [aws_s3_object.lambda_package](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
683713
| [local_file.archive_plan](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource |
684714
| [null_resource.archive](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
715+
| [null_resource.sam_metadata_aws_lambda_function](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
716+
| [null_resource.sam_metadata_aws_lambda_layer_version](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
685717
| [aws_arn.log_group_arn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
686718
| [aws_cloudwatch_log_group.lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudwatch_log_group) | data source |
687719
| [aws_iam_policy.tracing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source |

main.tf

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,59 @@ resource "aws_lambda_function_url" "this" {
326326
}
327327
}
328328
}
329+
330+
# This resource contains the extra information required by SAM CLI to provide the testing capabilities
331+
# to the TF application. The required data is where SAM CLI can find the Lambda function source code
332+
# and what are the resources that contain the building logic.
333+
resource "null_resource" "sam_metadata_aws_lambda_function" {
334+
count = local.create && var.create_package && var.create_function && !var.create_layer ? 1 : 0
335+
336+
triggers = {
337+
# This is a way to let SAM CLI correlates between the Lambda function resource, and this metadata
338+
# resource
339+
resource_name = "aws_lambda_function.this[0]"
340+
resource_type = "ZIP_LAMBDA_FUNCTION"
341+
342+
# The Lambda function source code.
343+
original_source_code = jsonencode(var.source_path)
344+
345+
# a property to let SAM CLI knows where to find the Lambda function source code if the provided
346+
# value for original_source_code attribute is map.
347+
source_code_property = "path"
348+
349+
# A property to let SAM CLI knows where to find the Lambda function built output
350+
built_output_path = data.external.archive_prepare[0].result.filename
351+
}
352+
353+
# SAM CLI can run terraform apply -target metadata resource, and this will apply the building
354+
# resources as well
355+
depends_on = [data.external.archive_prepare, null_resource.archive]
356+
}
357+
358+
# This resource contains the extra information required by SAM CLI to provide the testing capabilities
359+
# to the TF application. The required data is where SAM CLI can find the Lambda layer source code
360+
# and what are the resources that contain the building logic.
361+
resource "null_resource" "sam_metadata_aws_lambda_layer_version" {
362+
count = local.create && var.create_package && var.create_layer ? 1 : 0
363+
364+
triggers = {
365+
# This is a way to let SAM CLI correlates between the Lambda layer resource, and this metadata
366+
# resource
367+
resource_name = "aws_lambda_layer_version.this[0]"
368+
resource_type = "LAMBDA_LAYER"
369+
370+
# The Lambda layer source code.
371+
original_source_code = jsonencode(var.source_path)
372+
373+
# a property to let SAM CLI knows where to find the Lambda layer source code if the provided
374+
# value for original_source_code attribute is map.
375+
source_code_property = "path"
376+
377+
# A property to let SAM CLI knows where to find the Lambda layer built output
378+
built_output_path = data.external.archive_prepare[0].result.filename
379+
}
380+
381+
# SAM CLI can run terraform apply -target metadata resource, and this will apply the building
382+
# resources as well
383+
depends_on = [data.external.archive_prepare, null_resource.archive]
384+
}

modules/docker-build/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,15 @@ module "docker_image" {
5555
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
5656
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.22 |
5757
| <a name="requirement_docker"></a> [docker](#requirement\_docker) | >= 2.12 |
58+
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 2.0 |
5859

5960
## Providers
6061

6162
| Name | Version |
6263
|------|---------|
6364
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.22 |
6465
| <a name="provider_docker"></a> [docker](#provider\_docker) | >= 2.12 |
66+
| <a name="provider_null"></a> [null](#provider\_null) | >= 2.0 |
6567

6668
## Modules
6769

@@ -74,6 +76,7 @@ No modules.
7476
| [aws_ecr_lifecycle_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_lifecycle_policy) | resource |
7577
| [aws_ecr_repository.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecr_repository) | resource |
7678
| [docker_registry_image.this](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/registry_image) | resource |
79+
| [null_resource.sam_metadata_docker_registry_image](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
7780
| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
7881
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
7982

modules/docker-build/main.tf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,19 @@ resource "aws_ecr_lifecycle_policy" "this" {
4141
policy = var.ecr_repo_lifecycle_policy
4242
repository = local.ecr_repo
4343
}
44+
45+
# This resource contains the extra information required by SAM CLI to provide the testing capabilities
46+
# to the TF application. This resource will maintain the metadata information about the image type lambda
47+
# functions. It will contain the information required to build the docker image locally.
48+
resource "null_resource" "sam_metadata_docker_registry_image" {
49+
triggers = {
50+
resource_type = "IMAGE_LAMBDA_FUNCTION"
51+
docker_context = var.source_path
52+
docker_file = var.docker_file_path
53+
docker_build_args = jsonencode(var.build_args)
54+
docker_tag = var.image_tag
55+
built_image_uri = docker_registry_image.this.name
56+
}
57+
58+
depends_on = [docker_registry_image.this]
59+
}

modules/docker-build/versions.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@ terraform {
1010
source = "kreuzwerker/docker"
1111
version = ">= 2.12"
1212
}
13+
null = {
14+
source = "hashicorp/null"
15+
version = ">= 2.0"
16+
}
1317
}
1418
}

0 commit comments

Comments
 (0)