Consul
Run Lua scripts in Envoy proxy
The Lua Envoy extension enables the HTTP 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 isconnect-proxy.ListenerType: string | required - Specifies if the extension is applied to theinboundoroutboundlistener.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:
- Configure EnvoyExtensions through
service-defaultsorproxy-defaults. - 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.
lua-envoy-extension-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
}
}
For a full list of parameters for EnvoyExtensions, refer to the service-defaults and proxy-defaults 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 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.
$ consul config write lua-envoy-extension-proxy-defaults.hcl
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 thex-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.
lua-envoy-extension.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
}
}
]
Alternatively, you can apply the same extension configuration to proxy-defaults configuration entries.
You can also specify multiple Lua filters through the Envoy extensions. They will not override each other.
lua-envoy-extension.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
}
}
]