Using instance templates to install Salt on AWS

Deanna Thompson

Discussing how I use instance templates to spin up a small-scale Salt infrastructure on AWS

A few months ago, I found myself needing to brush up on the basics of Salt. If you’re never heard of Salt before, it’s a Python-based, open-source automation and configuration management engine. You can use Salt to configure and manage your nodes.

A basic Salt infrastructure typically consists of a Salt master and one or more Salt minions. Typically, you send commands to a Salt minion from the Salt master. Data is sent between a Salt master and a Salt minion through an event bus.

For example, if you want to check the FTP proxy settings on all of your nodes, you’d run:

salt '*' proxy.get_ftp_proxy

This command targets all minions '*' and uses the proxy.get_ftp_proxy execution module to get current FTP proxy settings. You send this command from the Salt master and the Salt minions return the data.

It’s cool stuff.

Anyway, a few months ago, I needed to brush up on my Salt knowledge, such as how to install Salt on a virtual machine (VM), and how to send commands to Salt minions from Salt masters. At that time, I was also learning about AWS, so I figured this was a great opportunity to do both.

The biggest problem, though, was figuring out how to install the Salt master service and Salt minion service on my VMs. If I wanted to create several Salt masters or several Salt minions, I’d have to do that one at a time, and that is very time-consuming.

Why create EC2 launch templates

With launch templates, you can specify configuration information for an EC2 instance. You might create a launch template that creates a Linux instance and deploy the instance in a particular security group. Once you create the template, you can deploy as many instances as you like from the template. This saves you time from having to deploy each instance manually. If you have 1000 VMs to deploy, you definitely don’t want to go through the Launch instance workflow 1000 times. Or worse, SSH into 1000 different VMs to install Salt.

If you’d like to install certain packages or applications on launch, or complete a series of tasks on launch, you can pass user data to the EC2 instance. You can pass shell scripts or cloud-init directives to the instance. For example, you could write a script that runs sudo apt-get update and sudo apt-get upgrade to immediately update and upgrade any packages.

I created two shell scripts that install and enable the Salt master service and the Salt minion service. After the instance is deployed, I can SSH into the VM and test the installation and communication between the Salt master and Salt minion(s).

Note: These scripts install Salt on RedHat (RHEL) operating systems. If you want to install Salt on other operating systems, view the manual installation instructions.

User data for the Salt master EC2 instance

Here is the script I created to install the Salt master service on my EC2 instance:

#!/bin/bash
mkdir /etc/apt/keyrings
rpm --import https://repo.saltproject.io/salt/py3/redhat/9/x86_64/SALT-PROJECT-GPG-PUBKEY-2023.pub
curl -fsSL https://repo.saltproject.io/salt/py3/redhat/9/x86_64/latest.repo | tee /etc/yum.repos.d/salt.repo
yum clean expire-cache
yum install -y salt-master
yum install -y salt-minion
rm -f /etc/salt/minion
echo "master: 127.0.0.1" >> /etc/salt/minion 
echo "salt-master-01" > /etc/salt/minion_id #Sets minion id for the Salt master
systemctl enable salt-master && systemctl start salt-master
systemctl enable salt-minion && systemctl start salt-minion

This script does the following:

  1. Installs the Salt Project repository and key
  2. Installs the Salt master service and Salt minion service (you can manage your Salt masters as a minion if you like)
  3. Sets the hostname for the Salt master
  4. Sets the minion id for the Salt master
  5. Enables and starts the Salt master and Salt minion service

User data for the Salt minion EC2 instance

Here is the script I created to install the Salt minion service on my EC2 instance:

#!/bin/bash
mkdir /etc/apt/keyrings
rpm --import https://repo.saltproject.io/salt/py3/redhat/9/x86_64/SALT-PROJECT-GPG-PUBKEY-2023.pub
curl -fsSL https://repo.saltproject.io/salt/py3/redhat/9/x86_64/latest.repo | tee /etc/yum.repos.d/salt.repo
yum clean expire-cache
yum install -y salt-minion
systemctl enable salt-minion && systemctl start salt-minion

This script does the following:

  1. Installs the Salt Project repository and key
  2. Installs the Salt minion service
  3. Enables and starts the Salt minion service

After I deploy the EC2 instances, I usually SSH into the Salt minion and set the Salt master’s hostname and run a test.ping command to test communication between the Salt master and Salt minion.

Summary

User data is a great way to streamline the launch process for your EC2 instances. Rather than SSH into every instance, you can pass a series of commands to your instance at launch time.

Keep in mind that this is a very basic Salt installation; it only installs Salt and required services. I still think it’s a useful script for someone who wants to install Salt and start exploring what it can do. I might modify the script to update and upgrade packages or complete some other task.