Moritzzimmer Terraform Aws Lambda Save

A Terraform module to create AWS Lambda ressources.

Project README

AWS Lambda Terraform module

Terraform Module Registry Terraform Version License: MIT

Terraform module to create AWS Lambda and accompanying resources for an efficient and secure development of Lambda functions like:

  • inline declaration of triggers for DynamodDb, EventBridge (CloudWatch Events), Kinesis, SNS or SQS including all required permissions
  • IAM role with permissions following the principle of least privilege
  • CloudWatch Logs and Lambda Insights configuration
  • blue/green deployments with AWS CodePipeline and CodeDeploy

Features

How do I use this module?

The module can be used for all runtimes supported by AWS Lambda.

Deployment packages can be specified either directly as a local file (using the filename argument), indirectly via Amazon S3 (using the s3_bucket, s3_key and s3_object_versions arguments) or using container images (using image_uri and package_type arguments), see documentation for details.

basic

see example for other configuration options

provider "aws" {
  region = "eu-west-1"
}

module "lambda" {
  source           = "moritzzimmer/lambda/aws"

  filename         = "my-package.zip"
  function_name    = "my-function"
  handler          = "my-handler"
  runtime          = "go1.x"
  source_code_hash = filebase64sha256("${path.module}/my-package.zip")
}

using container images

see example for details

module "lambda" {
  source        = "moritzzimmer/lambda/aws"

  function_name = "my-function"
  image_uri     = "111111111111.dkr.ecr.eu-west-1.amazonaws.com/my-image"
  package_type  = "Image"
}

with Amazon EventBridge (CloudWatch Events) rules

CloudWatch Event Rules to trigger your Lambda function by EventBridge patterns or on a regular, scheduled basis can be declared inline. The module will create the required Lambda permissions automatically.

see example for details

module "lambda" {
  // see above

  cloudwatch_event_rules = {
    scheduled = {
      schedule_expression = "rate(1 minute)"

      // optionally overwrite arguments like 'description'
      // from https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule
      description = "Triggered by CloudTrail"

      // optionally overwrite `cloudwatch_event_target_arn` in case an alias should be used for the event rule
      cloudwatch_event_target_arn = aws_lambda_alias.example.arn

      // optionally add `cloudwatch_event_target_input` for event input
      cloudwatch_event_target_input = jsonencode({"key": "value"})
    }

    pattern = {
      event_pattern = <<PATTERN
      {
        "detail-type": [
          "AWS Console Sign In via CloudTrail"
        ]
      }
      PATTERN
    }
  }
}

with event source mappings

Event Source Mappings to trigger your Lambda function by DynamoDb, Kinesis and SQS can be declared inline. The module will add the required read-only IAM permissions depending on the event source type to the function role automatically (including support for dedicated-throughput consumers using enhanced fan-out).

Permissions to send discarded batches to SNS or SQS will be added automatically, if destination_arn_on_failure is configured.

see examples for details

DynamoDb

module "lambda" {
  // see above

  event_source_mappings = {
    table_1 = {
      event_source_arn  = aws_dynamodb_table.table_1.stream_arn

      // optionally overwrite arguments like 'batch_size'
      // from https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_event_source_mapping
      batch_size        = 50
      starting_position = "LATEST"

      // optionally configure a SNS or SQS destination for discarded batches, required IAM
      // permissions will be added automatically by this module,
      // see https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventsourcemapping.html
      destination_arn_on_failure = aws_sqs_queue.errors.arn

      // optionally overwrite function_name in case an alias should be used in the
      // event source mapping, see https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html
      function_name = aws_lambda_alias.example.arn

      // Lambda event filtering, see https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html
      filter_criteria = [
        {
          pattern = jsonencode({
            data : {
              Key1 : ["Value1"]
            }
          })
        },
        {
          pattern = jsonencode({
            data : {
              Key2 : [{ "anything-but" : ["Value2"] }]
            }
          })
        }
      ]
    }

    table_2 = {
      event_source_arn = aws_dynamodb_table.table_2.stream_arn
    }
  }
}

Kinesis

resource "aws_kinesis_stream_consumer" "this" {
  name       = module.lambda.function_name
  stream_arn = aws_kinesis_stream.stream_2.arn
}

module "lambda" {
  // see above

  event_source_mappings = {
    stream_1 = {
      // To use a dedicated-throughput consumer with enhanced fan-out, specify the consumer's ARN instead of the stream's ARN, see https://docs.aws.amazon.com/lambda/latest/dg/with-kinesis.html#services-kinesis-configure
      event_source_arn = aws_kinesis_stream_consumer.this.arn
    }
  }
}

with SNS subscriptions

SNS Topic Subscriptions to trigger your Lambda function by SNS can de declared inline. The module will create the required Lambda permissions automatically.

see example for details

module "lambda" {
  // see above

  sns_subscriptions = {
    topic_1 = {
      topic_arn = aws_sns_topic.topic_1.arn

      // optionally overwrite `endpoint` in case an alias should be used for the SNS subscription
      endpoint  = aws_lambda_alias.example.arn
    }

    topic_2 = {
      topic_arn = aws_sns_topic.topic_2.arn
    }
  }
}

with access to AWS Systems Manager Parameter Store

Required IAM permissions to get parameter(s) from AWS Systems Manager Parameter Store (by path or name) can added to the Lambda role:

module "lambda" {
  // see above

  ssm = {
      parameter_names = [aws_ssm_parameter.string.name, aws_ssm_parameter.secure_string.name]
  }
}

with CloudWatch Logs configuration

The module will create a CloudWatch Log Group for your Lambda function. It's retention period and CloudWatch Logs subscription filters to stream logs to other Lambda functions (e.g. to forward logs to Amazon OpenSearch Service) can be declared inline.

The module will create the required Lambda permissions automatically. Sending logs to CloudWatch can be disabled with cloudwatch_logs_enabled = false

see example for details

module "lambda" {
  // see above

  // disable CloudWatch logs
  // cloudwatch_logs_enabled = false

  cloudwatch_logs_retention_in_days = 14

  cloudwatch_log_subscription_filters = {
    lambda_1 = {
      //see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_subscription_filter for available arguments
      destination_arn = module.destination_1.arn
    }

    lambda_2 = {
      destination_arn = module.destination_2.arn
    }
  }
}

with CloudWatch Lambda Insights

Amazon CloudWatch Lambda Insights can be enabled for zip and image function deployment packages of all runtimes supporting Lambda extensions.

This module will add the required IAM permissions to the function role automatically for both package types. In case of a zip deployment package, the region and architecture specific layer version needs to specified in layers.

module "lambda" {
  // see above

  cloudwatch_lambda_insights_enabled = true

  // see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html
  layers = "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:16"
}

For image deployment packages, the Lambda Insights extension needs to be added to the container image:

FROM public.ecr.aws/lambda/nodejs:12

RUN curl -O https://lambda-insights-extension.s3-ap-northeast-1.amazonaws.com/amazon_linux/lambda-insights-extension.rpm && \
    rpm -U lambda-insights-extension.rpm && \
    rm -f lambda-insights-extension.rpm

COPY index.js /var/task/

Deployments

Controlled, blue/green deployments of Lambda functions with (automatic) rollbacks and traffic shifting can be implemented using Lambda aliases and AWS CodeDeploy.

The deployment submodule can be used to create the required AWS CodePipeline, CodeBuild and CodeDeploy resources and permissions to execute secure deployments of S3 or containerized Lambda functions in your AWS account, see examples for details.

Examples

Bootstrap new projects

In case you are using go for developing your Lambda functions, you can also use func to bootstrap your project and get started quickly.

How do I contribute to this module?

Contributions are very welcome! Check out the Contribution Guidelines for instructions.

How is this module versioned?

This Module follows the principles of Semantic Versioning. You can find each new release in the releases page.

During initial development, the major version will be 0 (e.g., 0.x.y), which indicates the code does not yet have a stable API. Once we hit 1.0.0, we will make every effort to maintain a backwards compatible API and use the MAJOR, MINOR, and PATCH versions on each release to indicate any incompatibilities.

History

Implementation of this module started at Spring Media/Welt. Users of spring-media/lambda/aws should migrate to this module as a drop-in replacement to benefit from new features and bugfixes.

Requirements

Name Version
terraform >= 1.3
aws >= 5.0

Providers

Name Version
aws >= 5.0

Modules

No modules.

Resources

Name Type
aws_cloudwatch_event_rule.lambda resource
aws_cloudwatch_event_target.lambda resource
aws_cloudwatch_log_group.lambda resource
aws_cloudwatch_log_subscription_filter.cloudwatch_logs resource
aws_iam_policy.event_sources resource
aws_iam_policy.logs resource
aws_iam_policy.ssm resource
aws_iam_role.lambda resource
aws_iam_role_policy_attachment.cloudwatch_lambda_insights resource
aws_iam_role_policy_attachment.event_sources resource
aws_iam_role_policy_attachment.logs resource
aws_iam_role_policy_attachment.ssm resource
aws_iam_role_policy_attachment.tracing_attachment resource
aws_iam_role_policy_attachment.vpc_attachment resource
aws_lambda_event_source_mapping.event_source resource
aws_lambda_function.lambda resource
aws_lambda_function.lambda_external_lifecycle resource
aws_lambda_permission.cloudwatch_events resource
aws_lambda_permission.cloudwatch_logs resource
aws_lambda_permission.sns resource
aws_sns_topic_subscription.subscription resource
aws_caller_identity.current data source
aws_iam_policy_document.assume_role_policy data source
aws_iam_policy_document.event_sources data source
aws_iam_policy_document.logs data source
aws_iam_policy_document.ssm data source
aws_partition.current data source
aws_region.current data source

Inputs

Name Description Type Default Required
architectures Instruction set architecture for your Lambda function. Valid values are ["x86_64"] and ["arm64"]. Removing this attribute, function's architecture stay the same. list(string) null no
cloudwatch_event_rules Creates EventBridge (CloudWatch Events) rules invoking your Lambda function. Required Lambda invocation permissions will be generated. map(any) {} no
cloudwatch_lambda_insights_enabled Enable CloudWatch Lambda Insights for your Lambda function. bool false no
cloudwatch_log_subscription_filters CloudWatch Logs subscription filter resources. Currently supports only Lambda functions as destinations. map(any) {} no
cloudwatch_logs_enabled Enables your Lambda function to send logs to CloudWatch. The IAM role of this Lambda function will be enhanced with required permissions. bool true no
cloudwatch_logs_kms_key_id The ARN of the KMS Key to use when encrypting log data. string null no
cloudwatch_logs_retention_in_days Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653, and 0. If you select 0, the events in the log group are always retained and never expire. number null no
description Description of what your Lambda Function does. string "Instruction set architecture for your Lambda function. Valid values are [\"x86_64\"] and [\"arm64\"]." no
environment Environment (e.g. env variables) configuration for the Lambda function enable you to dynamically pass settings to your function code and libraries
object({
variables = map(string)
})
null no
ephemeral_storage_size The size of your Lambda functions ephemeral storage (/tmp) represented in MB. Valid value between 512 MB to 10240 MB. number 512 no
event_source_mappings Creates event source mappings to allow the Lambda function to get events from Kinesis, DynamoDB and SQS. The IAM role of this Lambda function will be enhanced with necessary minimum permissions to get those events. any {} no
filename The path to the function's deployment package within the local filesystem. If defined, The s3_-prefixed options and image_uri cannot be used. string null no
function_name A unique name for your Lambda Function. string n/a yes
handler The function entrypoint in your code. string "" no
iam_role_name Override the name of the IAM role for the function. Otherwise the default will be your function name with the region as a suffix. string null no
ignore_external_function_updates Ignore updates to your Lambda function executed externally to the Terraform lifecycle. Set this to true if you're using CodeDeploy, aws CLI or other external tools to update your Lambda function code. bool false no
image_config The Lambda OCI image configurations block with three (optional) arguments:

- entry_point - The ENTRYPOINT for the docker image (type list(string)).
- command - The CMD for the docker image (type list(string)).
- working_directory - The working directory for the docker image (type string).
any {} no
image_uri The ECR image URI containing the function's deployment package. Conflicts with filename, s3_bucket, s3_key, and s3_object_version. string null no
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
lambda_at_edge Enable Lambda@Edge for your Node.js or Python functions. Required trust relationship and publishing of function versions will be configured. bool false no
layers List of Lambda Layer Version ARNs (maximum of 5) to attach to your Lambda Function. list(string) [] no
memory_size Amount of memory in MB your Lambda Function can use at runtime. number 128 no
package_type The Lambda deployment package type. Valid values are Zip and Image. string "Zip" no
publish Whether to publish creation/change as new Lambda Function Version. bool false no
reserved_concurrent_executions The amount of reserved concurrent executions for this lambda function. A value of 0 disables lambda from being triggered and -1 removes any concurrency limitations. number -1 no
runtime The runtime environment for the Lambda function you are uploading. string "" no
s3_bucket The S3 bucket location containing the function's deployment package. Conflicts with filename and image_uri. This bucket must reside in the same AWS region where you are creating the Lambda function. string null no
s3_key The S3 key of an object containing the function's deployment package. Conflicts with filename and image_uri. string null no
s3_object_version The object version containing the function's deployment package. Conflicts with filename and image_uri. string null no
snap_start Enable snap start settings for low-latency startups. This feature is currently only supported for java11 and java17 runtimes and x86_64 architectures. bool false no
sns_subscriptions Creates subscriptions to SNS topics which trigger your Lambda function. Required Lambda invocation permissions will be generated. map(any) {} no
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
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.
object({
parameter_names = list(string)
})
null no
tags A mapping of tags to assign to the Lambda function and all resources supporting tags. map(string) {} no
timeout The amount of time your Lambda Function has to run in seconds. number 3 no
tracing_config_mode Tracing config mode of the Lambda function. Can be either PassThrough or Active. string null no
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).
object({
security_group_ids = list(string)
subnet_ids = list(string)
})
null no

Outputs

Name Description
arn The Amazon Resource Name (ARN) identifying your Lambda Function.
cloudwatch_log_group_arn The Amazon Resource Name (ARN) identifying the CloudWatch log group used by your Lambda function.
cloudwatch_log_group_name The name of the CloudWatch log group used by your Lambda function.
function_name The unique name of your Lambda Function.
invoke_arn The ARN to be used for invoking Lambda Function from API Gateway - to be used in aws_api_gateway_integration's uri
role_arn The ARN of the IAM role attached to the Lambda Function.
role_name The name of the IAM role attached to the Lambda Function.
version Latest published version of your Lambda Function.
Open Source Agenda is not affiliated with "Moritzzimmer Terraform Aws Lambda" Project. README Source: moritzzimmer/terraform-aws-lambda

Open Source Agenda Badge

Open Source Agenda Rating