pe_bulk_agent_install
Version information
This version is compatible with:
- Puppet Enterprise 2017.2.x, 2017.1.x, 2016.5.x, 2016.4.x
- Puppet >=4.2.3 <5.0.0
- , , , , , , , ,
Start using this module
Add this module to your Puppetfile:
mod 'puppetlabs-pe_bulk_agent_install', '1.1.0'
Learn more about managing modules with a PuppetfileDocumentation
PE Bulk Agent Install
Puppet toolkit for rapidly installing Puppet agents in Puppet Enterprise
Table of Contents
- Overview
- Module State
- Command Line Usage
- Installation Requirements
- Simple SSH agent deployment
- Credentials
- Fixing DNS and NTP on agent nodes
- Windows
- Reference
- Limitations
- Maintainers
Overview
This module is used for bulk installs of Puppet Agents on Linux and Windows machines with Puppet Enterprise. It builds on the standard Simplified Agent Installation process that comes with Puppet Enterprise.
The goal of this module is to accomplish the following tasks, rapidly and remotely, on Linux and Windows nodes:
- Install the Puppet agent
- Start the Puppet Agent
Module State
NOTE: This module started as a Puppet Professional Services toolkit. It is a side project, and it is currently neither officially maintained nor officially supported by Puppet, Inc. It may not function as expected; however, it is actively used in the wild so issues are likely to be resolved if found and reported. Have fun!
Command Line Usage
This module ships a Puppet face, puppet bulk install
. The face can be used with any
system that supports SSH to allow for the mass installation of Puppet agent nodes using
the simplified installer bundled with Puppet Enterprise.
Example CLI usage can be found in the examples folder of this module.
All possible CLI flags can be seen in the Command Line Options section.
For Windows nodes, a separate method that uses a PowerShell script should be used. See the docs here.
Installation Requirements
Chloride Gem
The Puppet face requires the chloride gem to be in place in the Puppet ruby stack (not puppetserver) of the node that will be executing the Puppet face. This could be your Puppet master or some other Puppet agent that is able to connect to the soon-to-be Puppet agents.
Install Chloride using one of these methods:
-
Automatically, with Puppet:
include pe_bulk_agent_install::chloride
-
Manually, into Puppet's Ruby stack:
/opt/puppetlabs/puppet/bin/gem install chloride --no-ri --no-rdoc
Future versions of Puppet Enterprise (2017'ish) will likely ship with Chloride built-in to Puppet's Ruby stack on the master.
pe_repo
Because the Bulk Agent Installer face leverages the built-in Simplified Agent Installer of Puppet Enterprise, it's important that the
simplified agent installer is setup accordingly. Namely, make sure that your Puppet master has the correct pe_repo::platform
classes
applied to it before attempting to run the Bulk Agent Installer.
Documentation for doing this is available here: https://docs.puppet.com/pe/latest/install_agents.html#install-agents-with-a-different-os-and-architecture-than-the-puppet-master
Simple SSH agent deployment
sudo puppet bulk install unprovisioned-agent1 unprovisioned-agent2 \
--credentials ./examples/json/sudo_install.json \
--debug
This invocation would connect to unprovisioned-agent1 and unprovisioned-agent2
node and execute the simplified agent installer. The credentials for the SSH
connection should be contained in the JSON file passed with --credentials
.
In the event other authentication methods fail, the user will be prompted for the password by the installer libraries. This may allow for some systems such as two factor to be used however it likely will be cumbersome on large numbers of nodes.
This may stop an unattended installation waiting for input. Ensure your credentials are correct.
Simple SSH agent deployment with nodes file
sudo puppet bulk install \
--nodes ./examples/el_nodes.txt \
--credentials ./examples/json/sudo_install.json --trace --debug
This assumes a file that contains node names with newline character separating each
Simple SSH agent deployment with nodes STDIN
#!/bin/bash
printf '%s\n%s\n%s\n' unprovisioned-agent1 unprovisioned-agent2 unprovisioned-agent4 |
sudo puppet bulk install \
--nodes - \
--credentials ./examples/json/sudo_install.json --trace --debug
You can build your own custom scripts to add agent nodes to the install list and pass them in via STDIN. I.e. you can ping the nodes and only echo them if they respond.
Multiple thread support
puppet bulk install
supports a --threads
argument which defaults to the number of processors on the bastion host times 2.
You can increase or decrease this to control the load on your masters and bastion host running the SSH sessions.
Credentials
Authentication credentials must be specified as a JSON hash and passed in a file to --credentials
:
puppet bulk install --credentials bulk_install.json
By default, a credentials file named bulk_install.json
is looked for and parsed if --credentials
is not used.
The credentials JSON must be a hash containing the following keys:
Key Name | Description |
---|---|
username | (required) Username for the SSH connection to the agent |
master | (required) FQDN of the Puppet master |
sudo_password | Password used for SSH login and sudo escalation |
ssh_key_file | Path to SSH private key if using key-based auth |
ssh_key_password | SSH passphrase for the private key |
arguments | Hash of Puppet configs, CSR attributes, and/or extension requestss |
Sudo + Password
{
"username": "provisioner",
"sudo_password": "p_4_s_s_w_0_r_d",
"master" : "pe-201620-master"
}
This assumes a user named provisioner
with sudo access exists on the target agent system. The agent node will run the Simplified
Agent Installer from the Puppet master named pe-201620-master. The master's hostname must be resolvable and reachable by the agent node as
it is used in the yum/apt repos. Ensure your site has proper DNS or /etc/hosts entries configured for the Puppet master.
Sudo + Private key w/ no passphrase
{
"username": "provisioner",
"ssh_key_file": "/root/.ssh/id_rsa",
"master" : "pe-201620-master"
}
This assumes a private key is installed and readable on the machine running the CLI (with no passphrase set), and that it corresponds
to an authorized_key file on the target host using the username provisioner
(who has sudo access that doesn't require a password).
Root + Private key w/ no passphrase
{
"username": "root",
"ssh_key_file": "/root/.ssh/id_rsa",
"master" : "pe-201620-master"
}
This assumes a private key is installed and readable on the machine running the CLI (with no passphrase set), and that the key corresponds to an authorized_key file on the target agent using the username root.
Root + Private key w/ passphrase
{
"username": "root",
"ssh_key_file": "/root/.ssh/id_rsa",
"ssh_key_passphrase": "freyjaIscute",
"master" : "pe-201620-master"
}
This assumes a private key is installed and readable on the machine running the CLI (with a passphrase set), and that it corresponds to an authorized_key file on the target host using the username root.
Puppet Config Arguments and CSR Attributes
{
"username": "root",
"ssh_key_file": "/root/.ssh/id_rsa",
"master" : "pe-201620-master",
"arguments" :
{
"agent": { "environment": "development" },
"custom_attributes": { "challengePassword": "imyourpuppet" },
"extension_requests": { "pp_role": "gitlab_runner" }
}
}
Using the arguments key of the json file, you can specify puppet.conf settings, CSR attributes, and extension requests. They will be passed to the bash installer as arguments to -s
.
Refer to the Puppet Enterprise install script docs on possible options that can be specified here:
Fixing DNS and NTP on agent nodes
Ideally your environment will have correct DNS and Time synchronized ahead of the Puppet Enterprise installation by way of your preseed/kickstart/sysprep provisioning process. In the event that you need to update this information, you can have the bulk install tool copy a script to the agent and execute it before installing Puppet. That script could setup DNS and NTP.
Use the --script
option of the CLI to do this as shown below.
sudo puppet bulk install \
--nodes el_nodes.txt \
--credentials sudo_install.json \
--debug
--script 'setup_prerequisites.sh'
This will download the setup_prerequisites.sh
script to the soon-to-be agent and execute it.
Note at the time of this writing you may need to build a custom wrapper script to pass this script arguments.
Windows
Setup
To use this module for Windows agents, things are a bit different, and you'll need to setup some prerequisites first. You'll need:
- An existing Windows agent that will act as a Windows bastion.
- WinRM configured on the Windows bastion and your soon-to-be Windows agents.
Note: Configuration of WinRM is out-of-scope for this module at this time and must be manually setup prior to attempting to use this tool. This link may help: https://msdn.microsoft.com/en-us/library/aa384372(v=vs.85).aspx
This module comes with a PowerShell script, called Invoke-PuppetAgentInstall.ps1
that will connect to Windows nodes via WinRM and execute
the standard Simplified Agent installer for Windows
that comes bundled with Puppet Enterprise. The Invoke-PuppetAgentInstall.ps1
script is managed on the Windows bastion with the
pe_bulk_agent_install::windows::bastion
class.
To prepare a Windows bastion, follow these steps, choosing the correct set based on your version of Puppet Enterprise:
PE 2016.3.x and higher
- Apply the
pe_repo::platform::windows_<arch>
class to the Puppet master and run Puppet. This will prepare the Puppet agent MSI package and the Simplified Agent Installer for Windows. - Apply the
pe_bulk_agent_install::windows::bastion
class to the Windows bastion server. This creates the WinRM installer script (by default, atC:\Windows\Temp\Invoke-PuppetAgentInstall.ps1
).
PE 2016.2.x and lower
- Apply the
pe_repo::platform::windows_<arch>
class to the Puppet master and run Puppet. This will prepare the Puppet agent MSI package. - Apply the
pe_bulk_agent_install::windows::master
class to the Puppet master and run Puppet. This will prepare a copy of the Simplified Agent Installer for Windows. - Apply the
pe_bulk_agent_install::windows::bastion
class to the Windows bastion server. This creates the WinRM installer script (by default, atC:\Windows\Temp\Invoke-PuppetAgentInstall.ps1
).
Note: The Simplified Agent Installer for Windows was added in PE 2016.3.0, hence the additional step for older versions.
Usage
Below are examples of using the Invoke-PuppetAgentInstall.ps1
script in various scenarios.
See the pe_bulk_agent_install::windows::bastion
class documentation for how to customize the Windows bastion.
See the WinRM Install Script documentation for options that can be passed into the script.
Single-agent
The Agent argument supports hostname or IP Address.
.\Invoke-PuppetAgentInstall.ps1 -Node fqdn.example.com -PMHostname master.puppet.vm
Pass Windows credentials
Credentials associated with a Windows user account.
.\Invoke-PuppetAgentInstall.ps1 -Credential MYDOMAIN\Administrator -PMHostname master.puppet.vm
Multiple agents (using agents.txt)
Placing the FQDN of each of the respective agents in a file called agents.txt
in the same directory as the script.
.\Invoke-PuppetAgentInstall.ps1 -PMHostname master.puppet.vm
Multiple agents (using provided file)
Placing the FQDN of each of the respective agents in a file of your choosing then referencing said file with the FilePath
argument.
.\Invoke-PuppetAgentInstall.ps1 -FilePath C:\ProgramData\nodes_list.txt -PMHostname master.puppet.vm
Caveats
Domain Member vs Standalone System
Regardless if the system running the remote script is a domain member or a standalone system, an entry for the each remote system will be created in the Trusted Hosts file.
If this is not a desired result, at the completion of the distributed install script execution you can clean out the Trusted Hosts file. One method to complete this task programmatically is as follows:
Use PowerShell to clear the Trusted Hosts file
Reference
Command Line Options
The bulk installer face accepts options from the command line as shown below.
--credentials=
The relative or absolute path to a JSON file containing the credentials information.
- Default:
bulk_install.json
--sudo
A boolean flag that specifies weather or not to run the installation scripts with sudo
on Linux/Unix hosts.
Sudo is automatically used if the credentials hash contains a sudo_password
key or a non root username.
--threads=
The number of threads to use for concurrent agent installations.
- Default: Number of processors times 2.
--script=
The name of the Puppet Enterprise agent installation script to run by default.
- Default:
install.bash
--nodes=
The relative or absolute path to a new line separated file containing node names to install Puppet on.
- Default:
nodes.txt
Class Usage
pe_bulk_agent_install::windows::bastion
This class is expected to be installed on a Windows node that has had Puppet manually installed. This "bastion" host will connect to unprovisioned Windows nodes.
master
- Type:
String
- Default:
$::settings::server
The hostname of the Puppet master where the client will register its certificate.
master_port
- Type:
Integer[0,65535]
- Default:
8140
The port number that puppetserver is listening on.
scripts_install_location
- Type:
String
- Default:
C:/Windows/Temp
The directory to put the Invoke-PuppetAgentInstall.ps1
WinRM install script on the Windows bastion.
script_name
- Type:
String
- Default:
install.ps1
The name of the simplified agent install script Invoke-PuppetAgentInstall will attempt to execute.
WinRM Script Arguments
The WinRM script, Invoke-PuppetAgentInstall.ps1
, accepts the following command line arguments.
Node
A comma-separated list of node names to install Puppet on. The node names must be resolvable by the Windows bastion running this script.
Mutually exclusive with the FilePath
argument.
- Type:
String
- Default:
$null
Credential
The username used to authenticate to the unprovisioned Windows agent.
- Type:
String
- Default:
$null
FilePath
The relative or absolute path to a new-line separated file containing node names to install Puppet on.
Mutually exclusive with the Node
argument.
- Type:
String
- Default:
nodes.txt
LogPath
The relative or absolute path to the log file used by this script.
- Type:
String
- Default:
pe_bulk_agent_install.log
InstallScript
The name of the Simplified Agent Install script on the Puppet master.
- Type:
String
- Default:
install.ps1
InstallDest
The full path to where the Simplified Agent Install script will be copied to the unprovisioned Windows agent.
- Type:
String
- Default:
C:\Windows\Temp\install.ps1
PMHostname
The FQDN of the Puppet Master that the Windows agent will communicate with.
- Type:
String
- Default: The FQDN of the Puppet Master that manages the Windows bastion
Maintainers
This repository is largely the work of the Puppet Professional Services team. It is not officially maintained by Puppet, or any individual in particular. Issues should be opened in GitHub. Questions should be directed at the individuals responsible for committing that particular code.
The list of contributors to this module can be found here: https://github.com/puppetlabs/puppet-pe_bulk_agent_install/graphs/contributors
Change Log
v1.1.0 (2017-02-26)
Implemented enhancements:
- Manage the chloride gem #5
- The
windows::master
class will now fail if applied to a non Puppet master node cf94df30
Merged pull requests:
- README cleanup and improvements
- Enabled Travis-CI automated testing #2
- Other various code style and cleanup PR's
v1.0.0 (2017-01-12)
This is the first publicly available release. It provides initial implementations for bulk installing Puppet Agents on POSIX (EL and Debian) and Windows hosts.
Dependencies
- puppetlabs-stdlib (>=4.5.0 <5.0.0)
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.