--- 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: - `ProxyType`: string | `connect-proxy` - Determines the proxy type the extension applies to. The only supported value is `connect-proxy`. - `ListenerType`: string | required - Specifies if the extension is applied to the `inbound` or `outbound` listener. - `Script`: string | required - 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`. ```hcl Kind = "proxy-defaults" Name = "global" Config { protocol = "http" } EnvoyExtensions { Name = "builtin/lua" Arguments = { ProxyType = "connect-proxy" Listener = "inbound" Script = <<-EOF 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 EOF } } ``` ```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" } }] } ``` ```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 ``` 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. ```shell-session $ consul config write lua-envoy-extension-proxy-defaults.hcl ``` ```shell-session $ consul config write lua-envoy-extension-proxy-defaults.json ``` ```shell-session $ kubectl apply lua-envoy-extension-proxy-defaults.yaml ``` ## 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. ```hcl Kind = "service-defaults" Name = "myservice" EnvoyExtensions = [ { Name = "builtin/lua" Arguments = { ProxyType = "connect-proxy" Listener = "inbound" Script = < Alternatively, you can apply the same extension configuration to [`proxy-defaults`](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions) configuration entries. You can also specify multiple Lua filters through the Envoy extensions. They will not override each other. ```hcl Kind = "service-defaults" Name = "myservice" EnvoyExtensions = [ { Name = "builtin/lua", Arguments = { ProxyType = "connect-proxy" Listener = "inbound" Script = <<-EOF function envoy_on_request(request_handle) meta = request_handle:streamInfo():dynamicMetadata() m = meta:get("consul") request_handle:headers():add("x-consul-datacenter", m["datacenter1"]) end EOF } }, { Name = "builtin/lua", Arguments = { ProxyType = "connect-proxy" Listener = "inbound" Script = <<-EOF function envoy_on_request(request_handle) meta = request_handle:streamInfo():dynamicMetadata() m = meta:get("consul") request_handle:headers():add("x-consul-datacenter", m["datacenter2"]) end EOF } } ] ```