Within a plan, you can use Bolt to apply blocks of Puppet code (manifest blocks) to remote nodes. 

Similar to the puppet apply command, which applies a standalone Puppet manifest to a local system, the Bolt apply command leverages manifest blocks to pass code to remote nodes from the command line. You can create manifest blocks that use existing content from the Forge, or mix declarative resource configuration via manifest blocks with procedural orchestration and action in a plan. Most features of the Puppet language are available in a manifest block: classes, custom resource types, and functions. For information about what language features aren't supported, see Manifest block limitations.

Tip: If you installed Bolt as a Ruby gem, make sure you have installed the core modules required to use the puppet apply command. These modules are listed in the Bolt GitHub repository and you can install them using a Puppetfile.

How manifest blocks are applied

When you run a plan that contains a manifest block, the apply_prep function installs the packages necessary to run the Bolt apply command.

The apply_prep function identifies the nodes that do not have Puppet agents and runs the puppet_agent::install task (from the puppet_agent module). It also copies over custom facts from the Bolt modulepath and runs facter on the target nodes.

Behind the scenes, Bolt compiles the code in your manifest block (the code wrapped in curly braces that follows the apply function) into a catalog. Code is compiled in the following order:
  • Facts gathered from the targets or set in your inventory.
  • Local variables in the plan, such as $site_content.
  • Vars set in your inventory.

Like the code compiled with the puppet apply function, all the variables are generated. As a result, you can reuse code between Bolt and Puppet. Bolt then copies custom module content from the Bolt modulepath to the target nodes and applies the catalog using Puppet.

After the catalog compiles and is executed successfully on all targets, apply returns the reports generated by applying the catalog on each node.

Options for Apply action

The apply action supports the following options:

  • _catch_errors => true returns a ResultSet including failed results, rather than failing the plan.

  • _noop => true applies the manifest block in Puppet no-operation mode, returning a report of the changes it would make, but takes no action.

  • _run_as => <USER> applies the manifest block as the specified user. (This option is for transports that allow a user to run commands under a different username.)

    # Preview installing docker as root on $nodes.
    apply($nodes, _catch_errors => true, _noop => true, _run_as => root) {
       include 'docker'
    }

Return value of Apply action

The apply action returns an object type ResultSet that contains ApplyResult object for each target. For more information on the methods you can call on $result, see Handling plan function results.

$results = apply($nodes) { ... }
$results.each |$result| {
   notice($result.report)
}

Configuring concurrency

Each target requires a separate catalog be compiled with its unique facts and Vars. The apply action compiles and applies catalogs in parallel on the Bolt host. Concurrency of catalog compilation is controlled by a compile-concurrency config option. This option is limited to twice the number of threads your CPU can run concurrently. Catalog application, on the other hand, uses the Bolt default thread pool controlled by the concurrency option.

Using Hiera data in a manifest block

Use Hiera to separate configuration from context-specific data, where context may be fact-based or the name of a target.

Note: Only Hiera version 5 is supported in Bolt.
Hiera is a key-value configuration data lookup system, used for separating data from Puppet code. You use Hiera data to implicitly override default class parameters. You can also explicitly lookup data from Hiera via lookup, for example:
plan do_thing() {
  apply('localhost') {
    notice("Some data in Hiera: ${lookup('mydata')}")
  }
}

Manifest block compilation can access Hiera data that you add to your Bolt configuration. The default location for Hiera config is $BOLTDIR/hiera.yaml; you can change this with the hiera-config key in a Bolt config file.

Following the Hiera 5 convention, the default data dir is relative to hiera.yaml at $BOLTDIR/data. For config file examples, see Configuring Hiera.

If a custom data provider is used (such as hiera-eyaml, which allows you to encrypt your data) the gem dependencies must be available to Bolt. See Install gems with Bolt packages.

Manifest block limitations

Exported resources are not supported in manifest blocks. You must pass exported resources directly instead of exporting and collecting them from PuppetDB. If you need to interact with resources managed during a normal run, use the function puppetdb_query.

In addition, the following top-level variables, which exist in normal catalog compilation, are not included during manifest block compilation:
  • $server_facts

  • master variables like $servername

  • $environment

You can optionally set these from a target's vars, but they don't have defaults in Bolt.

Create a sample manifest for nginx on Linux

Create a manifest that sets up a web server with nginx, and run it as a plan.

  1. Go to the site-modules directory in the default Bolt project directory: ~/.puppetlabs/bolt/site-modules
  2. Create a module named profiles.
    • If you use the Puppet Development Kit: pdk new module profiles
    • Otherwise create ~/.puppetlabs/bolt/site-modules/profiles
  3. Add a plans directory to the profiles module.
  4. In the plans directory, create a manifest file called nginx_install.pp and add the following code:
    plan profiles::nginx_install(
         TargetSpec $nodes,
         String $site_content = 'hello!',
       ) {
    
         # Install the puppet-agent package if Puppet is not detected.
         # Copy over custom facts from the Bolt modulepath.
         # Run the `facter` command line tool to gather node information.
         $nodes.apply_prep
    
         # Compile the manifest block into a catalog
         apply($nodes) {
           if($facts['os']['family'] == 'redhat') {
             package { 'epel-release':
               ensure => present,
               before => Package['nginx'],
             }
             $html_dir = '/usr/share/nginx/html'
           } else {
             $html_dir = '/var/www/html'
           }
    
           package {'nginx':
             ensure => present,
           }
    
           file {"${html_dir}/index.html":
             content => $site_content,
             ensure  => file,
           }
    
           service {'nginx':
             ensure  => 'running',
             enable  => 'true',
             require => Package['nginx']
           }
         }
       }
  5. Run the plan on a target node:
    bolt plan run profiles::nginx_install --nodes mynode.mydomain
  6. In a web browser, open mynode.mydomain

    The page displays the text hello!

Tip: For complex web server deployments, consider adding the puppet-nginx module.

Create a sample manifest for IIS on Windows

Create a manifest that sets up a web server with IIS and run it as a plan.

  1. Go to the site-modules directory in the default Bolt project directory: ~/.puppetlabs/bolt/site-modules
  2. Create a module named profiles.
    • If you use the Puppet Development Kit: pdk new module profiles
    • Otherwise create ~/.puppetlabs/bolt/site-modules/profiles
  3. Add a plans directory to the profiles module.
  4. Install the IIS dependencies.
    1. Add the following code to ~/.puppetlabs/bolt/Puppetfile
      forge 'http://forge.puppetlabs.com'
      mod 'puppetlabs-iis', '4.3.2'
      mod 'profiles', local: true
    2. Run bolt puppetfile install
  5. In the plans directory, create a manifest file called iis_install.pp and add the following code:
    plan profiles::iis_install(
         TargetSpec $nodes,
         String $site_content = 'hello!',
       ) {
    
         # Install the puppet-agent package if Puppet is not detected. 
         # Copy over custom facts from the Bolt modulepath.
         # Run the `facter` command line tool to gather node information.
         $nodes.apply_prep
    
         # Compile the manifest block into a catalog
         return apply($nodes, '_catch_errors' => true) {
           $iis_features = ['Web-WebServer','Web-Scripting-Tools']
    
           iis_feature { $iis_features:
             ensure => 'present',
           }
    
           # Delete the default website to prevent a port binding conflict.
           iis_site {'Default Web Site':
             ensure  => absent,
             require => Iis_feature['Web-WebServer'],
           }
    
           iis_site { 'minimal':
             ensure          => 'started',
             physicalpath    => 'c:\\inetpub\\minimal',
             applicationpool => 'DefaultAppPool',
             require         => [
               File['minimal'],
               Iis_site['Default Web Site']
             ],
           }
    
           file { 'minimal':
             ensure => 'directory',
             path   => 'c:\\inetpub\\minimal',
           }
    
           file { 'content':
             ensure  => 'file',
             path    => 'c:\\inetpub\\minimal\\index.html',
             content => $site_content,
           }
         }
       }
  6. Run the plan on a target node:
    bolt plan run profiles::iis_install --nodes mynode.mydomain --transport winrm
  7. In a web browser, open mynode.mydomain

    The page displays the text hello!

Using Puppet device modules from an apply statement

Puppet device modules based on remote transports allow network devices and other targets that can't run a Puppetagent to be managed from a proxy.

Note: Support for device modules is experimental and might change in future minor (y) releases.

To use device modules from an apply statement, the devices must be added to the Bolt inventory as remote targets. The name of the target will be used to auto-populate the name, uri, user, password, host, and port fields of the remote transport's connnection info. You must set the remote-transport option and any other connnection info under the remote section of config.

---
nodes:
  - name: "https://username:[email protected]"
    config:
      transport: remote
      remote:
       remote-transport: panos

When you set the run-on option with a device module, the puppet-resource_api gem be must installed with the puppet agent on the proxy target and it must be version 1.8.1 or later.

Back to top
The page rank or the 1 our of 5 rating a user has given the page.
The email address of the user submitting feedback.
The URL of the page being ranked/rated.