AWS Lambda

  • This filter should be configured with the type URL type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config.

  • v3 API reference

Attention

The AWS Lambda filter is currently under active development.

The HTTP AWS Lambda filter is used to trigger an AWS Lambda function from a standard HTTP request. It supports a few options to control whether to pass through the HTTP request payload as is or to wrap it in a JSON schema.

If payload_passthrough is set to true, then the payload is sent to Lambda without any transformations. Note: This means you lose access to all the HTTP headers in the Lambda function.

However, if payload_passthrough is set to false, then the HTTP request is transformed to a JSON payload with the following schema:

 {
     "raw_path": "/path/to/resource",
     "method": "GET|POST|HEAD|...",
     "headers": {"header-key": "header-value", ... },
     "query_string_parameters": {"key": "value", ...},
     "body": "...",
     "is_base64_encoded": true|false
 }
  • raw_path is the HTTP request resource path (including the query string)

  • method is the HTTP request method. For example GET, PUT, etc.

  • headers are the HTTP request headers. If multiple headers share the same name, their values are coalesced into a single comma-separated value.

  • query_string_parameters are the HTTP request query string parameters. If multiple parameters share the same name, the last one wins. That is, parameters are not coalesced into a single value if they share the same key name.

  • body the body of the HTTP request is base64-encoded by the filter if the content-type header exists and is not one of the following:

    • text/*

    • application/json

    • application/xml

    • application/javascript

Otherwise, the body of HTTP request is added to the JSON payload as is.

On the other end, the response of the Lambda function must conform to the following schema:

 {
     "status_code": ...
     "headers": {"header-key": "header-value", ... },
     "cookies": ["key1=value1; HttpOnly; ...", "key2=value2; Secure; ...", ...],
     "body": "...",
     "is_base64_encoded": true|false
 }
  • The status_code field is an integer used as the HTTP response code. If this key is missing, Envoy returns a 200 OK.

  • The headers are used as the HTTP response headers.

  • The cookies are used as Set-Cookie response headers. Unlike the request headers, cookies are _not_ part of the response headers because the Set-Cookie header cannot contain more than one value per the RFC. Therefore, each key/value pair in this JSON array will translate to a single Set-Cookie header.

  • The body is base64-decoded if it is marked as base64-encoded and sent as the body of the HTTP response.

Note

The target cluster must have its endpoint set to the regional Lambda endpoint. Use the same region as the Lambda function.

AWS IAM credentials must be defined in either environment variables, EC2 metadata or ECS task metadata.

The filter supports per-filter configuration.

If you use the per-filter configuration, the target cluster must have the following metadata:

metadata:
  filter_metadata:
    com.amazonaws.lambda:
      egress_gateway: true

If you use the upstream filter configuration, this metadata is not required.

Below are some examples that show how the filter can be used in different deployment scenarios.

Example configuration

In this configuration, the filter applies to all routes in the filter chain of the http connection manager:

http_filters:
- name: envoy.filters.http.aws_lambda
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config
    arn: "arn:aws:lambda:us-west-2:987654321:function:hello_envoy"
    payload_passthrough: true

The corresponding regional endpoint must be specified in the target cluster. So, for example if the Lambda function is in us-west-2:

clusters:
- name: lambda_egress_gateway
  connect_timeout: 0.25s
  type: LOGICAL_DNS
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: lambda_egress_gateway
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: lambda.us-west-2.amazonaws.com
              port_value: 443
  transport_socket:
    name: envoy.transport_sockets.tls
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
      sni: "*.amazonaws.com"

The filter can also be configured per virtual-host, route or weighted-cluster. In that case, the target cluster must have specific Lambda metadata and target cluster’s endpoint should point to a region where the Lambda function is present.

weighted_clusters:
clusters:
- name: lambda_egress_gateway
  weight: 42
  typed_per_filter_config:
    envoy.filters.http.aws_lambda:
      "@type": type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.PerRouteConfig
      invoke_config:
        arn: "arn:aws:lambda:us-west-1:987654321:function:hello_envoy"
        payload_passthrough: false

An example with the Lambda metadata applied to a weighted-cluster:

clusters:
- name: lambda_egress_gateway
  connect_timeout: 0.25s
  type: LOGICAL_DNS
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  metadata:
    filter_metadata:
      com.amazonaws.lambda:
        egress_gateway: true
  load_assignment:
    cluster_name: lambda_egress_gateway # does this have to match? seems redundant
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: lambda.us-west-1.amazonaws.com
              port_value: 443
  transport_socket:
    name: envoy.transport_sockets.tls
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
      sni: "*.amazonaws.com"

Configuration as an upstream HTTP filter

SigV4 or SigV4A request signatures are calculated using the HTTP host, URL and payload as input. Depending on the configuration, Envoy may modify one or more of these prior to forwarding to the Cluster subsystem, but after the signature has been calculated and inserted into the HTTP headers. Modifying fields in a SigV4 or SigV4A signed request will result in an invalid signature.

To avoid invalid signatures, the AWS Request Signing Filter can be configured as an upstream HTTP filter. This allows signatures to be calculated as a final step before the HTTP request is forwarded upstream, ensuring signatures are correctly calculated over the updated HTTP fields.

Configuring this filter as an upstream HTTP filter is done in a similar way to the downstream case, but using the http_filters filter chain within the cluster configuration.

26  clusters:
27  - name: default_service
28    load_assignment:
29      cluster_name: default_service
30      endpoints:
31      - lb_endpoints:
32        - endpoint:
33            address:
34              socket_address:
35                address: 127.0.0.1
36                port_value: 10001
37    typed_extension_protocol_options:
38      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
39        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
40        upstream_http_protocol_options:
41          auto_sni: true
42          auto_san_validation: true
43        auto_config:
44          http2_protocol_options: {}
45        http_filters:
46          - name: envoy.filters.http.aws_lambda
47            typed_config:
48              "@type": type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config
49              arn: "arn:aws:lambda:us-west-2:987654321:function:hello_envoy"
50              payload_passthrough: false

Credentials

The filter uses a few different credentials providers to obtain an AWS access key ID, AWS secret access key, and AWS session token. It moves through the credentials providers in the order described below, stopping when one of them returns an access key ID and a secret access key (the session token is optional).

  1. Environment variables. The environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN are used.

  2. The AWS credentials file. The environment variables AWS_SHARED_CREDENTIALS_FILE and AWS_PROFILE are respected if they are set, else the file ~/.aws/credentials and profile default are used. The fields aws_access_key_id, aws_secret_access_key, and aws_session_token defined for the profile in the credentials file are used. These credentials are cached for 1 hour.

  3. From AssumeRoleWithWebIdentity API call towards AWS Security Token Service using WebIdentityToken read from a file pointed by AWS_WEB_IDENTITY_TOKEN_FILE environment variable and role arn read from AWS_ROLE_ARN environment variable. The credentials are extracted from the fields AccessKeyId, SecretAccessKey, and SessionToken are used, and credentials are cached for 1 hour or until they expire (according to the field Expiration). To enable this credentials provider set envoy.reloadable_features.use_http_client_to_fetch_aws_credentials to true so that it can use http async client to fetch the credentials. This provider is not compatible with Grpc Credentials AWS AwsIamConfig plugin which can only support deprecated libcurl credentials fetcher , see https://github.com/envoyproxy/envoy/pull/30626. To fetch the credentials a static cluster is required with the name sts_token_service_internal pointing towards regional AWS Security Token Service. The static internal cluster will still be added even if initially envoy.reloadable_features.use_http_client_to_fetch_aws_credentials is not set so that subsequently if the reloadable feature is set to true the cluster config is available to fetch the credentials.

  4. Either EC2 instance metadata, ECS task metadata or EKS Pod Identity. For EC2 instance metadata, the fields AccessKeyId, SecretAccessKey, and Token are used, and credentials are cached for 1 hour. For ECS task metadata, the fields AccessKeyId, SecretAccessKey, and Token are used, and credentials are cached for 1 hour or until they expire (according to the field Expiration). For EKS Pod Identity, The environment variable AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE will point to a mounted file in the container, containing the string required in the Authorization header sent to the EKS Pod Identity Agent. The fields AccessKeyId, SecretAccessKey, and Token are used, and credentials are cached for 1 hour or until they expire (according to the field Expiration). Note that the latest update on AWS credentials provider utility provides an option to use http async client functionality instead of libcurl to fetch the credentials. This behavior can be changed by setting envoy.reloadable_features.use_http_client_to_fetch_aws_credentials to true. The usage of libcurl is on the deprecation path and will be removed soon. To fetch the credentials from either EC2 instance metadata or ECS task metadata a static cluster is required pointing towards the credentials provider. The static cluster name has to be ec2_instance_metadata_server_internal for fetching from EC2 instance metadata or ecs_task_metadata_server_internal for fetching from ECS task metadata. If these clusters are not provided in the bootstrap configuration then either of these will be added by default. The static internal cluster will still be added even if initially envoy.reloadable_features.use_http_client_to_fetch_aws_credentials is not set so that subsequently if the reloadable feature is set to true the cluster config is available to fetch the credentials.

Statistics

The AWS Lambda filter outputs statistics in the http.<stat_prefix>.aws_lambda. namespace. The | stat prefix comes from the owning HTTP connection manager.

Name

Type

Description

server_error

Counter

Total requests that returned invalid JSON response (see payload_passthrough)

upstream_rq_payload_size

Histogram

Size in bytes of the request after JSON-transformation (if any).