Lambda@Edge Function Module
This module makes it easy to deploy and manage an AWS Lambda@Edge function. Lambda@Edge gives you a way to run code on-demand in AWS Edge locations without having to manage servers.
Lambda@Edge has the following limitations compared to regular Lambda (see the CloudFront Developer Guide for the full details):
- The functions must not have any environment variables.
- The execution timeout must not be higher than 30 seconds.
- The function must be versioned in order to be a target for Cloudfront events.
- The function must be deployed in the
us-east-1
region. - The function runtime must be one of:
nodejs18.x
or newerpython3.9
or newer
What is AWS Lambda?
AWS Lambda lets you run code without provisioning or managing servers. You define a function in a supported language (currently: Python, JavaScript, Java, and C#), upload the code to Lambda, specify how that function can be triggered, and then AWS Lambda takes care of all the details of deploying and scaling the infrastructure to run that code.
How do you add additional IAM policies and permissions?
By default, the lambda-edge
module configures your lambda function with an IAM role that allows it to write logs to
CloudWatch Logs. The ID of the IAM role is exported as the output iam_role_id
and the ID of the lambda function is
exported as the output function_arn
, so you can add custom rules using the aws_iam_role_policy
or
aws_lambda_permission
resources, respectively. For example, to allow your lambda function to be triggered by SNS:
module "my_lambda_function" {
source = "git::git@github.com:gruntwork-io/terraform-aws-lambda.git//modules/lambda-edge?ref=v1.0.8"
# (params omitted)
}
resource "aws_lambda_permission" "with_sns" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = "${module.my_lambda_function.function_arn}"
principal = "sns.amazonaws.com"
source_arn = "${aws_sns_topic.default.arn}"
}
How to get the logs of your function
Lambda@Edge stores CloudWatch Logs in the AWS Regions closest to the location where the function receives traffic and is
executed. That means a log group must be created in every region that have Regional Edge Caches.
Instructions on how to do this can be found at the lambda-edge-multi-region-log-groups
module. To see which regions are receiving traffic, you can find graphs of metrics for the
function on the CloudFront console and choose your region there.
How to trigger this Lambda function from Cloudfront
This module deploys the Lambda function but doesn't create any CloudFront trigger. There are two ways to create those triggers:
- Using terraform. To link the Lambda@Edge function to the s3-cloudfront module from terraform-aws-static-assets, you can use the default_lambda_associations input variable.
- Manually from the AWS Console as described in the Lambda@Edge documentation
Sample Usage
- Terraform
- Terragrunt
# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S LAMBDA-EDGE MODULE
# ------------------------------------------------------------------------------------------------------
module "lambda_edge" {
source = "git::git@github.com:gruntwork-io/terraform-aws-lambda.git//modules/lambda-edge?ref=v1.0.2"
# ----------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# ----------------------------------------------------------------------------------------------------
# The function entrypoint in your code. This is typically the name of a
# function or method in your code that AWS will execute when this Lambda
# function is triggered.
handler = <string>
# The maximum amount of memory, in MB, your Lambda function will be able to
# use at runtime. Can be set in 64MB increments from 128MB up to 1536MB. Note
# that the amount of CPU power given to a Lambda function is proportional to
# the amount of memory you request, so a Lambda function with 256MB of memory
# has twice as much CPU power as one with 128MB.
memory_size = <number>
# The name of the Lambda function. Used to namespace all resources created by
# this module.
name = <string>
# The maximum amount of time, in seconds, your Lambda function will be allowed
# to run. Must be between 1 and 30 seconds.
timeout = <number>
# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------
# The ID (ARN, alias ARN, AWS ID) of a customer managed KMS Key to use for
# encrypting log data.
cloudwatch_log_group_kms_key_id = null
# The number of days to retain log events in the log group. Refer to
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days
# for all the valid values. When null, the log events are retained forever.
cloudwatch_log_group_retention_in_days = null
# The ARN of the destination to deliver matching log events to. Kinesis stream
# or Lambda function ARN. Only applicable if var.log_regions is not empty.
cloudwatch_log_group_subscription_destination_arn = null
# The method used to distribute log data to the destination. Only applicable
# when var.cloudwatch_log_group_subscription_destination_arn is a kinesis
# stream. Valid values are `Random` and `ByLogStream`.
cloudwatch_log_group_subscription_distribution = null
# A valid CloudWatch Logs filter pattern for subscribing to a filtered stream
# of log events.
cloudwatch_log_group_subscription_filter_pattern = ""
# ARN of an IAM role that grants Amazon CloudWatch Logs permissions to deliver
# ingested log events to the destination. Only applicable when
# var.cloudwatch_log_group_subscription_destination_arn is a kinesis stream.
cloudwatch_log_group_subscription_role_arn = null
# Tags to apply on the CloudWatch Log Group, encoded as a map where the keys
# are tag keys and values are tag values.
cloudwatch_log_group_tags = {}
# The ARN of an SNS topic or an SQS queue to notify when invocation of a
# Lambda function fails. If this option is used, you must grant this
# function's IAM role (the ID is outputted as iam_role_id) access to write to
# the target object, which means allowing either the sns:Publish or
# sqs:SendMessage action on this ARN, depending on which service is targeted.
dead_letter_target_arn = null
# A description of what the Lambda function does.
description = null
# Set to true to enable versioning for this Lambda function. This allows you
# to use aliases to refer to execute different versions of the function in
# different environments. Note that an alternative way to run Lambda functions
# in multiple environments is to version your Terraform code. Only versioned
# lambdas can be the target of a CloudFront event trigger.
enable_versioning = true
# A map of environment variables to pass to the Lambda function. AWS will
# automatically encrypt these with KMS and decrypt them when running the
# function.
environment_variables = null
# A custom KMS key to use to encrypt and decrypt Lambda function environment
# variables. Leave it blank to use the default KMS key provided in your AWS
# account.
kms_key_arn = null
# The ARN of the policy that is used to set the permissions boundary for the
# IAM role for the Lambda function.
lambda_role_permissions_boundary_arn = null
# Regions in which to create log groups. If you completely disable one of
# these regions in your AWS account, you can not pass them here, but their
# respective providers still need to be passed to the lambda-edge module. The
# default is set to all regions that have a Regional Edge Cache.
log_regions = ["us-east-1","us-east-2","us-west-1","us-west-2","ap-south-1","ap-northeast-2","ap-southeast-1","ap-southeast-2","ap-northeast-1","eu-central-1","eu-west-1","eu-west-2","sa-east-1"]
# Advanced logging settings. Format can either be the default Text option or
# JSON. JSON allows for different log levels to be selected, not setting those
# attributes will use the AWS defaults. More information available at:
# https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html
logging_config = null
# The amount of reserved concurrent executions for this lambda function or -1
# if unreserved.
reserved_concurrent_executions = null
# The runtime environment for the Lambda function (e.g. nodejs, python3.9,
# java8). See
# https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime
# for all possible values. Currently Lambda@Edge supports only nodejs18.x and
# python3.9.
runtime = "nodejs18.x"
# An S3 bucket location containing the function's deployment package. Exactly
# one of var.source_path or the var.s3_xxx variables must be specified.
s3_bucket = null
# The path within var.s3_bucket where the deployment package is located.
# Exactly one of var.source_path or the var.s3_xxx variables must be
# specified.
s3_key = null
# The version of the path in var.s3_key to use as the deployment package.
# Exactly one of var.source_path or the var.s3_xxx variables must be
# specified.
s3_object_version = null
# If set to false, this function will no longer set the source_code_hash
# parameter, so this module will no longer detect and upload changes to the
# deployment package. This is primarily useful if you update the Lambda
# function from outside of this module (e.g., you have scripts that do it
# separately) and want to avoid a plan diff. Used only if var.source_path is
# non-empty.
set_source_code_hash = true
# (Optional) Set to true if you do not wish the log group to be deleted at
# destroy time, and instead just remove the log group from the Terraform
# state. Defaults to `false`.
skip_destroy = false
# Set to true to skip zip archive creation and assume that var.source_path
# points to a pregenerated zip archive.
skip_zip = false
# The path to the directory that contains your Lambda function source code.
# This code will be zipped up and uploaded to Lambda as your deployment
# package. If var.skip_zip is set to true, then this is assumed to be the path
# to an already-zipped file, and it will be uploaded directly to Lambda as a
# deployment package. Exactly one of var.source_path or the var.s3_xxx
# variables must be specified.
source_path = null
# A map of tags to apply to the Lambda function.
tags = {}
# Whether to sample and trace a subset of incoming requests with AWS X-Ray.
# Valid values are PassThrough and Active.
tracing_config_mode = null
# When true, all IAM policies will be managed as dedicated policies rather
# than inline policies attached to the IAM roles. Dedicated managed policies
# are friendlier to automated policy checkers, which may scan a single
# resource for findings. As such, it is important to avoid inline policies
# when targeting compliance with various security standards.
use_managed_iam_policies = true
# Files in var.source_path to ignore when zipping the directory in addition to
# .terragrunt-source-manifest.
zip_exclude_files = []
# The path to store the output zip file of your source code. If empty,
# defaults to module path. This should be the full path to the zip file, not a
# directory.
zip_output_path = null
}
# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S LAMBDA-EDGE MODULE
# ------------------------------------------------------------------------------------------------------
terraform {
source = "git::git@github.com:gruntwork-io/terraform-aws-lambda.git//modules/lambda-edge?ref=v1.0.2"
}
inputs = {
# ----------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# ----------------------------------------------------------------------------------------------------
# The function entrypoint in your code. This is typically the name of a
# function or method in your code that AWS will execute when this Lambda
# function is triggered.
handler = <string>
# The maximum amount of memory, in MB, your Lambda function will be able to
# use at runtime. Can be set in 64MB increments from 128MB up to 1536MB. Note
# that the amount of CPU power given to a Lambda function is proportional to
# the amount of memory you request, so a Lambda function with 256MB of memory
# has twice as much CPU power as one with 128MB.
memory_size = <number>
# The name of the Lambda function. Used to namespace all resources created by
# this module.
name = <string>
# The maximum amount of time, in seconds, your Lambda function will be allowed
# to run. Must be between 1 and 30 seconds.
timeout = <number>
# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------
# The ID (ARN, alias ARN, AWS ID) of a customer managed KMS Key to use for
# encrypting log data.
cloudwatch_log_group_kms_key_id = null
# The number of days to retain log events in the log group. Refer to
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days
# for all the valid values. When null, the log events are retained forever.
cloudwatch_log_group_retention_in_days = null
# The ARN of the destination to deliver matching log events to. Kinesis stream
# or Lambda function ARN. Only applicable if var.log_regions is not empty.
cloudwatch_log_group_subscription_destination_arn = null
# The method used to distribute log data to the destination. Only applicable
# when var.cloudwatch_log_group_subscription_destination_arn is a kinesis
# stream. Valid values are `Random` and `ByLogStream`.
cloudwatch_log_group_subscription_distribution = null
# A valid CloudWatch Logs filter pattern for subscribing to a filtered stream
# of log events.
cloudwatch_log_group_subscription_filter_pattern = ""
# ARN of an IAM role that grants Amazon CloudWatch Logs permissions to deliver
# ingested log events to the destination. Only applicable when
# var.cloudwatch_log_group_subscription_destination_arn is a kinesis stream.
cloudwatch_log_group_subscription_role_arn = null
# Tags to apply on the CloudWatch Log Group, encoded as a map where the keys
# are tag keys and values are tag values.
cloudwatch_log_group_tags = {}
# The ARN of an SNS topic or an SQS queue to notify when invocation of a
# Lambda function fails. If this option is used, you must grant this
# function's IAM role (the ID is outputted as iam_role_id) access to write to
# the target object, which means allowing either the sns:Publish or
# sqs:SendMessage action on this ARN, depending on which service is targeted.
dead_letter_target_arn = null
# A description of what the Lambda function does.
description = null
# Set to true to enable versioning for this Lambda function. This allows you
# to use aliases to refer to execute different versions of the function in
# different environments. Note that an alternative way to run Lambda functions
# in multiple environments is to version your Terraform code. Only versioned
# lambdas can be the target of a CloudFront event trigger.
enable_versioning = true
# A map of environment variables to pass to the Lambda function. AWS will
# automatically encrypt these with KMS and decrypt them when running the
# function.
environment_variables = null
# A custom KMS key to use to encrypt and decrypt Lambda function environment
# variables. Leave it blank to use the default KMS key provided in your AWS
# account.
kms_key_arn = null
# The ARN of the policy that is used to set the permissions boundary for the
# IAM role for the Lambda function.
lambda_role_permissions_boundary_arn = null
# Regions in which to create log groups. If you completely disable one of
# these regions in your AWS account, you can not pass them here, but their
# respective providers still need to be passed to the lambda-edge module. The
# default is set to all regions that have a Regional Edge Cache.
log_regions = ["us-east-1","us-east-2","us-west-1","us-west-2","ap-south-1","ap-northeast-2","ap-southeast-1","ap-southeast-2","ap-northeast-1","eu-central-1","eu-west-1","eu-west-2","sa-east-1"]
# Advanced logging settings. Format can either be the default Text option or
# JSON. JSON allows for different log levels to be selected, not setting those
# attributes will use the AWS defaults. More information available at:
# https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html
logging_config = null
# The amount of reserved concurrent executions for this lambda function or -1
# if unreserved.
reserved_concurrent_executions = null
# The runtime environment for the Lambda function (e.g. nodejs, python3.9,
# java8). See
# https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime
# for all possible values. Currently Lambda@Edge supports only nodejs18.x and
# python3.9.
runtime = "nodejs18.x"
# An S3 bucket location containing the function's deployment package. Exactly
# one of var.source_path or the var.s3_xxx variables must be specified.
s3_bucket = null
# The path within var.s3_bucket where the deployment package is located.
# Exactly one of var.source_path or the var.s3_xxx variables must be
# specified.
s3_key = null
# The version of the path in var.s3_key to use as the deployment package.
# Exactly one of var.source_path or the var.s3_xxx variables must be
# specified.
s3_object_version = null
# If set to false, this function will no longer set the source_code_hash
# parameter, so this module will no longer detect and upload changes to the
# deployment package. This is primarily useful if you update the Lambda
# function from outside of this module (e.g., you have scripts that do it
# separately) and want to avoid a plan diff. Used only if var.source_path is
# non-empty.
set_source_code_hash = true
# (Optional) Set to true if you do not wish the log group to be deleted at
# destroy time, and instead just remove the log group from the Terraform
# state. Defaults to `false`.
skip_destroy = false
# Set to true to skip zip archive creation and assume that var.source_path
# points to a pregenerated zip archive.
skip_zip = false
# The path to the directory that contains your Lambda function source code.
# This code will be zipped up and uploaded to Lambda as your deployment
# package. If var.skip_zip is set to true, then this is assumed to be the path
# to an already-zipped file, and it will be uploaded directly to Lambda as a
# deployment package. Exactly one of var.source_path or the var.s3_xxx
# variables must be specified.
source_path = null
# A map of tags to apply to the Lambda function.
tags = {}
# Whether to sample and trace a subset of incoming requests with AWS X-Ray.
# Valid values are PassThrough and Active.
tracing_config_mode = null
# When true, all IAM policies will be managed as dedicated policies rather
# than inline policies attached to the IAM roles. Dedicated managed policies
# are friendlier to automated policy checkers, which may scan a single
# resource for findings. As such, it is important to avoid inline policies
# when targeting compliance with various security standards.
use_managed_iam_policies = true
# Files in var.source_path to ignore when zipping the directory in addition to
# .terragrunt-source-manifest.
zip_exclude_files = []
# The path to store the output zip file of your source code. If empty,
# defaults to module path. This should be the full path to the zip file, not a
# directory.
zip_output_path = null
}
Reference
- Inputs
- Outputs
Required
handler
stringThe function entrypoint in your code. This is typically the name of a function or method in your code that AWS will execute when this Lambda function is triggered.
memory_size
numberThe maximum amount of memory, in MB, your Lambda function will be able to use at runtime. Can be set in 64MB increments from 128MB up to 1536MB. Note that the amount of CPU power given to a Lambda function is proportional to the amount of memory you request, so a Lambda function with 256MB of memory has twice as much CPU power as one with 128MB.
name
stringThe name of the Lambda function. Used to namespace all resources created by this module.
timeout
numberThe maximum amount of time, in seconds, your Lambda function will be allowed to run. Must be between 1 and 30 seconds.
Optional
The ID (ARN, alias ARN, AWS ID) of a customer managed KMS Key to use for encrypting log data.
null
The number of days to retain log events in the log group. Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days for all the valid values. When null, the log events are retained forever.
null
The ARN of the destination to deliver matching log events to. Kinesis stream or Lambda function ARN. Only applicable if log_regions
is not empty.
null
The method used to distribute log data to the destination. Only applicable when cloudwatch_log_group_subscription_destination_arn
is a kinesis stream. Valid values are Random
and ByLogStream
.
null
A valid CloudWatch Logs filter pattern for subscribing to a filtered stream of log events.
""
ARN of an IAM role that grants Amazon CloudWatch Logs permissions to deliver ingested log events to the destination. Only applicable when cloudwatch_log_group_subscription_destination_arn
is a kinesis stream.
null
cloudwatch_log_group_tags
map(string)Tags to apply on the CloudWatch Log Group, encoded as a map where the keys are tag keys and values are tag values.
{}
The ARN of an SNS topic or an SQS queue to notify when invocation of a Lambda function fails. If this option is used, you must grant this function's IAM role (the ID is outputted as iam_role_id) access to write to the target object, which means allowing either the sns:Publish or sqs:SendMessage action on this ARN, depending on which service is targeted.
null
description
stringA description of what the Lambda function does.
null
Set to true to enable versioning for this Lambda function. This allows you to use aliases to refer to execute different versions of the function in different environments. Note that an alternative way to run Lambda functions in multiple environments is to version your Terraform code. Only versioned lambdas can be the target of a CloudFront event trigger.
true
environment_variables
map(string)A map of environment variables to pass to the Lambda function. AWS will automatically encrypt these with KMS and decrypt them when running the function.
null
kms_key_arn
stringA custom KMS key to use to encrypt and decrypt Lambda function environment variables. Leave it blank to use the default KMS key provided in your AWS account.
null
The ARN of the policy that is used to set the permissions boundary for the IAM role for the Lambda function.
null
log_regions
list(any)Regions in which to create log groups. If you completely disable one of these regions in your AWS account, you can not pass them here, but their respective providers still need to be passed to the lambda-edge module. The default is set to all regions that have a Regional Edge Cache.
Any types represent complex values of variable type. For details, please consult `variables.tf` in the source repo.
[
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2",
"ap-south-1",
"ap-northeast-2",
"ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
"sa-east-1"
]
Details
Regions that have Regional Edge Caches
More info: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html
logging_config
object(…)Advanced logging settings. Format can either be the default Text option or JSON. JSON allows for different log levels to be selected, not setting those attributes will use the AWS defaults. More information available at: https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html
object({
log_format = optional(string, "Text")
application_log_level = optional(string)
system_log_level = optional(string)
})
null
The amount of reserved concurrent executions for this lambda function or -1 if unreserved.
null
runtime
stringThe runtime environment for the Lambda function (e.g. nodejs, python3.9, java8). See https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime for all possible values. Currently Lambda@Edge supports only nodejs18.x and python3.9.
"nodejs18.x"
s3_bucket
stringAn S3 bucket location containing the function's deployment package. Exactly one of source_path
or the s3_xxx
variables must be specified.
null
s3_key
stringThe path within s3_bucket
where the deployment package is located. Exactly one of source_path
or the s3_xxx
variables must be specified.
null
s3_object_version
stringThe version of the path in s3_key
to use as the deployment package. Exactly one of source_path
or the s3_xxx
variables must be specified.
null
If set to false, this function will no longer set the source_code_hash parameter, so this module will no longer detect and upload changes to the deployment package. This is primarily useful if you update the Lambda function from outside of this module (e.g., you have scripts that do it separately) and want to avoid a plan diff. Used only if source_path
is non-empty.
true
skip_destroy
bool(Optional) Set to true if you do not wish the log group to be deleted at destroy time, and instead just remove the log group from the Terraform state. Defaults to false
.
false
skip_zip
boolSet to true to skip zip archive creation and assume that source_path
points to a pregenerated zip archive.
false
source_path
stringThe path to the directory that contains your Lambda function source code. This code will be zipped up and uploaded to Lambda as your deployment package. If skip_zip
is set to true, then this is assumed to be the path to an already-zipped file, and it will be uploaded directly to Lambda as a deployment package. Exactly one of source_path
or the s3_xxx
variables must be specified.
null
tags
map(string)A map of tags to apply to the Lambda function.
{}
tracing_config_mode
stringWhether to sample and trace a subset of incoming requests with AWS X-Ray. Valid values are PassThrough and Active.
null
When true, all IAM policies will be managed as dedicated policies rather than inline policies attached to the IAM roles. Dedicated managed policies are friendlier to automated policy checkers, which may scan a single resource for findings. As such, it is important to avoid inline policies when targeting compliance with various security standards.
true
zip_exclude_files
list(string)Files in source_path
to ignore when zipping the directory in addition to .terragrunt-source-manifest.
[]
zip_output_path
stringThe path to store the output zip file of your source code. If empty, defaults to module path. This should be the full path to the zip file, not a directory.
null
Name of the (optionally) created CloudWatch log groups for the lambda function.