SaltStack and Terraform: Installing Minions in ec2 instances

  • October 11, 2015

Terraform is a great orchestration tool and SaltStack is great configuration management software. The first one allows you to create resources in the cloud (instances, load balancer, databases, etc) and the second is used to provision the instances. Salt works in a master-agent mode, the agents are called minions. To provision an instance you have to install the salt-minion first. I’ve found two options to do it, this article is about the first one.

The first option is using “user data”. The majority of clouds supports user data to pass information or scripts to be executed in the first boot of the instance. Terraform supports this too. One of the advantages of this approach is that allows to install the Salt Minion on instances without public IP address.

In Terraform you pass the user data like this:

resource "aws_instance" "api-1" {
  ami = "ami-aaabbbccc"
  user_data = "....."

One of the problems is passing scripts to user data is the long strings. There are two options to work around this.

The first one is using the file function:

resource "aws_instance" "mongo" {
  ami = "ami-aaabbbccc"
  user_data = "${file("")}"

The second option is to use templates, which are more flexible if you need to pass some arguments to your script.
resource "aws_instance" "mongo" {
  ami = "ami-aaabbbccc"
  user_data = "${template_file.salt_bootstrap_mongo.rendered}"

You need to define the template resource in Terraform first:

resource "template_file" "salt_bootstrap_mongo" {
  filename = ""
  vars {
    roles = "mongo"
    environment = "develop"

Check the vars section of the template. Here you can define some variables to be used in the user data script. In the salt_bootstral.shtemplate script, you can use them to setup grains for example:

wget -O
sudo sh -A
salt-call --local grains.setval roles ${roles}
salt-call --local grains.setval environment ${environment}

Then when you run terraform apply, the template_file is going to be rendered with the values from template_file resource, before the instance is launched in the cloud.