Developer updates
Find out what the Bolt team is working on and why we're making the decisions we're making.
April 2021
How Bolt loads scripts
Where we are
Currently, you can point to the location of a script or file as an absolute path
or use a Module-style load
path. Puppet
module-style paths use the syntax <module_name>/<path_to_file>
, where the <module_name>
is the
name of the module on the modulepath to load from, and <path_to_file>
is the path to the file
within the <module_name>/files/
subdirectory. For example, if you provided Bolt with
ruby_task_helper/task_helper.rb
, Bolt would find the ruby_task_helper
module on the modulepath,
and look in ruby_task_helper/files/
for the file task_helper.rb
. Similarly, when provided
powershell_task_helper/BoltPwshHelper/BoltPwshHelper.psm1
, Bolt looks in
powershell_task_helper/files/BoltPwshHelper/
for BoltPwshHelper.psm1
.
You can also load tasks and plans as first-class citizens of a module, but with a slightly
different syntax that uses double colons instead of slashes. For example, provided
the task terraform::apply
, Bolt finds the terraform
module on the modulepath and looks in
terraform/tasks
for a task called apply
(with any file extension). If you used the name
terraform::subdir::apply
, Bolt would look in terraform/tasks/subdir/
for apply
.
All of these loading methods leave out one of the most common Bolt artifacts: scripts. You can load
a script using module-style file loading, but the script needs to be in the files/
subdirectory of
a module, not the scripts/
subdirectory. It's about time scripts got their due as the Bolt
workhorses they are. That's why we're introducing a more elegant and comprehensible workflow for
sharing and loading scripts from a module. With these changes, there's no magic to understanding
where Bolt is loading a script from, and scripts are more visible as the core Bolt entities that
they are.
Where we're going
Eventually, you'll be able to load scripts and files using their fully qualified names. In other
words, you'll provide Bolt with a more specific path to the script or file within a module. Files
will remain in a module's files/
subdirectory, but scripts will live in a new scripts/
subdirectory. For example, to load a file you'll provide Bolt with <module_name>/files/myfile
. To
load a script, you'll use the syntax <module_name>/scripts/myscript.sh
.
This more detailed syntax will make scripts first-class citizens in Bolt, and disambiguate loading
files vs loading scripts from a module. Plus, it is easier to understand where files are coming from
if the fully qualified name is provided, as opposed to magically looking in the files/
directory
for a file. Once this feature is fully rolled out, the old syntax <module_name>/myfile
will
no longer load from the files/
subdirectory of a module.
How we get there 🚲
This is a big change in how Bolt loads file and scripts, so it's going to take a few different
phases to transition from where we are to where we're going. Inevitably, in order for a module to
function with older versions of Bolt, module authors will need to have scripts in two places at some
point: one under the files/
directory and one in the new location that Bolt will load from. We
know this is a burden on content authors, but we think it's worth the improved experience for users
new to the Puppet ecosystem and Bolt.
Phase 1: In this phase, fully qualified name will be opt-in using the new file_paths
project-level configuration option, which is nested under the future
key. When provided with the
following paths, Bolt will search these subdirectories in order:
-
Provided:
module/myscript.sh
Load from
files/myscript.sh
(old behavior)
-
Provided:
module/scripts/myscript.sh
Load from
files/scripts/myscript.sh
(old behavior)Fall back to
scripts/myscript.sh
(new behavior)
-
Provided:
module/files/myscript.sh
Load from
files/files/myscript.sh
(old behavior)Fall back to
files/myscript.sh
(new behavior)
Phase 2: In this phase, we'll switch the precedence of paths that Bolt searches: so Bolt will first look in the new location for a given path, and then the old location. Because this is a breaking change, it will either be gated by the same future flag as above, or will happen with a major version release.
-
Provided:
module/myscript.sh
Load from
files/myscript.sh
(old behavior)
-
Provided:
module/scripts/myscript.sh
Load from
scripts/myscript.sh
(new behavior)Fall back to
files/scripts/myscript.sh
(old behavior)
-
Provided:
module/files/myscript.sh
Load from
files/myscript.sh
(new behavior)Fall back to
files/files/myscript.sh
(old behavior)
Phase 3: In this phase, we will issue a deprecation warning when Bolt finds
a script in a files
directory, or if you provide Bolt with the old
module-style name.
-
Provided:
module/myscript.sh
Raise deprecation warning
-
Provided:
module/scripts/myscript.sh
Raise a deprecation warning if file is found at
files/scripts/myscript.sh
-
Provided:
module/files/myscript.sh
Raise a deprecation warning if file is found at
files/files/myscript.sh
Phase 4: In the final phase, Bolt will only load scripts from specific paths and will error if provided a non-specific module syntax.
-
Provided:
module/myscript.sh
Error
-
Provided:
module/scripts/myscript.sh
Load from
scripts/myscript.sh
-
Provided:
module/files/myscript.sh
Load from
files/myscript.sh
We don't have a timeline yet for when each phase will happen, beyond that Phase 1 is already in progress and should be rolled out in late-April or early-May. We will communicate when we're moving into a new phase as best we can once we are ready to move into that phase.
March 2021
Deprecating dotted fact names
With the release of Facter 4, dotted fact names are automatically converted to
structured facts. For example, the custom fact role.name = server
becomes the
following structured fact:
{
"role" => {
"name" => "server"
}
}
This is a significant change from earlier versions of Facter, which permitted dotted fact names.
Because Bolt allows you to set facts in the inventory file or during a plan run,
and uses Facter directly (such as when running the apply_prep
function) and
indirectly (such as when making a PuppetDB query), we've updated Bolt to warn
you when it detects a dotted fact name.
If Bolt detects that a target has a dotted fact name set in either the inventory or during a plan run, it displays a deprecation warning. Bolt does not automatically convert these facts to structured facts, which is inconsistent behavior with Facter 4.
To suppress these deprecation warnings, you can either update your facts or add
the dotted_fact_name
ID to the disable-warnings
option in your project
configuration.
November 2020
Changes coming in Bolt 3.0
With the new year fast approaching, the team is preparing to release the next major version of Bolt: Bolt 3.0! Over the next few releases you'll start to see deprecation warnings for specific features and configuration options that are slated for removal in Bolt 3.0. To help you prepare for the release, we've compiled a list of expected changes and removals.
Changes
-
Ship with Puppet 7
Bolt packages will ship with Puppet 7. This change should not impact most users, but changes to the Puppet language might require updating your Bolt plans.
To read more about the changes in Puppet 7, see the Puppet 7 release notes.
-
Ship with Ruby 2.7
Bolt packages will ship with Ruby 2.7 instead of Ruby 2.5.1. This change will not affect most users who install the Bolt package, as Bolt packages ship with their own Ruby. However, gem installs will require Ruby 2.7 or higher, and users who install gems with Bolt's Ruby might also need to update their gems.
-
New default modulepath
Since the introduction of the module feature in Bolt 2.30.0, Bolt has used a shorter, simpler default modulepath when a project enables the feature. Starting in Bolt 3.0, the module management feature will be enabled for all projects, meaning the default modulepath will also be updated.
To read more about the new module management workflow and the updated modulepath, see the modules overview.
-
Move PowerShell module to PowerShell Gallery
The PuppetBolt PowerShell module will be distributed through PowerShell Gallery.
-
Ship with
bolt.bat
file on WindowsBolt packages on Windows will ship with a
bolt.bat
batch file. This will disable thebolt
andInvoke-BoltCommandLine
commands in Powershell. Users should instead use the built-in PowerShell cmdlets. -
New default configuration for the local transport
In Bolt 2.x, Bolt applied the following settings to targets named
localhost
by default:targets: - name: localhost config: transport: local local: interpreters: .rb: RbConfig.ruby # This uses the Ruby we ship with Bolt features: - puppet-agent
These settings will now be applied to all targets using the local transport. Settings can be overridden at the target level in inventory. They can also be enabled or disabled starting in Bolt 2.37 using the
bundled-ruby
local transport config option. -
apply_settings
configuration option renamed toapply-settings
Most other configuration options in Bolt use hyphens instead of underscores.
For a full list of project configuration options, see the bolt-project.yaml options reference page.
-
plugin_hooks
configuration option renamed toplugin-hooks
Most other configuration options in Bolt use hyphens instead of underscores.
For a full list of project configuration options, see the bolt-project.yaml options reference page.
-
puppetfile
configuration option renamed tomodule-install
This configuration option has a confusing name that implies the path to a Puppetfile. The new name more clearly indicates that it configures how modules are installed.
For a full list of project configuration options, see the bolt-project.yaml options reference page.
target
key for YAML plan steps renamed totargets
This key has been deprecated in favor of the
targets
key.For more information about writing YAML plans, see writing YAML plans.
-
source
key for YAML planupload
step renamed toupload
This key has been deprecated in favor of the
upload
key.For more information about upload YAML plan step, see writing YAML plans.
-
private-key
andpublic-key
parameters for pkcs7 plugin renamed toprivate_key
andpublic_key
These keys have been deprecated in favor of the
private_key
andpublic_key
parameters.For more information about the
pkcs7
plugin, see the Forge documentation.
Removals
-
Packages for Debian 8 will be removed
Debian 8 reached end-of-life on June 30, 2020.
For a full list of supported platforms, see installing Bolt.
-
Support for
bolt.yaml
configuration file will be removedBolt will no longer support the
bolt.yaml
configuration file. Instead, you should usebolt-project.yaml
in your project andbolt-defaults.yaml
at the user and system level.For more information about configuring your project, see configuring Bolt.
-
bolt puppetfile *
commands and*-BoltPuppetfile
PowerShell cmdlets will be removedThese commands are being removed in favor of the new
bolt module *
commands and*-BoltModule
PowerShell cmdlets.To read more about the new module management workflow and the updated modulepath, see the modules overview.
-
Support for PowerShell 2.0 will be dropped
PowerShell 2.0 has been deprecated since 2017 and adds unecessary complexity for Bolt. Bolt will no longer support running on controllers when using PowerShell 2.0 or when connecting to remote targets running PowerShell 2.0.
-
--boltdir
command-line option will be removedThis command-line option has been deprecated in favor of
--project
. -
--configfile
command-line option will be removedThis command-line option provides little value and adds unecessary complexity to Bolt. Instead, use the
--project
command-line option to run Bolt from a specific project. -
--debug
command-line option will be removedThis command-line option has been deprecated in favor of
--log-level debug
. Additionally, Bolt now writes a debug log tobolt-debug.log
by default, removing the need to explicitly run in debug mode for most users. -
--description
command-line option will be removedThis command-line option provides little value.
-
inventoryfile
configuration option will be removedBolt already offers the
--inventoryfile
command-line option to use a non-default inventory file for a single run. However, there is little value in configuring a permanent non-default inventoryfile for a project. -
notice
log level will be removedThe
notice
log level has already been soft-deprecated. Bolt does not log any messages at this level. Messages logged in apply blocks using thenotice()
function are logged by Bolt at theinfo
level.
Updating your project
While some of these changes will require you to manually update files, others can be made automatically with Bolt. We'll be updating the project migrate command to automatically update your Bolt project to use the latest features and best practices. You can run this command now to pick up any changes that have already been made, or wait until Bolt 3.0 is released to pick up all changes at once.
To migrate your project, run the following command in your project directory:
*nix shell command
bolt project migrate
PowerShell cmdlet
Update-BoltProject
Keep in mind that this command only makes changes to a project. Changes to plans
and configuration files at the user and system level will need to be made
manually. For more information on how the migrate
command changes your project
files, see Migrate a Bolt project.
Puppet 7 Release Prep
Puppet 7 is set to be
released November 19th, 2020. While the Bolt package won't be pulling in Puppet
7 until early next year, the puppet_agent::install
task bundled with Bolt will
pick up Puppet 7 agents by default when the packages are available. This means
that using the apply_prep()
Bolt plan function or the install task directly
will be pulling in a major version bump for the agent. While we don't anticipate
any of the changes in the agent to affect Bolt users, if you find you need to
use the Puppet 6 agent, you can configure apply_prep()
and the
puppet_agent::install
task to do so.
The puppet_agent::install
task accepts a collections
parameter that tells
the task which collection to download the package from. This defaults to
puppet
which maps to the latest collection, but you can set this value to
puppet6
to pull in the latest Puppet 6 agent. You can pass this parameter on
the command line:
*nix shell command
bolt task run puppet_agent::install -t mytargets collection='puppet6'
PowerShell cmdlet
Invoke-BoltTask -Name puppet_agent::install -Targets mytargets collection='puppet6'
Or to the run_task()
plan function:
run_task('puppet_agent::install', $targets, { collection => 'puppet6' })
If you need the apply_prep()
plan function to install the Puppet 6 agents
instead of Puppet 7, you can configure this by configuring the puppet_library
plugin hook in either
bolt-project.yaml
or bolt-defaults.yaml
:
plugin_hooks:
puppet_library:
task: puppet_agent
collection: puppet6
September 2020
Module management in Bolt projects
We've recently finished work on a major improvement to Bolt projects: module management! With this improvement, you no longer need to manually manage your modules and their dependencies in a Puppetfile and can instead automate that process with Bolt.
If you want to try it out, create a project or migrate an existing project with the following command:
*nix shell command
bolt project migrate
PowerShell cmdlet
Update-BoltProject
Why are we making these changes?
So why did we make this change to how Bolt manages modules? Because managing a project's modules could be a frustrating process that includes multiple steps:
Find the module you want to add to your project
Find all of the dependencies for that module
Determine which version of each module is compatible with every other module you have installed
Manually update your Puppetfile to include each module
Install the Puppetfile
By offloading most of this work to Bolt, you now only need to list the modules you care about in your project configuration. Bolt takes care of resolving a module's dependencies and installing compatible versions. This greatly simplifies the process of managing your project's modules:
Find the module you want to add to your project
Tell Bolt to install the module with all of its dependencies
With these changes, we've also updated where Bolt installs modules. You no longer need to worry about accidentally overwriting local modules when you install a Puppetfile, because Bolt installs modules to a special directory that is not part of the configured modulepath.
The new module management feature is available starting with Bolt 2.30.0. To try it out, create a project or migrate an existing project.
Here's a summary of what's changed:
Managed module installation directory: Bolt now installs modules it manages into the
.modules/
directory instead ofmodules/
. Avoid committing.modules/
to source control. Your users can download your Bolt project and use thebolt module install
*nix shell command, orInstall-BoltModule
cmdlet to download the required modules.Non-managed module directory: Bolt no longer uses the
site-modules/
directory. Store any modules that you don't want Bolt to manage in themodules/
directory.Module configuration: Your
bolt-project.yaml
file contains amodules
key that lists the direct module dependencies of your Bolt project. Unless you need to pin a module to a specific version, avoid editing themodules
list directly. Instead, use thebolt module add
command.Puppetfile: The Puppet file is now a lock file. Bolt generates a Puppetfile each time you modify your modules with a Bolt command. Do not edit the Puppetfile directly. Instead, use Bolt commands to manage your modules, and rely on Bolt to manage the Puppetfile. You can compare a Puppetfile to a Gemfile.lock file in Ruby, or a yarn.lock file in Yarn.
modulepath: The new modulepath is
['modules']
and Bolt always appends.modules
to the modulepath.