Salt DevKit: Developing Formulas

Developing Salt Formulas on a Salt Stack Dev Environment

Salt Stack offers modularity where you can package up your Salt Stack code into a single component called a Salt formula. You store on the file system along with other Salt code, or publish these in a git repository.

Previous Article

How to use external formulas:

Tool Prerequisites

These are the tools used in this guide:

  • VirtualBox (recommended) is a cross-platform (Windows, Linux, mac OS) that allows you to run virtual machines. Another virtual machine system can be used, such as Hyper-V for Windows 10 Pro or KVM (libvrt) on Linux. This guide uses VirtualBox as it is open source and cross platform.
  • Bash Shell (recommended) is not strictly required, but the commands in this tutorial are tested and oriented toward bash. [Note: this is default on mac OS and popular Linux distros, or msys2 with Windows].

The Guide

In this guide, we start by creating the docker formula, then states and pillars that use the docker formula, and finally the Vagrantfile configuration that will show how to provision the system using all of this.

Step 1: Create Project Area

Create the directory and file structure that looks like following:

├── Vagrantfile
└── roots
├── pillar
│ ├── docker.sls
│ └── top.sls
└── salt
├── docker
│ ├── default.yaml
│ ├── init.sls
│ └── map.jinja
├── docker_nginx.sls
└── top.sls
# create directory structure
-p ~/salt-devkit-dev-formula/roots/{pillar,salt/docker}
cd ~/salt-devkit-dev-formula
# create files
roots/salt/{top.sls,docker_nginx.sls} \
roots/salt/docker/{default.yaml,init.sls,map.jinja} \
roots/pillar/{top.sls,docker.sls} \

Step 2: Create Docker Formula

A typical Salt formula has an main entry point (init.sls), default values (default.yaml), and a map.jinja to merge variables between pillars and local defaults, should values in the pillar not be set.

docker/init.sls (Part 1)
{% from "docker/map.jinja" import docker with context %}
docker/init.sls (Part 2)
docker/init.sls (Part 3)

Step 3: Create Salt State

Let’s create a state that will use docker. Edit docker_nginx.sls file and add the following content:


Step 4: Create Salt Pillars

Now comes time to setup the values we want to use for our project. First edit the top pillar pillar/top.sls that references pillars for use with our docker formula:


Step 5: Create Vagrant Configuration

Add the following content to the Vagrantfile configuration:

  1. Run nginx docker container

Step 6: Provision and Test the Docker Formula

The whole Ubuntu 18.04 guest environment (using VirtualBox) can be brought up by typing the following:

vagrant up --no-provision
vagrant provision
curl localhost:8081

Step 7: Clean up

You can halt and destroy the virtual guest by the following command:

vagrant destroy

Testing Solution with Python 3

Salt Stack installation process (salt bootstrap) defaults to Python2. Unfortunately, Python2 is officially deprecated as of 2020.

PYTHON=python3 vagrant up
PYTHON=python3 vagrant provision


Here are some useful articles I have come across that might be useful in your journey and related to the topics covered above.


Here’s information about installing Docker Engine as well as the nginx image (and source).

Vagrant Ubuntu 18.04 box

Vagrant community calls system images boxes (or boxen). This guide uses a bento box, which is a kit for building vagrant boxes in a variety of distros for the purpose of testing change configuration tools.


Information about provisioners in case you need options not demonstrated in this guide:

Salt States

General information about Salt States.

Salt Pillars

General information about Salt Pillars.

Salt Formulas

General information about Salt Formulas.

Salt References

Some Salt states configured in this guide.


This concludes the guide on how to quickly develop formulas for use with your Salt Stack environment. Vagrant as a tool from Hashicorp is useful to configuring, developing, and testing Salt formulas before they are integrated into production.

Linux NinjaPants Automation Engineering Mutant — exploring DevOps, o11y, k8s, progressive deployment (ci/cd), cloud native infra, infra as code