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

Backport of Add envoy extension docs into release/1.15.x #16394

Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ spec:
{
name: 'EnvoyExtensions',
type: 'array<EnvoyExtension>: []',
description: `A list of extensions to modify Envoy proxy configuration.`,
description: `A list of extensions to modify Envoy proxy configuration.<br><br>
Applying \`EnvoyExtensions\` to \`ProxyDefaults\` may produce unintended consequences. We recommend enabling \`EnvoyExtensions\` with [\`ServiceDefaults\`](/consul/docs/connect/config-entries/service-defaults#envoyextensions) in most cases.`,
children: [
{
name: 'Name',
Expand Down
31 changes: 31 additions & 0 deletions website/content/docs/connect/proxies/envoy-extensions/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
layout: docs
page_title: Envoy Extensions
description: >-
Learn how Envoy extensions enables you to add support for additional Envoy features without modifying the Consul codebase.
---

# Envoy extensions overview

This topic provides an overview of Envoy extensions in Consul service mesh deployments. You can modify Consul-generated Envoy resources to add additional functionality without modifying the Consul codebase.

## Introduction

Consul supports two methods for modifying Envoy behavior. You can either modify the Envoy resources Consul generates through [escape hatches](/consul/docs/connect/proxies/envoy#escape-hatch-overrides) or configure your services to use Envoy extensions using the `EnvoyExtension` parameter. Implementing escape hatches requires rewriting the Envoy resources so that they are compatible with Consul, a task that also requires understanding how Consul names Envoy resources and enforces intentions.

Instead of modifying Consul code, you can configure your services to use Envoy extensions through the `EnvoyExtensions` field. This field is definable in [`proxy-defaults`](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions) and [`service-defaults`](/consul/docs/connect/config-entries/service-defaults#envoyextensions) configuration entries.

## Supported extensions

Envoy extensions enable additional service mesh functionality in Consul by changing how the sidecar proxies behave. Extensions invoke custom code when traffic passes through an Envoy proxy. Consul supports the following extensions:

- Lua
- Lambda

### Lua

The `lua` Envoy extension enables HTTP Lua filters in your Consul Envoy proxies. It allows you to run Lua scripts during Envoy requests and responses from Consul-generated Envoy resources. Refer to the [`lua`](/consul/docs/proxies/envoy-extensions/usage/lua) documentation for more information.

### Lambda

The `lambda` Envoy extension enables services to make requests to AWS Lambda functions through the mesh as if they are a normal part of the Consul catalog. Refer to the [`lambda`](/consul/docs/proxies/envoy-extensions/usage/lambda) documentation for more information.
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
layout: docs
page_title: Lambda Envoy Extension
description: >-
Learn how the `lambda` Envoy extension enables Consul to join AWS Lambda functions to its service mesh.
---

# Invoke Lambda functions in Envoy proxy

The Lambda Envoy extension configures outbound traffic on upstream dependencies allowing mesh services to properly invoke AWS Lambda functions. Lambda functions appear in the catalog as any other Consul service.

You can only enable the Lambda extension through `service-defaults`. This is because the Consul uses the `service-defaults` configuration entry name as the catalog name for the Lambda functions.

## Specification

The Lambda Envoy extension has the following arguments:

| Arguments | Description |
| -------------------- | ------------------------------------------------------------------------------------------------ |
| `ARN` | Specifies the [AWS ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) for the service's Lambda. |
| `InvocationMode` | Determines if Consul configures the Lambda to be invoked using the synchronous or asynchronous [invocation mode](https://docs.aws.amazon.com/lambda/latest/operatorguide/invocation-modes.html). |
| `PayloadPassthrough` | Determines if the body Envoy receives is converted to JSON or directly passed to Lambda. |

Be aware that unlike [manual lambda registration](/consul/docs/lambda/registration/manual#supported-meta-fields), region is inferred from the ARN when specified through an Envoy extension.

## Workflow

There are two steps to configure the Lambda Envoy extension:

1. Configure EnvoyExtensions through `service-defaults`.
1. Apply the configuration entry.

### Configure `EnvoyExtensions`

To use the Lambda Envoy extension, you must configure and apply a `service-defaults` configuration entry. Consul uses the name of the entry as the Consul service name for the Lambdas in the catalog. Downstream services also use the name to invoke the Lambda.

The following example configures the Lambda Envoy extension to create a service named `lambda` in the mesh that can invoke the associated Lambda function.

<Tabs>
<Tab heading="HCL" group="hcl">
<CodeBlockConfig filename="lambda-envoy-extension.hcl">

```hcl
Kind = "service-defaults"
Name = "lambdaInvokingApp"
Protocol = "http"
EnvoyExtensions {
Name = "builtin/aws/lambda"
Arguments = {
ARN = "arn:aws:lambda:us-west-2:111111111111:function:lambda-1234"
}
}
```

</CodeBlockConfig>
</Tab>
<Tab heading="JSON" group="json">
<CodeBlockConfig filename="lambda-envoy-extension.json">

```hcl
{
"kind": "service-defaults",
"name": "lambdaInvokingApp",
"protocol": "http",
"envoy_extensions": [{
"name": "builtin/aws/lambda",
"arguments": {
"arn": "arn:aws:lambda:us-west-2:111111111111:function:lambda-1234"
}
}]
}

```

</CodeBlockConfig>
</Tab>

<Tab heading="Kubernetes" group="kubernetes">
<CodeBlockConfig filename="lambda-envoy-extension.yaml">

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: lambda
spec:
protocol: http
envoyExtensions:
name = "builtin/aws/lambda"
arguments:
arn: arn:aws:lambda:us-west-2:111111111111:function:lambda-1234
```

</CodeBlockConfig>
</Tab>

</Tabs>

For a full list of parameters for `EnvoyExtensions`, refer to the [`service-defaults`](/consul/docs/connect/config-entries/service-defaults#envoyextensions) and [`proxy-defaults`](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions) configuration entries reference documentation.

~> **Note:** You can only enable the Lambda extension through `service-defaults`.

Refer to [Configuration specification](#configuration-specification) section to find a full list of arguments for the Lambda Envoy extension.

### Apply the configuration entry

Apply the `service-defaults` configuration entry.

<Tabs>
<Tab heading="HCL" group="hcl">

```shell-session
$ consul config write lambda-envoy-extension.hcl
```

</Tab>
<Tab heading="JSON" group="json">

```shell-session
$ consul config write lambda-envoy-extension.json
```

</Tab>
<Tab heading="Kubernetes" group="kubernetes">

```shell-session
$ kubectl apply lambda-envoy-extension.yaml
```

</Tab>
</Tabs>

## Examples

In the following example, the Lambda Envoy extension adds a single Lambda function running in two regions into the mesh. Then, you can use the `lambda` service name to invoke it, as if it was any other service in the mesh.

<CodeBlockConfig filename="lambda-envoy-extension.json">

```hcl
Kind = "service-defaults"
Name = "lambda"
Protocol = "http"
EnvoyExtensions {
Name = "builtin/aws/lambda"

Arguments = {
payloadPassthrough: false
arn: arn:aws:lambda:us-west-2:111111111111:function:lambda-1234
}
}
EnvoyExtensions {
Name = "builtin/aws/lambda"

Arguments = {
payloadPassthrough: false
arn: arn:aws:lambda:us-east-1:111111111111:function:lambda-1234
}
}
```

</CodeBlockConfig>
185 changes: 185 additions & 0 deletions website/content/docs/connect/proxies/envoy-extensions/usage/lua.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
layout: docs
page_title: Lua Envoy Extension
description: >-
Learn how the `lua` Envoy extension enables Consul to run Lua scripts during Envoy requests and responses from Consul-generated Envoy resources.
---

# Run Lua scripts in Envoy proxy

The Lua Envoy extension enables the [HTTP Lua filter](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter) in your Consul Envoy proxies, letting you run Lua scripts when requests and responses pass through Consul-generated Envoy resources.

Envoy filters support setting and getting dynamic metadata, allowing a filter to share state information with subsequent filters. To set dynamic metadata, configure the HTTP Lua filter. Users can call `streamInfo:dynamicMetadata()` from Lua scripts to get the request's dynamic metadata.

## Configuration specifications

To use the Lua Envoy extension, configure the following arguments in the `EnvoyExtensions` block:

| Arguments | Description |
| -------------- | ------------------------------------------------------------------------------------------------ |
| `ProxyType` | Determines the proxy type the extension applies to. The only supported value is `connect-proxy`. |
| `ListenerType` | Specifies if the extension is applied to the `inbound` or `outbound` listener. |
| `Script` | The Lua script that is configured to run by the HTTP Lua filter. |

## Workflow

There are two steps to configure the Lua Envoy extension:

1. Configure EnvoyExtensions through `service-defaults` or `proxy-defaults`.
1. Apply the configuration entry.

### Configure `EnvoyExtensions`

To use Envoy extensions, you must configure and apply a `proxy-defaults` or `service-defaults` configuration entry with the Envoy extension.

- When you configure Envoy extensions on `proxy-defaults`, they apply to every service.
- When you configure Envoy extensions on `service-defaults`, they apply to a specific service.

Consul applies Envoy extensions configured in `proxy-defaults` before it applies extensions in `service-defaults`. As a result, the Envoy extension configuration in `service-defaults` may override configurations in `proxy-defaults`.

The following example configures the Lua Envoy extension on every service by using the `proxy-defaults`.

<Tabs>
<Tab heading="HCL" group="hcl">
<CodeBlockConfig filename="lua-envoy-extension-proxy-defaults.hcl">

```hcl
Kind = "proxy-defaults"
Name = "global"
Protocol = "http"
EnvoyExtensions {
Name = "builtin/lua"

Arguments = {
ProxyType = "connect-proxy"
Listener = "inbound"
Script = <<-EOS
function envoy_on_request(request_handle)
meta = request_handle:streamInfo():dynamicMetadata()
m = meta:get("consul")
request_handle:headers():add("x-consul-service", m["service"])
request_handle:headers():add("x-consul-namespace", m["namespace"])
request_handle:headers():add("x-consul-datacenter", m["datacenter"])
request_handle:headers():add("x-consul-trust-domain", m["trust-domain"])
end
EOS
}
}
```

</CodeBlockConfig>
</Tab>
<Tab heading="JSON" group="json">
<CodeBlockConfig filename="lua-envoy-extension-proxy-defaults.json">

```hcl
{
"kind": "proxy-defaults",
"name": "global",
"protocol": "http",
"envoy_extensions": [{
"name": "builtin/lua",
"arguments": {
"proxy_type": "connect-proxy",
"listener": "inbound",
"script": "function envoy_on_request(request_handle)\nmeta = request_handle:streamInfo():dynamicMetadata()\nm = \nmeta:get("consul")\nrequest_handle:headers():add("x-consul-service", m["service"])\nrequest_handle:headers():add("x-consul-namespace", m["namespace"])\nrequest_handle:headers():add("x-consul-datacenter", m["datacenter"])\nrequest_handle:headers():add("x-consul-trust-domain", m["trust-domain"])\nend"
}
}]
}
```

</CodeBlockConfig>
</Tab>
<Tab heading="Kubernetes" group="kubernetes">
<CodeBlockConfig filename="lua-envoy-extension-proxy-defaults.yaml">

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
name: global
spec:
protocol: http
envoyExtensions:
name = "builtin/lua"
arguments:
proxyType: "connect-proxy"
listener: "inbound"
script: |-
function envoy_on_request(request_handle)
meta = request_handle:streamInfo():dynamicMetadata()
m = meta:get("consul")
request_handle:headers():add("x-consul-service", m["service"])
request_handle:headers():add("x-consul-namespace", m["namespace"])
request_handle:headers():add("x-consul-datacenter", m["datacenter"])
request_handle:headers():add("x-consul-trust-domain", m["trust-domain"])
end
```

</CodeBlockConfig>
</Tab>
</Tabs>

For a full list of parameters for `EnvoyExtensions`, refer to the [`service-defaults`](/consul/docs/connect/config-entries/service-defaults#envoyextensions) and [`proxy-defaults`](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions) configuration entries reference documentation.

!> **Warning:** Applying `EnvoyExtensions` to `ProxyDefaults` may produce unintended consequences. We recommend enabling `EnvoyExtensions` with `ServiceDefaults` in most cases.

Refer to [Configuration specification](#configuration-specification) section to find a full list of arguments for the Lua Envoy extension.

### Apply the configuration entry

Apply the `proxy-defaults` or `service-defaults` configuration entry.

<Tabs>
<Tab heading="HCL" group="hcl">

```shell-session
$ consul config write lua-envoy-extension-proxy-defaults.hcl
```

</Tab>
<Tab heading="JSON" group="json">

```shell-session
$ consul config write lua-envoy-extension-proxy-defaults.json

```

</Tab>
<Tab heading="Kubernetes" group="kubernetes">

```shell-session
$ kubectl apply lua-envoy-extension-proxy-defaults.yaml
```

</Tab>
</Tabs>

## Examples

In the following example, the `service-defaults` configure the Lua Envoy extension to insert the HTTP Lua filter for service `myservice` and add the Consul service name to the`x-consul-service` header for all inbound requests. The `ListenerType` makes it so that the extension applies only on the inbound listener of the service's connect proxy.

<CodeBlockConfig filename="lua-envoy-extension.json">

```hcl
Kind = "service-defaults"
Name = "myservice"
EnvoyExtensions {
Name = "builtin/lua"

Arguments = {
ProxyType = "connect-proxy"
Listener = "inbound"
Script = <<EOF
function envoy_on_request(request_handle)
local service = request_handle:streamInfo():dynamicMetadata():get("consul")["service"]
request_handle:headers():add("x-consul-service", service)
end
EOF
}
}
```

</CodeBlockConfig>

Alternatively, you can apply the same extension configuration to [`proxy-defaults`](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions) configuration entries.
Loading