Skip to content

Commit

Permalink
Envoy Lua Part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Achuth17 committed Oct 15, 2024
1 parent ef8350f commit c4b1103
Show file tree
Hide file tree
Showing 14 changed files with 448 additions and 39 deletions.
116 changes: 116 additions & 0 deletions content/posts/Envoy-Lua-Filter-Exploration-Part-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
+++
title = 'Envoy Lua HTTP Filter Exploration - Part 1'
date = 2024-10-13T00:11:52-07:00
draft = false
+++

Envoy offers a of variety in HTTP filters and you can do a lot with what comes out of the box like `Header Mutation filter` or `gRPC-HTTP Transcoding`. While this is great, there are certain circumstances where we need some additional customizations. To solve this issue, Envoy provides options like Lua HTTP Filter, Wasm Filter or the ExtProc Filter. Through these filters, you can write custom code in a non-C++ language that gets excuted either in the request or response flow like any other Envoy Filter. To start my journey into extending Envoy, I spent some time looking into the Lua HTTP Filter.

## Writing and maintaining Lua Scripts

### In-lining Lua Scripts
Register the script as an `inline_string` in the `default_source_code` or in the `source_codes` map section of the Lua HTTP Filter.

```
...
http_filters:
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
default_source_code:
inline_string: |
-- Called on the request path.
function envoy_on_request(request_handle)
request_handle:logInfo("Logging in the request path from default lua source.")
end
-- Called on the response path.
function envoy_on_response(response_handle)
response_handle:logInfo("Logging in the response path from default lua source.")
end
...
```
[Full example](https://github.com/Achuth17/envoy-configs/blob/main/lua-filter/envoy-lua-default-source.yaml)

### Lua Script Files
Create a separate Lua script file, Implement the two stub methods function `envoy_on_request(request_handle)` and function `envoy_on_response(response_handle)`. Ensure the script is accessible from the Envoy runtime. Once this is done, the script file can be referenced from the `source_codes` map section of the Lua HTTP Filter.

```
-- file.lua
-- Called on the request path.
function envoy_on_request(request_handle)
local headers = request_handle:headers()
header_value_to_replace = "User-Agent"
header_value = headers:get(header_value_to_replace)
if header_value ~= nil then
request_handle:logInfo("Replacing UserAgent header found in the request with 'Envoy'")
request_handle:headers():remove(header_value_to_replace)
request_handle:headers():add(header_value_to_replace, "Envoy")
end
end
-- Called on the response path.
function envoy_on_response(response_handle)
end
```
Register the script file in the `source_codes` map in the Lua HTTP Filter.

```
...
http_filters:
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
source_codes:
file.lua:
filename: file.lua
...
```
[Full example](https://github.com/Achuth17/envoy-configs/blob/main/lua-filter/envoy-lua-custom-source.yaml)

## Attaching Lua Scripts

### Lua Per Route
In each applicable route defined in a `virtual_host`, the `source_codes` map entry for the lua script should be referenced in a `typed_per_filter_config`.

```
...
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/ip" }
route: { cluster: some_service }
typed_per_filter_config:
envoy.filters.http.lua:
'@type': "type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute"
name: "file.lua"
...
```

[Full example](https://github.com/Achuth17/envoy-configs/blob/main/lua-filter/envoy-lua-custom-source.yaml)

### Default Lua Script
Default scripts are added by default to all routes except in routes with `Lua Per Route`. No extra steps are required in the `virtual_host` or `route` configurations.

[Full example](https://github.com/Achuth17/envoy-configs/blob/main/lua-filter/envoy-lua-default-source.yaml)

## Learnings:

1. Default Lua Script gets executed only when `Lua Per Route` is not in play. If `Lua Per Route` is used, the Default Lua Script is ignored.

2. Scenarios where Lua HTTP Filter is useful in its current form:

i. Modifying Headers, Body and Trailers including cases where the body is chunked or streamed.

ii. Making an external HTTP call to an upstream cluster. This can be done to either to log the request or response, send stats to an external server or perform auth. The suggestion is to not make blocking calls in the Lua HTTP Filter.

iii. Short circuiting request or response flows. If the headers, body or trailers don’t meet a certain criteria, we can short circuit the request or response flow and send back a canned response to the client. In the request flow, This could prevent calls from reaching the upstream cluster.
7 changes: 0 additions & 7 deletions content/posts/my-first-post.md

This file was deleted.

2 changes: 1 addition & 1 deletion hugo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
baseURL = 'https://achuth.blog/'
languageCode = 'en-us'
title = 'My New Hugo Site'
title = "Achuth's Blog"
theme = 'archie'
8 changes: 4 additions & 4 deletions public/categories/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!DOCTYPE html>
<html><head lang="en"><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Categories - My New Hugo Site</title><meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Categories - Achuth&#39;s Blog</title><meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="" />
<meta property="og:image" content=""/>
<link rel="alternate" type="application/rss+xml" href="http://localhost:1313/categories/index.xml" title="My New Hugo Site" />
<link rel="alternate" type="application/rss+xml" href="http://localhost:1313/categories/index.xml" title="Achuth's Blog" />
<meta property="og:url" content="http://localhost:1313/categories/">
<meta property="og:site_name" content="My New Hugo Site">
<meta property="og:site_name" content="Achuth&#39;s Blog">
<meta property="og:title" content="Categories">
<meta property="og:locale" content="en_us">
<meta property="og:type" content="website">
Expand All @@ -32,7 +32,7 @@
<body>
<div class="content"><header>
<div class="main">
<a href="http://localhost:1313/">My New Hugo Site</a>
<a href="http://localhost:1313/">Achuth&#39;s Blog</a>
</div>
<nav>

Expand Down
4 changes: 2 additions & 2 deletions public/categories/index.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Categories on My New Hugo Site</title>
<title>Categories on Achuth&#39;s Blog</title>
<link>http://localhost:1313/categories/</link>
<description>Recent content in Categories on My New Hugo Site</description>
<description>Recent content in Categories on Achuth&#39;s Blog</description>
<generator>Hugo</generator>
<language>en-us</language>
<atom:link href="http://localhost:1313/categories/index.xml" rel="self" type="application/rss+xml" />
Expand Down
23 changes: 17 additions & 6 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
<html>
<head lang="en"><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>My New Hugo Site | Home </title><meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Achuth&#39;s Blog | Home </title><meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="" />
<meta property="og:image" content=""/>
<link rel="alternate" type="application/rss+xml" href="http://localhost:1313/index.xml" title="My New Hugo Site" />
<link rel="alternate" type="application/rss+xml" href="http://localhost:1313/index.xml" title="Achuth's Blog" />
<meta property="og:url" content="http://localhost:1313/">
<meta property="og:site_name" content="My New Hugo Site">
<meta property="og:title" content="My New Hugo Site">
<meta property="og:site_name" content="Achuth&#39;s Blog">
<meta property="og:title" content="Achuth&#39;s Blog">
<meta property="og:locale" content="en_us">
<meta property="og:type" content="website">

<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="My New Hugo Site">
<meta name="twitter:title" content="Achuth&#39;s Blog">


<link href="http://localhost:1313/css/fonts.2c2227b81b1970a03e760aa2e6121cd01f87c88586803cbb282aa224720a765f.css" rel="stylesheet">
Expand All @@ -35,7 +35,7 @@
<div class="content">
<header>
<div class="main">
<a href="http://localhost:1313/">My New Hugo Site</a>
<a href="http://localhost:1313/">Achuth&#39;s Blog</a>
</div>
<nav>

Expand All @@ -49,6 +49,17 @@



<section class="list-item">
<h1 class="title"><a href="/posts/envoy-lua-filter-exploration-part-1/">Envoy Lua HTTP Filter Exploration - Part 1</a></h1>
<time>Oct 13, 2024</time>
<br><div class="description">

<p>Envoy offers a of variety in HTTP filters and you can do a lot with what comes out of the box like <code>Header Mutation filter</code> or <code>gRPC-HTTP Transcoding</code>. While this is great, there are certain circumstances where we need some additional customizations. To solve this issue, Envoy provides options like Lua HTTP Filter, Wasm Filter or the ExtProc Filter. Through these filters, you can write custom code in a non-C++ language that gets excuted either in the request or response flow like any other Envoy Filter. To start my journey into extending Envoy, I spent some time looking into the Lua HTTP Filter.</p>&hellip;

</div>
<a class="readmore" href="/posts/envoy-lua-filter-exploration-part-1/">Read more ⟶</a>
</section>




Expand Down
13 changes: 10 additions & 3 deletions public/index.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>My New Hugo Site</title>
<title>Achuth&#39;s Blog</title>
<link>http://localhost:1313/</link>
<description>Recent content on My New Hugo Site</description>
<description>Recent content on Achuth&#39;s Blog</description>
<generator>Hugo</generator>
<language>en-us</language>
<lastBuildDate></lastBuildDate>
<lastBuildDate>Sun, 13 Oct 2024 00:11:52 -0700</lastBuildDate>
<atom:link href="http://localhost:1313/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Envoy Lua HTTP Filter Exploration - Part 1</title>
<link>http://localhost:1313/posts/envoy-lua-filter-exploration-part-1/</link>
<pubDate>Sun, 13 Oct 2024 00:11:52 -0700</pubDate>
<guid>http://localhost:1313/posts/envoy-lua-filter-exploration-part-1/</guid>
<description>&lt;p&gt;Envoy offers a of variety in HTTP filters and you can do a lot with what comes out of the box like &lt;code&gt;Header Mutation filter&lt;/code&gt; or &lt;code&gt;gRPC-HTTP Transcoding&lt;/code&gt;. While this is great, there are certain circumstances where we need some additional customizations. To solve this issue, Envoy provides options like Lua HTTP Filter, Wasm Filter or the ExtProc Filter. Through these filters, you can write custom code in a non-C++ language that gets excuted either in the request or response flow like any other Envoy Filter. To start my journey into extending Envoy, I spent some time looking into the Lua HTTP Filter.&lt;/p&gt;</description>
</item>
</channel>
</rss>
Loading

0 comments on commit c4b1103

Please sign in to comment.