Search

What's a VMOD?

What’s a VMOD?

A VMOD is a shared library that is written in C. It has a set of functions, containing the logic it wants to expose. These functions can then be imported and called from VCL, which in turn adds new functionality to VCL.

This is a very powerful concept because anything that can be written in C can in fact be exposed to VCL.

Varnish isn’t just a cache: by using the right VMODs, you can reshape content, route traffic, use custom authentication mechanisms and implement all kinds of custom logic using powerful VMODs.

Scope and purpose

However, it is important to know that VMODs aren’t a gateway to Varnish’s inner workings: the APIs that Varnish provides are quite limited, and there aren’t a lot of hooks. VMODs are intended to act independently, and usually wrap around some sort of library or logic in a simple and easy-to-use manner.

Some of the VMODs that are shipped with Varnish go beyond basic wrapping and do interface with the Varnish core. But that’s because the core has patches to open up access to internal APIs, purpose-built for these VMODs

The majority of VMODs perform the following tasks:

  • String manipulation
  • Type casting
  • Extracting values from complex data types
  • Inspecting session and request information
  • Safe access to third-party libraries

VMOD API

Every VMOD has an API. It is a collection of function calls and objects that the module exposes to VCL.

The VCL API is kept in a .vcc file, and one or more .c files contain the actual code.

Take for example https://github.com/varnishcache/libvmod-example, where you find the source code of the vmod_example VMOD.

vmod_example is a sample module for aspiring VMOD writers who need a bit of inspiration. The module itself doesn’t really do much, but it does lead the way, contains the necessary files, and scripts to build the module.

In the src directory, you’ll find a vmod_example.vcc file that contains the API.

$Module example 3 Example VMOD

DESCRIPTION
===========

This is the embedded documentation for the example VMOD. It should explain
the purpose and what problems it solves, with relevant examples.

It can span multiple lines and is written in RST format.
You can even have links and lists in here:

* https://github.com/varnish/libvmod-example/
* https://www.varnish-cache.org/

$Event event_function
$Function STRING info()

Returns a string set by the last VCL event, demonstrating the use of
event functions.

$Function STRING hello(STRING)

The different functions provided by the VMOD should also have their own
embedded documentation. This section is for the hello() function.

The $Module line defines the name of the VMOD, and the $Function lines define the API. The example above contains two functions:

  • example.info() which returns the information about the last VCL event that occurred
  • example.hello() which performs the typical Hello World, based on an input argument

The corresponding code can be found in vmod_example.c. The C-code itself isn’t that important to VMOD users, because the idea is that the VCL functions are the interface, and the implementation is abstracted by these VCL functions. As long as the documentation for the VMOD is good, the code is irrelevant.

VCL usage

Our example VMOD can be loaded into our VCL file by using the import statement:

vcl 4.1;

import example;

sub vcl_deliver {
	set resp.http.hello = example.hello("Thijs");
}

As you can see the example.hello() function becomes available and can be used in any of the VCL subroutines. In the example above, we’re using it to set the following response header:

hello: Hello Thijs

VMOD initialization

VMODs aren’t always a collection of utility functions. Often they keep track of state and are grouped into one or more objects.

Setting them up may require an initialization stage, which is done in the vcl_init subroutine. Throughout the book, we haven’t mentioned this subroutine a lot.

Let’s immediately throw in an example where vcl_init initializes vmod_directors:

vcl 4.1;

import directors;

backend backend1 {
	.host = "backend1.example.com";
	.port = "80";
}

backend backend2 {
	.host = "backend2.example.com";
	.port = "80";
}

sub vcl_init {
	new vdir = directors.round_robin();
	vdir.add_backend(backend1);
	vdir.add_backend(backend2);
}

sub vcl_recv {
	set req.backend_hint = vdir.backend();
}

This VMOD creates a director object that groups multiple backends into one. The director will distribute load across these backends using a distribution algorithm, and will expose itself as a single backend using the .backend() function.

Adding backends and choosing the right distribution algorithm is all done in vcl_init. As you can see in the example above, we’re using the directors.round_robin() function to create a directors object named vdir. This object uses the vdir.add_backend() method to assign backends.

vmod_directors is a load-balancing VMOD and will be covered in detail in chapter 7.

Installing a VMOD

Installing a VMOD is a lot like compiling C-code. That’s because a VMOD is written in C.

VMODs come with an autogen.sh script that will inspect your operating system, and will determine where to find the libtoolize, autoconf, and automake tools. The script also looks for the varnishapi library.

After this script finishes its execution, you can run the configure script that was generated. This script will configure the GCC compiler.

Eventually, all the configurations are in place to run the make command, which will use a Makefile to compile specific source files.

The final step is running make install, which will turn the compiled files into libvmod_example.so, and put this shared object in the right directory. By default this is /usr/lib/varnish/vmods/.

In order to successfully compile and install a VMOD your build system will have some dependencies.

If you’re on a Debian or Ubuntu system, you can use the following command to install the required dependencies:

# apt update && apt install -y \
varnish build-essential automake libtool python3-docutils

If you’re on Red Hat, Fedora, or CentOS, this is the equivalent:

# yum check-update && yum install -y \
varnish-devel gcc make automake libtool python3-docutils

It’s worth mentioning that you generally don’t have to compile or install any VMODs yourself, as most of them are packaged either with Varnish Cache or with Varnish Enterprise. It’s only for when you are developing your own VMODs, or when you are using non-packaged community VMODs.


®Varnish Software, Wallingatan 12, 111 60 Stockholm, Organization nr. 556805-6203