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: Add SAM Metadata resources to enable the integration with SAM CLI tool #325

Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This Terraform module is the part of [serverless.tf framework](https://github.co
3. Create, update, and publish AWS Lambda Function and Lambda Layer - [see usage](#usage).
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).
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).
6. Use AWS SAM CLI to test Lambda Function - [read more](#sam_cli_integration).

## Features

Expand Down Expand Up @@ -530,6 +531,35 @@ 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
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)
to be updated about the incoming releases, and features included in each release for the Terraform support feature).

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-package-id` 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-package-id 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,
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-package-id terraform --watch
```

## <a name="deployment"></a> How to deploy and manage Lambda Functions?

### Simple deployments
Expand Down Expand Up @@ -661,6 +691,8 @@ No modules.
| [aws_s3_object.lambda_package](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
| [local_file.archive_plan](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource |
| [null_resource.archive](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [null_resource.sam_metadata_aws_lambda_function_this](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [null_resource.sam_metadata_aws_lambda_layer_version_this](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [aws_arn.log_group_arn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
| [aws_cloudwatch_log_group.lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudwatch_log_group) | data source |
| [aws_iam_policy.tracing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source |
Expand Down
56 changes: 56 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,59 @@ resource "aws_lambda_function_url" "this" {
}
}
}

# This resource contains the extra information required by SAM CLI to provide the testing capabilities
# to the TF application. The required data is where SAM CLI can find the Lambda function source code
# and what are the resources that contain the building logic.
resource "null_resource" "sam_metadata_aws_lambda_function_this" {
count = local.create && var.create_package && var.create_function && !var.create_layer ? 1 : 0

triggers = {
# This is a way to let SAM CLI correlates between the Lambda function resource, and this metadata
# resource
resource_name = "aws_lambda_function.this[0]"
resource_type = "ZIP_LAMBDA_FUNCTION"

# The Lambda function source code.
original_source_code = jsonencode(var.source_path)

# a property to let SAM CLI knows where to find the Lambda function source code if the provided
# value for original_source_code attribute is map.
source_code_property = "path"

# A property to let SAM CLI knows where to find the Lambda function built output
built_output_path = data.external.archive_prepare[0].result.filename
}

# SAM CLI can run terraform apply -target metadata resource, and this will apply the building
# resources as well
depends_on = [data.external.archive_prepare, null_resource.archive]
}

# This resource contains the extra information required by SAM CLI to provide the testing capabilities
# to the TF application. The required data is where SAM CLI can find the Lambda layer source code
# and what are the resources that contain the building logic.
resource "null_resource" "sam_metadata_aws_lambda_layer_version_this" {
count = local.create && var.create_package && var.create_layer ? 1 : 0

triggers = {
# This is a way to let SAM CLI correlates between the Lambda layer resource, and this metadata
# resource
resource_name = "aws_lambda_layer_version.this[0]"
resource_type = "LAMBDA_LAYER"

# The Lambda layer source code.
original_source_code = jsonencode(var.source_path)

# a property to let SAM CLI knows where to find the Lambda layer source code if the provided
# value for original_source_code attribute is map.
source_code_property = "path"

# A property to let SAM CLI knows where to find the Lambda layer built output
built_output_path = data.external.archive_prepare[0].result.filename
}

# SAM CLI can run terraform apply -target metadata resource, and this will apply the building
# resources as well
depends_on = [data.external.archive_prepare, null_resource.archive]
}
3 changes: 3 additions & 0 deletions modules/docker-build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ module "docker_image" {
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.22 |
| <a name="requirement_docker"></a> [docker](#requirement\_docker) | >= 2.12 |
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 2.0 |

## Providers

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

## Modules

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

Expand Down
16 changes: 16 additions & 0 deletions modules/docker-build/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,19 @@ resource "aws_ecr_lifecycle_policy" "this" {
policy = var.ecr_repo_lifecycle_policy
repository = local.ecr_repo
}

# This resource contains the extra information required by SAM CLI to provide the testing capabilities
# to the TF application. This resource will maintain the metadata information about the image type lambda
# functions. It will contain the information required to build the docker image locally.
resource "null_resource" "sam_metadata_docker_registry_image_this" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we drop _this from the name in resources?

triggers = {
resource_type = "IMAGE_LAMBDA_FUNCTION"
docker_context = var.source_path
docker_file = var.docker_file_path
docker_build_args = jsonencode(var.build_args)
docker_tag = var.image_tag
built_image_uri = docker_registry_image.this.name
}

depends_on = [docker_registry_image.this]
}
4 changes: 4 additions & 0 deletions modules/docker-build/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ terraform {
source = "kreuzwerker/docker"
version = ">= 2.12"
}
null = {
source = "hashicorp/null"
version = ">= 2.0"
}
}
}