Presenters
Source
Unleashing Envoy’s Potential: Beyond C++ with Dynamic Modules 🚀
Ever felt the power of Envoy but wished you could extend its capabilities without diving headfirst into C++ or wrestling with complex build systems? You’re not alone! While Envoy is a powerhouse out of the box, there are times when custom logic is a must. This is where the magic of dynamic modules comes in, opening up a universe of possibilities for extending Envoy’s functionality in ways that are both powerful and surprisingly accessible.
Let’s dive into how dynamic modules are revolutionizing Envoy extension development, making it easier and more flexible than ever before.
The Evolving Landscape of Envoy Extensions 🌐
Envoy has always offered several avenues for customization:
- External Processing: A common approach, but it requires managing separate deployments and a deep understanding of Envoy’s internals.
- WebAssembly (Wasm): Ideal for sandboxing untrusted binaries or extensions, offering a secure way to run code within Envoy.
- Lua: A long-standing favorite in the network proxy community, especially familiar to Nginx engineers, offering a relatively easy scripting experience.
- Static C++ Filters: The traditional method, where you write C++ code and compile it directly with Envoy. The trade-off? You’re responsible for maintaining your own Envoy build.
While these options have served us well, there’s always been a desire for something more, something that leverages the familiarity and vast ecosystems of popular programming languages without the heavy lifting of C++ compilation or the limitations of other approaches.
Enter Dynamic Modules: The Game Changer ✨
Released around April 2023 (Envoy 1.34), dynamic modules are a significant leap forward. Think of them as shared libraries that can be loaded at runtime without requiring an Envoy restart or recompilation.
What Makes Dynamic Modules So Powerful? 💡
- Language Agnostic: As long as a language can produce a shared library, you can theoretically use it! This means you’re not tied to C++.
- Third-Party Dependencies Welcome: Bring in any library you need without worrying about compatibility or build system conflicts. Load them at runtime with ease.
- Near Feature Completeness: For most use cases, especially HTTP filters, dynamic modules offer the power to implement virtually any logic you can imagine.
- No Envoy Forking Required: This is a huge win! You can extend Envoy’s functionality in a “normal” way, avoiding the complexities of maintaining a forked Envoy codebase.
A Glimpse into the Possibilities 🤯
The potential is truly mind-boggling. One impressive example shared was a Python WSGI implementation built as a dynamic module, demonstrating the sheer power and flexibility available. This showcases how dynamic modules can bridge the gap between Envoy’s robust proxy capabilities and the rich application development ecosystems of other languages.
Is Lua the End of the Road? 🤔
While Lua is a fantastic and accessible option for many custom logic needs, the question remains: can we do better? Looking at developer surveys, Lua, while not unpopular, isn’t at the top of everyone’s favorite language list. The motivation behind exploring further is simple: why not bring the most popular programming languages into the Envoy community?
Prototyping the Future: Go and JavaScript 👨💻
To explore this exciting new frontier, prototyping with Go and a JavaScript
engine was undertaken. The source code is readily available in the
envoyproxy/dynamic-modules-examples repository, so feel free to dive in!
While Rust and a more robust JavaScript engine (like V8) might be the go-to for production-ready solutions, the core message is clear: it’s incredibly easy to write extensions with dynamic modules. The ability to leverage third-party dependencies is a significant advantage.
A Look at the JavaScript Filter Configuration 📝
The configuration for a JavaScript filter looks remarkably familiar to how you might configure a Lua filter. You embed your script, define callback functions, and can then interact with Envoy using familiar patterns like:
console.log()for logging to Envoy’s stdout.- Setting and getting headers.
- Performing various other manipulations on requests and responses.
Witnessing the Magic: A Live Demo 🎬
The presentation included a compelling demo showcasing these capabilities:
- Request Path Magic: JavaScript callbacks were used to log messages,
retrieve headers, and crucially, insert custom headers like
x-animal-catinto the request. - Response Path Enhancements: On the response, another header,
x-external-headers, was dynamically added. - Dynamic Updates: The demo even showed the ability to change the header
value (from
cattodog) on the fly, demonstrating the dynamic nature of these extensions.
The output clearly showed the logs from console.log and the headers being
inserted and modified by the JavaScript code, proving that this powerful
integration is not just theoretical but a tangible reality.
The Verdict: Dynamic Modules are Here to Stay! 🦾
The takeaway is clear: dynamic modules are incredibly powerful. It’s not just about JavaScript; the same principles can be applied to bring in Python, Ruby, and many other languages. This opens up a vast new landscape for Envoy customization, allowing developers to leverage their preferred tools and ecosystems to build more sophisticated and powerful proxy solutions.
Could hosting official JavaScript modules within Envoy be the next logical step? The possibilities are exciting! Dynamic modules are undoubtedly a significant step towards making Envoy extension development more accessible, flexible, and powerful than ever before.