Skip to main content

Bootstrapping Puppet with Bolt

Hands-On Lab

 

Photo of Elle Krout

Elle Krout

Content Team Lead in Content

Length

00:30:00

Difficulty

Intermediate

PuppetLabs' Bolt is an open-source orchestration tool that allows us to run multiple ad-hoc commands on our hosts over SSH — without the need for the Puppet configuration management tool at all! Bolt also lets us run pre-written tasks and overall configuration plans across our hosts, making it an ideal option for servers that cannot or do not currently support Puppet. This also means Bolt is an ideal solution for bootstrapping any nodes we want to include in our Puppet infrastructure. In this hands-on lab, we'll be crafting a Bolt plan that will allow us to install Puppet on any nodes we want to pull under our Puppet Enterprise setup. By doing this, we will gain experience writing Puppet tasks and plans, using the command line tool, and configuring Bolt on our workstation.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Bootstrapping Puppet with Bolt

Introduction

In this hands-on lab, we'll be crafting a Bolt plan that will allow us to install Puppet on any nodes we want to pull under our Puppet Enterprise setup. By doing this, we will gain experience writing Puppet tasks and plans, using the command line tool, and configuring Bolt on our workstation.

Solution

Begin by logging in to the lab server using the credentials provided on the hands-on lab page:

 ssh cloud_user@PUBLIC_IP_ADDRESS

Create the Hostname Task

From the workstation:

  1. Move into the default location for adding custom modules to Bolt:

    $ cd .puppetlabs/bolt/site-modules/

  2. Use the PDK to create a new module called base; move into the new module's directory when done:

    $ pdk new module base $ cd base

    Note: A prompt may be encountered for the Puppet Forge username, but we may enter: na.

  3. Leave the default license for the module code as: Apache-2.0.

  4. Deselect the Windows operating system, and leave:

    • RedHat based Linux
    • Debian based Linux
  5. Type y for Yes to approve the generation of metadata.

  6. Use cd base/ to redirect into the new module.

  7. We're going to write our task using a simple Bash script. Let's call it hostname:

    $ pdk new task hostname $ vim tasks/hostname.sh

  8. Create a script that uses the hostnamectl command and a user-provided variable for the actual desired hostname:

    !/bin/sh

    hostnamectl set-hostname $PT_hostname

    Save and exit.

  9. Open the associated tasks/hostname.json file to define the parameters for our provided variable; update any additional fields as required:

    $ vim tasks/hostname.json

    { "puppet_task_version": 1, "supports_noop": false, "description": "Sets the hostname of our node", "parameters": { "hostname": { "description": "The desired hostname" } } }

    Save and exit. The JSON task is now created.

Create the Boostrap Plan

  1. Since the PDK does not support writing plans at this time, create a new plans directory:

    $ mkdir plans

  2. We're going to write our plan using the Puppet DSL, so create and open plans/bootstrap.pp:

    $ vim plans/bootstrap.pp

  3. We want to first create our plan declaration:

    plan base::bootstrap( ) { }

  4. Next, we want to create our first step in our plan. Let's call our hostname task, note that instead of manually assigning our targets, we create an $node variable:

    plan base::bootstrap( TargetSpec $node, TargetSpec $hostname, ) {

     run_task('base::hostname', $node, hostname => $hostname)

    }

  5. Add the run_command steps for our installation:

    plan base::bootstrap( TargetSpec $node, TargetSpec $hostname, ) {

     run_task('base::hostname', $node, hostname => $hostname)
     run_command("curl -k https://puppet.ec2.internal:8140/packages/current/install.bash -o /tmp/install.bash", $node)

    }

  6. Finally, add a step to approve the new node via the Puppet master:

    plan base::bootstrap( TargetSpec $node, TargetSpec $hostname, ) { run_task('base::hostname', $node, hostname => $hostname) run_command("curl -k https://puppet.ec2.internal:8140/packages/current/install.bash -o /tmp/install.bash", $node) run_command("bash /tmp/install.bash", $node) run_command("puppetserver ca sign --all", "puppet.ec2.internal") }

    Save and exit the file.

Run the Plan

  1. First, we need to create a new keypair to use with our Puppet master and node; use all default options (setting no password):

    $ ssh-keygen

  2. We will copy the key to both the Ubuntu node and the master. Use the following:

    $ ssh-copy-id cloud_user@PUBLIC_ID_OF_UBUNTU_NODE

    Once the key is added, clear the screen.

  3. Next, run the following: $ ssh-copy-id cloud_user@puppet.ec2.internal

  4. Enter y for Yes when prompted.

  5. Log in if prompted, and the key will be added.

  6. Let's now run our plan:

    $ bolt plan run base::bootstrap hostname=web1.ec2.internal node=PUBLIC_ID_OF_UBUNTU_NODE --tty --run_as root --sudo_password

    Note: We use run_as and sudo_password to switch to root. Notice, too, the use the --tty flag to create a pseudo TTY during the creation process — this prevents an error during the installation of Puppet (specially with the use of sudo bash).

  7. Enter the password from the hands-on lab page when prompted.

  8. A message stating: "plan completed successfully" with no result should appear indicating that the plan ran without any issues.

  9. If we want to confirm our work further, we can log in via SSH to the Puppet master and view the available certs:

    $ sudo puppetserver ca list --all

Conclusion

Congratulations - you've completed this hands-on lab!