Register Lambda Functions

You can either manually register AWS Lambda functions with Consul or use the Lambda registrator to automatically synchronize Lambda state into Consul.

To manually register AWS Lambda functions into Consul, you must register a service into Consul and then write a service defaults configuration entry for the Lambda.

The registrator automatically registers, reconfigures, and deregisters Lambdas based on the Lambda function’s tags (refer to the AWS tag configuration documentation for details about tags).

We recommend using the Lambda registrator when possible so that you can keep the configuration entry up to date.

Requirements

  • Consul 1.12.1 and later

Prerequisites

Complete the following prerequisites prior to registering your Lambda functions. You only need to perform these steps once.

Enable the Serverless Plugin

Add the following configuration to all Consul clients:

connect { enable_serverless_plugin = true, connect = true }

Refer to the enable_serverless_plugin configuration documentation for additional information.

Configure IAM Permissions for Envoy

The Envoy proxy that invokes Lambda must have the lambda:InvokeFunction AWS IAM permissions. In the following example, the IAM policy enables an IAM user or role to invoke the example Lambda function:

  1. {
  2. "Version": "2012-10-17",
  3. "Statement": [
  4. {
  5. "Sid": "Invoke",
  6. "Effect": "Allow",
  7. "Action": [
  8. "lambda:InvokeFunction"
  9. ],
  10. "Resource": "arn:aws:lambda:us-east-1:123456789012:function:example"
  11. }
  12. ]
  13. }
  1. {
  2. "Version": "2012-10-17",
  3. "Statement": [
  4. {
  5. "Sid": "Invoke",
  6. "Effect": "Allow",
  7. "Action": [
  8. "lambda:InvokeFunction"
  9. ],
  10. "Resource": "arn:aws:lambda:us-east-1:123456789012:function:example"
  11. }
  12. ]
  13. }

Define AWS IAM credentials in environment variables, EC2 metadata or ECS metadata. On AWS EKS, associate an IAM role with the proxy’s ServiceAccount. Refer to the AWS IAM roles for service accounts documentation for instructions.

Optional: Set up a Terminating Gateway

If you intend to invoke Lambda services through a terminating gateway, the gateway must be registered and running in the Consul datacenter. Refer to the following documentation and tutorials for instructions on how to set up a terminating gateway:

To register a Lambda service with a terminating gateway, add the service to the Services field of the terminating gateway’s terminating-gateway configuration entry.

Optional: Run a Mesh Gateway

You can set up a mesh gateway so that you can invoke Lambda services across datacenters and admin partitions. The mesh gateway must be running and registered in the relevant Consul datacenters and partitions. Refer to the following documentation and tutorials for instructions on how to set up mesh gateways:

When using admin partitions, you must add Lambda services to the Services field of the exported-services configuration entry.

Automatic Lambda Function Registration

You can deploy the Lambda registrator to your environment to automatically register and deregister Lambda functions with Consul based on the function’s tags. Refer to the AWS Lambda tags documentation to learn about tags.

The registrator runs as a Lambda function that is invoked by AWS EventBridge. Refer to the AWS EventBridge documentation for additional information.

EventBridge invokes the registrator using either AWS CloudTrail to syncronize with Consul in real-time or in scheduled intervals.

CloudTrail events typically synchronize updates, registration, and deregistration within one minute, but events may occasionally be delayed.

Scheduled events fully synchronize functions betwen Lambda and Consul to prevent entropy. By default, EventBridge triggers a full sync every five minutes.

The following diagram shows the flow of events from EventBridge into Consul:

Lambda Registrator Architecture

  1. EventBridge invokes the Lambda registrator based on CloudTrail Lambda events or a schedule.
  2. Lambda registrator determines how to reconcile Lambda’s control plane state with Consul state and ensures they are in sync by registering, updating, and deregistering Lambda services.

Deploy Lambda Registrator

  1. Create a Terraform configuration and specify the lambda-registrator module. In the following example, the Lambda registrator is deployed to https://consul.example.com:8501. Refer to the Lambda registrator module documentation for additional usage information:

    1. module "lambda-registrator" {
    2. source = "hashicorp/consul-lambda-registrator/aws//modules/lambda-registrator"
    3. name = "consul-lambda-registrator"
    4. consul_http_addr = "https://consul.example.com:8501"
    5. ca_cert_path = aws_ssm_parameter.ca-cert.name
    6. http_token_path = aws_ssm_parameter.acl-token.name
    7. }
    1. module "lambda-registrator" {
    2. source = "hashicorp/consul-lambda-registrator/aws//modules/lambda-registrator"
    3. name = "consul-lambda-registrator"
    4. consul_http_addr = "https://consul.example.com:8501"
    5. ca_cert_path = aws_ssm_parameter.ca-cert.name
    6. http_token_path = aws_ssm_parameter.acl-token.name
    7. }
  2. Deploy Lambda registrator with terraform apply.

Optional: Store the CA Certificate in Parameter Store

When Lambda registrator makes a request to Consul’s HTTP API over HTTPS and the Consul API is signed by a custom CA, Lambda registrator uses the CA certificate stored in AWS Parameter Store (refer to the Parameter Store documentation for additional information) to verify the authenticity of the Consul API. You can apply the following Terraform configuration to store Consul’s server CA in Parameter Store:

  1. resource "aws_ssm_parameter" "ca-cert" {
  2. name = "/lambda-registrator/ca-cert"
  3. type = "SecureString"
  4. value = <VALUE>
  5. }
  1. resource "aws_ssm_parameter" "ca-cert" {
  2. name = "/lambda-registrator/ca-cert"
  3. type = "SecureString"
  4. value = <VALUE>
  5. }

Optional: Store the ACL Token in Parameter Store

If Consul access control lists (ACLs) are enabled, Lambda registrator must present an ACL token stored in Parameter Store to access resources. You can use the Consul CLI, API, or the Terraform provider to facilitate the ACL workflow. The following procedure describes how to create and store a token from the command line:

  1. Create an ACL policy that includes the following rule:

    1. service_prefix "" {
    2. policy = "write"
    3. }

    Register Lambda Functions - 图2

    rules.hcl

    1. service_prefix "" {
    2. policy = "write"
    3. }
  2. Issue consul acl policy create command to create the policy. The following example creates a policy called lambda-registrator-policy containing permissions specified in rules.hcl:

    1. $ consul acl policy create -name "lambda-registrator-policy" -rules @rules.hcl
    1. $ consul acl policy create -name "lambda-registrator-policy" -rules @rules.hcl
  3. Issue the consul acl token create command to create the token. The following example creates a token linked to the lambda-registrator-policy policy:

    1. $ consul acl token create -policy-name "lambda-registrator-policy"
    1. $ consul acl token create -policy-name "lambda-registrator-policy"
  4. Store the token in Parameter Store by applying the following Terraform:

    1. resource "aws_ssm_parameter" "acl-token" {
    2. name = "/lambda-registrator/acl-token"
    3. type = "SecureString"
    4. value = <VALUE>
    5. }
    1. resource "aws_ssm_parameter" "acl-token" {
    2. name = "/lambda-registrator/acl-token"
    3. type = "SecureString"
    4. value = <VALUE>
    5. }

Lambda Registrator Configuration Options

NameDescription
nameSpecifies the name name of the Lambda function associated with the Lambda registrator. The name is also used to construct the Identity and Access Management (IAM) role and policy names used by the Lambda function.
schedule_frequency_in_minutesSpecifies the interval in minutes that EventBridge uses to trigger a full synchronization. Default is 5.
timeoutThe maximum number of seconds Lambda registrator can run per invocation before timing out.
consul_http_addrSpecifies the address of the Consul API client.
consul_ca_cert_pathSpecifies the path to the CA certificate stored in the AWS Parameter Store. When Lambda registrator makes an HTTPS request to Consul’s API and the Consul API is signed by a custom CA, Lambda registrator uses this CA certificate to verify the authenticity of the Consul API. At startup, Lambda registrator pulls the CA certificate at this path from Parameter Store, writes the certificate to the filesystem and stores the path of that file in CONSUL_CACERT. Also see Optional: Store the CA Certificate in Parameter Store
consul_http_token_pathSpecifies the path to the ACL token stored in AWS Parameter Store that Lambda registrator presents to access resources. This parameter only required when ACLs are enabled for the Consul server. It is used to fetch an ACL token from Parameter Store and is stored in the CONSUL_HTTP_TOKEN environment variable. Also see Optional: Store the ACL Token in Parameter Store
node_nameThe Consul node name that Lambdas will be registered to. This defaults to lambdas.
enterprise
Enterprise
Determines if the Consul server at consul_http_addr is running open source or enterprise.
partitions
Enterprise
The partitions that Lambda registrator manages.

Register Lambda Functions

Lambda registrator registers Lambda functions into Consul, regardless of how the functions are deployed. The following procedure describes how to register Lambda functions with the Lambda registrator using Terraform, but you can also deploy a Lambda function with CloudFormation, the AWS user interface, or Cloud Development Kit (CDK):

  1. Add the aws_lambda_function resource to your Terraform configuration and specify the name of the Lambda function.
  2. Add a tags block to the resource and specify the tags you want to use to register the function (refer to Supported Tags).

In the following example, the example Lambda function is registered using the enabled, payload-passthrough, and invocation-mode tags:

  1. resource "aws_lambda_function" "example" {
  2. function_name = "lambda"
  3. tags = {
  4. "serverless.consul.hashicorp.com/v1alpha1/lambda/enabled" = "true"
  5. "serverless.consul.hashicorp.com/alpha/lambda/payload-passthrough" = "true"
  6. "serverless.consul.hashicorp.com/alpha/lambda/invocation-mode" = "ASYNCHRONOUS"
  7. }
  8. }
  1. resource "aws_lambda_function" "example" {
  2. function_name = "lambda"
  3. tags = {
  4. "serverless.consul.hashicorp.com/v1alpha1/lambda/enabled" = "true"
  5. "serverless.consul.hashicorp.com/alpha/lambda/payload-passthrough" = "true"
  6. "serverless.consul.hashicorp.com/alpha/lambda/invocation-mode" = "ASYNCHRONOUS"
  7. }
  8. }

Supported Tags

The following tags are supported. In all cases, the <PREFIX> should be serverless.consul.hashicorp.com/v1alpha1/lambda. For example, serverless.consul.hashicorp.com/v1alpha1/lambda/enabled.

TagDescription
<PREFIX>/enabledDetermines if Lambda registrator will sync the Lambda into Consul.
<PREFIX>/payload-passthroughDetermines if the body Envoy receives is converted to JSON or directly passed to Lambda. This attribute is optional and defaults to false.
<PREFIX>/invocation-modeSpecifies the Lambda invocation mode Consul uses to invoke the Lambda. The default is SYNCHRONOUS, but ASYNCHRONOUS invocations are also supported.
<PREFIX>/namespace
Enterprise
Specifies the Consul namespace the service will be registered in. Default is default if enterprise is enabled.
<PREFIX>/partition
Enterprise
Specifies the Consul partition the service will be registered in. Defaults is default if enterprise is enabled.
<PREFIX>/aliasesSpecifies a +-separated string of Lambda aliases that will be registered into Consul. For example, if set to dev+staging+prod, the dev, staging, and prod aliases of the Lambda function will be registered into Consul.

Manual Configuration

You can manually register Lambda functions if you are unable to automate the process using the Lambda registrator.

  1. Create a configuration for registering the service. You can copy the following example and replace <SERVICE_NAME> with your Consul service name for the Lambda function:

    1. {
    2. "Node": "lambdas",
    3. "SkipNodeUpdate": true,
    4. "NodeMeta": {
    5. "external-node": "true",
    6. "external-probe": "true"
    7. },
    8. "Service": {
    9. "Service": "<SERVICE_NAME>"
    10. }
    11. }

    Register Lambda Functions - 图3

    lambda.json

    1. {
    2. "Node": "lambdas",
    3. "SkipNodeUpdate": true,
    4. "NodeMeta": {
    5. "external-node": "true",
    6. "external-probe": "true"
    7. },
    8. "Service": {
    9. "Service": "<SERVICE_NAME>"
    10. }
    11. }
  2. Save the configuration to lambda.json.

  3. Send the configuration to the catalog/register API endpoint to register the service, for example:

    1. $ curl --request PUT --data @lambda.json localhost:8500/v1/catalog/register
    1. $ curl --request PUT --data @lambda.json localhost:8500/v1/catalog/register
  4. Create the service-defaults configuration entry and include the AWS tags used to invoke the Lambda function in the Meta field (see Supported Meta Fields. The following example creates a service-defaults configuration entry named lambda:

    1. Kind = "service-defaults"
    2. Name = "lambda"
    3. Protocol = "http"
    4. Meta = {
    5. "serverless.consul.hashicorp.com/v1alpha1/lambda/enabled" = "true"
    6. "serverless.consul.hashicorp.com/v1alpha1/lambda/arn" = "<INSERT ARN HERE>"
    7. "serverless.consul.hashicorp.com/v1alpha1/lambda/payload-passthrough" = "true"
    8. "serverless.consul.hashicorp.com/v1alpha1/lambda/region" = "us-east-2"
    9. }

    Register Lambda Functions - 图4

    lambda-service-defaults.hcl

    1. Kind = "service-defaults"
    2. Name = "lambda"
    3. Protocol = "http"
    4. Meta = {
    5. "serverless.consul.hashicorp.com/v1alpha1/lambda/enabled" = "true"
    6. "serverless.consul.hashicorp.com/v1alpha1/lambda/arn" = "<INSERT ARN HERE>"
    7. "serverless.consul.hashicorp.com/v1alpha1/lambda/payload-passthrough" = "true"
    8. "serverless.consul.hashicorp.com/v1alpha1/lambda/region" = "us-east-2"
    9. }
  5. Issue the consul config write command to store the configuration entry. For example:

    1. $ consul config write lambda-service-defaults.hcl
    1. $ consul config write lambda-service-defaults.hcl

Supported Meta Fields

The following tags are supported. In all cases, the <PREFIX> should be serverless.consul.hashicorp.com/v1alpha1/lambda. For example, serverless.consul.hashicorp.com/v1alpha1/lambda/enabled.

TagDescription
<PREFIX>/enabledDetermines if Consul configures the service as an AWS Lambda.
<PREFIX>/payload-passthroughDetermines if the body Envoy receives is converted to JSON or directly passed to Lambda.
<PREFIX>/arnSpecifies the AWS ARN for the service’s Lambda.
<PREFIX>/invocation-modeDetermines if Consul configures the Lambda to be invoked using the synchronous or asynchronous invocation mode.
<PREFIX>/regionSpecifies the AWS region the Lambda is running in.