Getting started with Bolt
Welcome to Getting started with Bolt! Bolt is an open source orchestration tool that helps you make on-demand changes to remote targets such as servers, network devices, and cloud services.
In this guide, you'll write and run a Bolt plan. Bolt plans are powerful workflows that allow you to string together and automate commands, scripts, tasks, and even other plans. Your plan will install Apache on a group of target machines and upload a customized home page.
After you've completed this guide, you'll know how to:
Set up a Bolt project directory.
Run a Bolt command on a target.
Create an inventory file to set up groups and add connection information for your targets.
Write a Bolt plan that runs a bash script, runs a Bolt task, and uploads a file to your targets.
Before you begin
Make sure you've installed Bolt on your machine. For instructions on how to install Bolt on your operating system, see Installing Bolt.
Make sure you've installed Docker. Bolt does not require Docker to run, but for the purposes of this guide, Docker containers offer a safe and relatively simple way to set up some targets to practice on.
You can follow along and create the content you need as you go, or download everything you need from the Getting started repo.
Create a Bolt project and set up targets
A Bolt project is a directory containing a bolt-project.yaml
file. The
bolt-project.yaml
file contains project-wide configuration settings. Your
my_project
directory must contain a bolt-project.yaml
file so Bolt
recognizes it as a Bolt project.
Create a Bolt project directory
Create a directory named my_project
and set it as your working directory:
mkdir my_project; cd my_project
Run the following command to turn my_project
into a Bolt project:
*nix shell command
bolt project init my_project
Powershell cmdlet
New-BoltProject -Name my_project
Note: If your Powershell cmdlet doesn't work, make sure you've followed the steps to install the PuppetBolt PowerShell module.
To use Bolt plans or tasks, your Bolt project must use a specific directory
structure. The directory structure of a Bolt project is closely tied to Puppet
modules.
Because your plan will install Apache, you need an apache
module directory.
Your apache
directory needs files
and plans
subdirectories.
Run the following commands to set up the required directories in your project folder:
mkdir -p modules/apache/plans; mkdir -p modules/apache/files
After creating the directories, the file structure of my_project
looks like this:
.
โโโ bolt-project.yaml
โโโ inventory.yaml
โโโ modules
โโโ apache
โโโ files
โโโ plans
Next, set up Docker targets to run Apache on.
Create your targets
Bolt connects directly to computers, or targets, using Secure Shell (SSH) or Windows Remote Management (WinRM). To see how a Bolt plan works, you'll build and run some Docker containers to use as targets.
In the root of your my_project
directory, create a file named Dockerfile
and
paste in the following:
FROM rastasheep/ubuntu-sshd
RUN apt-get update && apt-get -y install libssl-dev
EXPOSE 80
CMD ["/usr/sbin/sshd", "-D"]
This Dockerfile defines an Ubuntu container with an active SSH service. The SSH service allows Bolt to communicate with the container using the SSH transport.
๐ฉ Tip: A Bolt transport is the connection method that Bolt uses to connect and communicate with a target. There is a Docker transport that simplifies connecting to Docker containers, but the SSH transport is useful for gaining a broader understanding of how Bolt inventory files work.
Next, build a docker-compose.yaml
file to create two instances of the
container. In your my_project
directory, create the following file and name it
docker-compose.yaml
:
version: '3'
services:
target1:
build: .
ports:
- '3000:80'
- '2000:22'
container_name: target1
target2:
build: .
ports:
- '3001:80'
- '2001:22'
container_name: target2
This compose file uses the Dockerfile to create two containers. The containers
are named target1
and target2
, and are bound to SSH ports 2000
and 2001
,
and HTTP ports 3000
and 3001
.
After creating your Dockerfile and docker-compose.yaml
file, your file
structure looks like this:
.
โโโ Dockerfile
โโโ bolt-project.yaml
โโโ docker-compose.yaml
โโโ inventory.yaml
โโโ modules
โโโ apache
โโโ files
โโโ plans
Build and run your containers using the docker-compose
command:
docker-compose up -d --build
You can check that your containers are running using the docker-compose ps
command:
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
target1 /usr/sbin/sshd -D Up 0.0.0.0:2000->22/tcp, 0.0.0.0:3000->80/tcp
target2 /usr/sbin/sshd -D Up 0.0.0.0:2001->22/tcp, 0.0.0.0:3001->80/tcp
Your targets are ready. Next, run a command on a target to see how Bolt works.
Run a command on a target
Before you start writing a plan, try using Bolt to run a command on one of your
targets. The syntax to run a Bolt command is bolt command run <COMMAND>
--targets <TARGET_NAME> <OPTIONS>
.
Use the following command to run whoami
on target1
:
bolt command run whoami -t 127.0.0.1:2000 -u root -p root --no-host-key-check
This command targets 127.0.0.1:2000
, which is the IP address and SSH port for
the target1
container. The command also specifies root
as the username and
password, and includes the --no-host-key-check
option to turn off certificate
authentication.
After you run the command, you get the following output from whoami
. Ignore
the warning about your inventory file. You'll set that up next.
$ bolt command run whoami -t 127.0.0.1:2000 -u root -p root --no-host-key-check
CLI arguments ["user", "password", "host-key-check"] might be overridden by Inventory: /Users/heston.hoffman/bolt-projects/my_project/inventory.yaml [ID: cli_overrides]
Started on 127.0.0.1:2000...
Finished on 127.0.0.1:2000:
STDOUT:
root
Successful on 1 target: 127.0.0.1:2000
Ran on 1 target in 0.46 sec
You've run your first Bolt command on a target! Next, create an inventory file to group your targets together and simplify your Bolt commands.
Create an inventory file to group your targets
You've just run a command on a single target. You could use the same command with a comma-separated list to target both of your containers. However, as the number of targets grows, this approach quickly becomes cumbersome. An inventory file solves this problem.
With an inventory file, you can set up different connection settings for each of your targets, and group targets together so you can aim a command at the group instead of specifying targets in a list.
When you set up your Bolt project, Bolt created an inventory file template named
inventory.yaml
in your project directory. Replace the contents of that file
with the following:
groups:
- name: containers
targets:
- uri: 127.0.0.1:2000
name: target1
- uri: 127.0.0.1:2001
name: target2
config:
transport: ssh
ssh:
user: root
password: root
host-key-check: false
This inventory file contains a group called containers
. The containers
group
lists:
The Uniform Resource Identifier (URI) and name for each Docker container.
The transport type that Bolt is using to communicate with the containers. In this case you're using the SSH transport.
The SSH authentication settings, which include the username, password, and whether Bolt should check for host keys.
To test your inventory file, run the whoami
command on target1
:
bolt command run whoami -t target1
Notice how much shorter the command is now that the inventory file is handling connection details like the user, password, ports, and URIs.
To run the command on both containers in the containers
group:
bolt command run whoami -t containers
To run the command on all targets in an inventory, use Bolt's implicit all
group:
bolt command run whoami -t all
Next, write a Bolt plan to install Apache on your targets.
Write a Bolt plan
Plans allow you to tie your commands, scripts, and tasks together to create powerful workflows. You can write Bolt plans in the Puppet language, or use YAML. In this guide, you're going to write a YAML plan that installs the Apache package on your Docker targets, starts the Apache service, and uploads an HTML homepage.
Use a task to install Apache on your targets
The first step in your YAML plan uses a Puppet task to install Apache on your targets.
In your my_project/modules/apache/plans
directory, create the following
file and name it install.yaml
:
parameters:
targets:
type: TargetSpec
steps:
- name: install_apache
task: package
targets: $targets
parameters:
action: install
name: apache2
description: "Install Apache using the packages task"
The first section of a Bolt plan defines the parameters your plan accepts. So
far, this plan has one parameter, targets
, with the type TargetSpec
. The
TargetSpec
type is a wrapper for defining targets that allows you to pass a
target, or multiple targets, into a plan. When you run this plan from the
command line and use the --targets
argument, Bolt interpolates the targets
into the targets
parameter.
After the parameters
section, you define the steps that make up the body of
your plan. The first step in your plan is named install_apache
. This step uses
a Bolt task called package
to install Apache on your targets. The package
task includes:
A
targets
parameter so Bolt knows which targets to execute the step on: In this case the task is using the$targets
parameter, so the step will run on all of the targets that you specify when you run your plan.A
parameters
section to tell the task what action to perform (install
), and the name of the package that Bolt should install (apache2
).An optional
description
key.
๐ฉ Tip: A Bolt task is a script that has been packaged into a Puppet module. The
package
task comes prepackaged with Bolt and allows you to perform various package-related actions. Bolt tasks are useful because you can reuse them or share them with others. Many of the modules on the Puppet forge include Bolt tasks.
After creating install.yaml
, your file structure looks like this:
.
โโโ Dockerfile
โโโ bolt-project.yaml
โโโ docker-compose.yaml
โโโ inventory.yaml
โโโ modules
โโโ apache
โโโ files
โโโ plans
โโโ install.yaml
From the root of your project directory, run the plan on your containers group using the following command:
bolt plan run apache::install -t containers
Note: The name of this plan consists of two segments joined by a double colon. The first segment indicates the name of the module where the plan is located and the second segment is the name of the plan file without the extension. Your plan is located in the
apache
module directory and is namedinstall.yaml
, so the name of the plan isapache::install
.
The output looks like this:
bolt plan run apache::install -t containers
Starting: plan apache::install
Starting: Install Apache using the packages task on target1, target2
Finished: Install Apache using the packages task with 0 failures in 11.42 sec
Finished: plan apache::install in 11.43 sec
Plan completed successfully with no result
Next, run a script on your targets to start the Apache service.
Run a script on your targets
Because you're running Apache on containers, the Apache service does not start automatically. You must create a short bash script that starts the Apache service and add it to your plan as a script step.
Create a file named start_apache.sh
in my-project/modules/apache/files/
and enter the following script:
#!/usr/bin/env bash
i=`ps -eaf | grep -i apache | grep -v grep | grep -v bash | wc -l`
if [[ $i > 0 ]]
then
echo "Apache is running"
else
echo "Starting Apache"
apache2ctl start
fi
At this point, your file structure looks like this:
.
โโโ Dockerfile
โโโ bolt-project.yaml
โโโ docker-compose.yaml
โโโ inventory.yaml
โโโ modules
โโโ apache
โโโ files
โ โโโ start_apache.sh
โโโ plans
โโโ install.yaml
The script checks the processes running on the container for Apache and starts the service if it is not running.
Now, add the script to install.yaml
as a step. After the install_apache
step, paste the following:
- name: start_apache
script: apache/start_apache.sh
targets: $targets
description: "Starting Apache service"
The step calls the start_apache.sh
script from your apache module directory.
Because the file is in your <MODULE_NAME>/files
location, you can use the
syntax <MODULE_NAME>/<FILE_NAME>
instead of typing out the full path to the
script.
Your plan now looks like this:
parameters:
targets:
type: TargetSpec
steps:
- name: install_apache
task: package
targets: $targets
parameters:
action: install
name: apache2
description: "Install Apache using the package task"
- name: start_apache
script: apache/start_apache.sh
targets: $targets
description: "Starting Apache service"
Run the plan again:
bolt plan run apache::install -t containers
At this point, you can reach either of your targets in your web browser using
their UID followed by port 3000
for target1
, or port 3001
for target2
.
Go to 127.0.0.1:3000 to see Apache's default Ubuntu
homepage on target1
.
You have two functioning Apache servers. Next, upload a file to your targets to change the homepage.
Upload an HTML homepage to your targets
Now that Apache is installed on both of your containers, upload an HTML homepage for the targets to display.
In my_project/modules/apache/files/
, create a file named index.html
and
enter the following:
<html>
<head>
<title> Getting started with Bolt </title>
</head>
<body>
<h1>Success!</h1>
<p>I'm running this website on a server configured with Bolt!</p>
</body>
</html>
Your final file structure looks like this:
.
โโโ Dockerfile
โโโ bolt-project.yaml
โโโ docker-compose.yaml
โโโ inventory.yaml
โโโ modules
โโโ apache
โโโ files
โ โโโ index.html
โ โโโ start_apache.sh
โโโ plans
โโโ install.yaml
Before you add a step to upload your homepage to your containers, you must
define another parameter. In the parameters
section of install.yaml
, add a
parameter named src
with the type String
. The src
parameter is the
location of the file you want to upload. You'll pass in src
as an argument
when you run the plan.
The parameters
section of your plan now looks like this:
parameters:
targets:
type: TargetSpec
src:
type: String
...
Now add the following step after the start_apache
step:
- name: upload_homepage
upload: $src
destination: /var/www/html/index.html
targets: $targets
description: "Upload homepage"
The upload_homepage
step uploads a file from the path you specify to a
destination path on the specified targets.
Your final plan looks like this:
parameters:
targets:
type: TargetSpec
src:
type: String
steps:
- name: install_apache
task: package
targets: $targets
parameters:
action: install
name: apache2
description: "Install Apache using the package task"
- name: start_apache
script: apache/start_apache.sh
targets: $targets
description: "Start the Apache service"
- name: upload_homepage
upload: $src
destination: /var/www/html/index.html
targets: $targets
description: "Upload site contents"
This time, run the plan with the src
argument to give Bolt a path to the
homepage file you want to upload:
bolt plan run apache::install -t containers src=apache/index.html
Remember: Because the file is in your
<MODULE_NAME>/files
location, you can use the syntaxsrc=<MODULE_NAME>/<FILE_NAME>
instead of typing in the full path to the file.
Go to 127.0.0.1:3000 again to see your new index page.
Note: If the page hasn't changed from the default Ubuntu homepage, try a hard refresh to clear the page's cache. On most browsers, you can accomplish this by holding Shift and clicking Reload.
Congratulations! You've learned how to run commands and scripts with Bolt, you've created a Bolt project with an inventory file, and you've written and run a Bolt plan that installs Apache on your targets and uploads a customized homepage.
Continue learning about Bolt:
For a deeper dive into Bolt, try the Introduction to Bolt training course or the Bolt learning kit.
For more information on working with Windows targets, see Automating Windows targets.
To find out more about Bolt plans, see Orchestrating workflows with plans.
For a list of available Bolt transports, see Running Bolt commands.
To learn about Bolt tasks, see Making on-demand changes with tasks.
To find Puppet modules that use tasks, take a look at the Puppet Forge.
For information on Bolt configuration see Configuring Bolt.
For information on Bolt projects see Bolt projects