Variables as Code
Definition
- VaC
VaC stands for Variables as Code, it is the practice of managing configuration variables the same way you treat source code.
It is a concept that extends the Infrastructure as Code (IaC) philosophy to the management of configuration variables, secrets, and environment-specific settings. More precisely, this extends Configuration as Code (CaC) principles.
The idea is to treat variables — not just infrastructure or configuration — as version-controlled, declarative, and automated code rather than manual, static, or hardcoded values.
With growing complexity of the infrastructure, it is difficult to manage all the variables. Due to more and more available variables required to set up the infrastructure, it became quite annoying to hand the necessary variables to where they are actually used and even more annoying to add new variables.
Variables can be redundant and sometimes are defined on several places.
Attention
Many IaC projects use what could be called Values as Code (User Data as Code with the Rougail terminology). Values are placed in a versioned and structured repositories. But we don’t share the variable itself (apart from its name). We are thinking of its type, its scope, its purpose, etc.
Variables as Code is not only the values.
Variables as Code with Rougail
For this, we thought of a solution and came up with a concept of managing all our variables as a code called VaC (Variables as Code).
Often when we talk about VaC (or CaC) we think of the different environments (Development, Staging, Production).
With Rougail, this question does not arise. Essentially, Rougail manages this with user data. Here we’re talking about sharing variables between projects.
Furthermore, using a tool like Rougail allows you to use variables with different IaC deployment solutions without having to redefine those variables. It can be said that Rougail allows you to use variables not only between projects but also between tools.
To do this, we need typed variable definitions with defaults and validation.
Once defined, variables must be able to:
provide useful information to the operator to make their choices
load user values from differents sources
validate the context
display and archive the final values in a readable format
allow other applications to use these variables
Variables as Code with Rougail by example
There’s nothing better than a simple example to illustrate everything that’s just been presented.
Structured file
Let’s start by creating a file in Rougail format.
This isn’t the time to explain the format.
But we’ll create a quick file here to create the “my_variable” variable:
%YAML 1.2
---
version: 1.1
my_variable: my_value # It's my variable
...
Let’s document it
We can start by generating the variable’s documentation from this file:
Variable |
Description |
my_variable string |
It’s my variable. Default: my_value |
Or an example user data file in YAML format:
Example with all variables modifiable:
---
my_variable: my_value
Regarding documentation, it’s even possible to generate a changelog view for users.
Let’s imagine that the default value was originally old_value and is now my_value:
Variable |
Description |
my_variable string |
It’s my variable. Default: old_value myvalue |
Now it’s time to export
In simple JSON format:
{
"my_variable": "my_value"
}
Or in advanced Ansible format:
{
"_meta": {
"hostvars": {
"host1.net": {
"ansible_host": "host1.net",
"inventory": {
"my_variable": "my_value"
}
}
}
},
"app1": {
"hosts": [
"host1.net"
]
}
}
Or display it
Displaying informations is an important step in the VaC approach. In a complex environment where variables are defined in multiple places, not to mention their values located elsewhere, maintaining good traceability of variables and their values becomes difficult.
Managing variables like code also means compiling the informations.
Here display our examples:
╭─────── Caption ────────╮ │ Variable Default value │ ╰────────────────────────╯ Variables: ┗━━ 📓 It's my variable: my_value
Now change the value with differents user data:
╭────────────── Caption ───────────────╮ │ Variable Modified value │ │ (⏳ Original default value) │ ╰──────────────────────────────────────╯ ╭──────────── Layers ─────────────╮ │ • the YAML file "user_data.yml" │ │ • environment variable │ │ • Questionary │ ╰─────────────────────────────────╯ Variables: ┗━━ 📓 It's my variable: I am right about the value ◀ loaded from questionary
(⏳ I define the value! ◀ loaded from environment variable
⏳ no it's my value ◀ loaded from the YAML file "user_data.yml"
⏳ my_value)