Showing with 2,244 additions and 33 deletions.
  1. +1 −0 .gitattributes
  2. +68 −0 README.md
  3. +80 −0 docs/basic_usage.md
  4. +75 −0 docs/classification.md
  5. +3 −0 docs/images/architecture.png
  6. +3 −0 docs/images/pe-compile-master-group-a.png
  7. +3 −0 docs/images/pe-compile-master-group-b.png
  8. +3 −0 docs/images/pe-master-a.png
  9. +3 −0 docs/images/pe-master-b.png
  10. +3 −0 docs/images/pe-xl-classification.png
  11. +28 −0 examples/ruby_task.rb
  12. +11 −0 functions/flatten_compact.pp
  13. +29 −0 functions/install_module.pp
  14. +33 −0 functions/retrieve_and_upload.pp
  15. +4 −0 installer/primary-master/csr_attributes.yaml
  16. +64 −0 installer/primary-master/pe.conf
  17. +4 −0 installer/puppetdb-database/csr_attributes.yaml
  18. +21 −0 installer/puppetdb-database/pe.conf
  19. +23 −0 lib/puppet/functions/pe_xl/file_content_upload.rb
  20. +11 −0 lib/puppet/functions/pe_xl/to_json.rb
  21. +1 −1 manifests/agent.pp
  22. +2 −2 manifests/compile_master.pp
  23. +8 −4 manifests/load_balancer.pp
  24. +55 −19 manifests/node_manager.pp
  25. +2 −2 manifests/primary_master.pp
  26. +2 −2 manifests/puppetdb.pp
  27. +3 −3 manifests/puppetdb_database.pp
  28. +21 −0 manifests/role.pp
  29. +29 −0 metadata.json
  30. +92 −0 plans/configure.pp
  31. +91 −0 plans/init.pp
  32. +231 −0 plans/install.pp
  33. +44 −0 plans/misc/divert_code_manager.pp
  34. +149 −0 plans/upgrade.pp
  35. +17 −0 tasks/agent_install.json
  36. +7 −0 tasks/agent_install.sh
  37. +13 −0 tasks/agent_upgrade.json
  38. +5 −0 tasks/agent_upgrade.sh
  39. +17 −0 tasks/code_manager.json
  40. +167 −0 tasks/code_manager.sh
  41. +33 −0 tasks/configure_node_groups.json
  42. +200 −0 tasks/configure_node_groups.sh
  43. +4 −0 tasks/divert_code_manager.json
  44. +20 −0 tasks/divert_code_manager.pp
  45. +17 −0 tasks/download.json
  46. +12 −0 tasks/download.sh
  47. +17 −0 tasks/enable_replica.json
  48. +20 −0 tasks/enable_replica.sh
  49. +13 −0 tasks/filesize.json
  50. +10 −0 tasks/filesize.sh
  51. +8 −0 tasks/hostname.json
  52. +6 −0 tasks/hostname.sh
  53. +33 −0 tasks/mkdir_p_file.json
  54. +19 −0 tasks/mkdir_p_file.sh
  55. +8 −0 tasks/orchestrator_healthcheck.json
  56. +22 −0 tasks/orchestrator_healthcheck.sh
  57. +21 −0 tasks/pe_install.json
  58. +31 −0 tasks/pe_install.sh
  59. +17 −0 tasks/provision_replica.json
  60. +18 −0 tasks/provision_replica.sh
  61. +13 −0 tasks/puppet_runonce.json
  62. +27 −0 tasks/puppet_runonce.sh
  63. +13 −0 tasks/rbac_token.json
  64. +33 −0 tasks/rbac_token.rb
  65. +17 −0 tasks/run_puppet_w_master.json
  66. +101 −0 tasks/run_puppet_w_master.rb
  67. +5 −0 templates/autosign.conf.epp
  68. +56 −0 templates/primary_master-pe.conf.epp
  69. +24 −0 templates/puppetdb_database-pe.conf.epp
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.png filter=lfs diff=lfs merge=lfs -text
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Puppet Enterprise Extra Large

This Puppet module contains profile classes used to deploy an at-scale Puppet Enterprise architecture.

It SHOULD contain instructions for how to set that all up, too. Right now it doesn't. Big To-do.

Note pending more detailed instructions:

* This deployment depends on and assumes the use of trusted facts. Specifically, `pp_role` and `pp_environment`.
* This deployment assumes that at least for PE infrastructure nodes, Puppet certnames are correct, resolvable FQDNs.
* This deployment assumes the control repository to manage PE is independent of the normal "customer" control-repo.

## Documentation

See this README file and any documents in the [docs](docs) directory.

## Architecture

![architecture](docs/images/architecture.png)

## Installation

These are just sketched out instructions right now. It's likely there are big gaps still.

### Prepare the Control Repositories

You'll need two control repositories configured. One dedicated to managing Puppet Enterprise nodes (consider it kinda like an appliance), and another for your regular Puppet code used to manage your infrastructure.

### Installing the Primary Master

1. Download and extract the Puppet Enterprise installer
2. Place the csr\_attributes.yaml file from installer/primary-master in /etc/puppetlabs/puppet/csr\_attributes.yaml
3. Place the pe.conf file from installer/primary-master in the working directory, and edit it to fill in required values
4. Run the installer, passing the appropriate flags to use the prepared pe.conf file
5. Set up the ssh private keys needed to access the configured control repositories
6. For each environment configured (however many you want to initially deploy), run e.g.

puppet code deploy production --wait
puppet code deploy pe_production --wait

7. Using the same list of environments deployed above, run e.g.

puppet apply --environment pe_production --exec '
class { "pe_xl::node_manager":
environments => ["production", "pe_production"],
}
'

5. Perform the PuppetDB Database installation (described below)
6. Run `puppet agent -t`

### Installing the PuppetDB Database

1. Download and extract the Puppet Enterprise installer
2. Place the csr\_attributes.yaml file from installer/puppetdb-database in /etc/puppetlabs/puppet/csr\_attributes.yaml
3. Place the pe.conf file from installer/puppetdb-database in the working directory, and edit it to fill in required values
4. Run the installer, passing the appropriate flags to use the prepared pe.conf file
5. Finish the Primary Master installation (described above)
6. Run `puppet agent -t`

### Installing a Compile Master

```
curl -k https://primary-master.example.com:8140/packages/current/install.bash | sudo bash -s \
main:certname=<certname> \
extension_requests:pp_role="pe_xl::compile_master" \
extension_requests:pp_environment="pe_production"
```
80 changes: 80 additions & 0 deletions docs/basic_usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Basic usage

This is a base reference implementation. Once a base stack is stood up, you may need to continue and perform additional configuration and adjustments to reach your target state, depending on your use case.

The reference implementation currently includes Task Plans to install, configure, and later upgrade a new Extra Large HA stack.

The current versions of those plans can be found at:

* [install.pp](https://github.com/reidmv/reidmv-pe_xl/blob/master/plans/install.pp)
* [configure.pp](https://github.com/reidmv/reidmv-pe_xl/blob/master/plans/configure.pp)
* [upgrade.pp](https://github.com/reidmv/reidmv-pe_xl/blob/master/plans/upgrade.pp)

These are still a work in progress and lack documentation. Reading through them can give you an idea of what steps we've found to be required to deploy and configure all of the Puppet Enterprise components.

Besides getting everything installed the key configuration that makes this work is laid out in four classification groups. Links provided below to a Markdown document that describes the groups, and also to the Puppet manifest that actually configures them:

* [classification.md](https://github.com/reidmv/reidmv-pe_xl/blob/master/docs/classification.md)
* [configure\_node\_groups.pp](https://github.com/reidmv/reidmv-pe_xl/blob/master/tasks/configure_node_groups.pp)

The reference implementation uses trusted facts to put nodes in the right groups. Because the important puppet\_enterprise::\* class parameters and data are specified in the console, it should also be safe to have a pe.conf present on both the primary master, and the primary master replica nodes.

## Basic usage instructions

1. Ensure the hostname of each system is set correctly, to the same value that will be used to connect to the system, and refer to the system as. If the hostname is not set as expected the installation plan will refuse to continue.
2. Install Bolt on a jumphost. This can be the primary master, or any other system.
3. Download or git clone the pe\_xl module and put it somewhere on the jumphost, e.g. ~/modules/pe\_xl.
4. Create an inventory file with connection information. Example included below. Available Bolt configuration options are documented here.
5. Create a parameters file. Example included below. Note at the top of the file are arguments which dictate which plans should be run, such as install+configure.
6. Run the pe\_xl plan with the inputs created. Example:

bolt plan run pe_xl \
--inventory nodes.yaml \
--modulepath ~/modules \
--params @params.json

Example nodes.yaml Bolt inventory file:

```yaml
---
groups:
- name: pe_xl_nodes
config:
transport: ssh
ssh:
host-key-check: false
user: centos
run-as: root
tty: true
nodes:
- pe-xl-core-0.lab1.puppet.vm
- pe-xl-core-1.lab1.puppet.vm
- pe-xl-core-2.lab1.puppet.vm
- pe-xl-core-3.lab1.puppet.vm
- pe-xl-compilemaster-0.lab1.puppet.vm
- pe-xl-compilemaster-1.lab1.puppet.vm
```
Example params.json Bolt parameters file:
```json
{
"install": true,
"configure": true,
"upgrade": false,

"primary_master_host": "pe-xl-core-0.lab1.puppet.vm",
"puppetdb_database_host": "pe-xl-core-1.lab1.puppet.vm",
"primary_master_replica_host": "pe-xl-core-2.lab1.puppet.vm",
"puppetdb_database_replica_host": "pe-xl-core-3.lab1.puppet.vm",
"compile_master_hosts": [
"pe-xl-compilemaster-0.lab1.puppet.vm",
"pe-xl-compilemaster-1.lab1.puppet.vm"
],

"console_password": "puppetlabs",
"dns_alt_names": [ "puppet", "puppet.lab1.puppet.vm" ],
"compile_master_pool_address": "puppet.lab1.puppet.vm",
"version": "2018.1.4"
}
```
75 changes: 75 additions & 0 deletions docs/classification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# PE Extra Large architecture classification #

## Overview

This reference implementation uses four non-default node classification groups to implement the Extra Large HA architecture. Intentionally, classification of default, out-of-box node groups is not modified. This allows normal commands such as `puppet infrastructure enable replica` to behave more or less exactly as they would in Standard or Large architecture deployments.

This image shows a fully expanded view of the PE Infrastructure node group, highlighting the new additions made to support the Extra Large archtecture.

![PE Classification tree](images/pe-xl-classification.png)

## Node Groups

The new groups are:

* PE Master A
* PE Master B
* PE Compile Master Group A
* PE Compile Master Group B

The configuration applied in each group looks as follows:

### PE Master A

![PE Master A group](images/pe-master-a.png)

Notes for PE Master A:

* The (initial) Primary Master is the only member of this node group
* Sets as data two parameters
* `puppet_enterprise::profile::primary_master_replica::database_host_puppetdb`
* `puppet_enterprise::profile::puppetdb::database_host`
* Sets both parameters to the name of the PuppetDB PostgreSQL node paired with this master
* Uses a different PuppetDB PostgreSQL node than PE Master B

### PE Master B
![PE Master B group](images/pe-master-b.png)

Notes for PE Master B:

* The (initial) Primary Master Replica is the only member of this node group
* Sets as data two parameters
* `puppet_enterprise::profile::primary_master_replica::database_host_puppetdb`
* `puppet_enterprise::profile::puppetdb::database_host`
* Sets both parameters to the name of the PuppetDB PostgreSQL node paired with this master
* Uses a different PuppetDB PostgreSQL node than PE Master A

### PE Compile Master Group A
![PE Compile Master Group A group](images/pe-compile-master-group-a.png)

Notes for PE Compile Master Group A:

* Half of the compile masters are members of this group
* Applies the `puppet_enterprise::profile::puppetdb` class
* Sets the `puppet_enterprise::profile::puppetdb::database_host` parameter
* Should be set to `"pdb-pg-a"`, where "pdb-pg-a" is the name of the PuppetDB PostgreSQL database host paired with the (initial) Primary Master
* Modifies the `puppet_enterprise::profile::master::puppetdb_host` parameter
* Should be set to `[${clientcert}, "master-b"]`, where "master-b" is the name of the (initial) Primary Master Replica.
* If you have a load balancer for the compile masters in PE Compile Master Group B port 8081, you should use that load balancer address instead of "master-b"
* Modifies the `puppet_enterprise::profile::master::puppetdb_port` parameter
* Should be set to `[8081]`

### PE Compile Master Group B
![PE Compile Master Group B group](images/pe-compile-master-group-b.png)

Notes for PE Compile Master Group B:

* The other half of the compile masters (those not in the PE Compile Master Group A node group) are members of this group
* Applies the `puppet_enterprise::profile::puppetdb` class
* Sets the `puppet_enterprise::profile::puppetdb::database_host` parameter
* Should be set to `"pdb-pg-b"`, where "pdb-pg-b" is the name of the PuppetDB PostgreSQL database host paired with the (initial) Primary Master Replica
* Modifies the `puppet_enterprise::profile::master::puppetdb_host` parameter
* Should be set to `[${clientcert}, "master-a"]`, where "master-a" is the name of the PuppetDB PostgreSQL node paired with the (initial) Primary Master Replica.
* If you have a load balancer for the compile masters in PE Compile Master Group A port 8081, you should use that load balancer address instead of "master-a"
* Modifies the `puppet_enterprise::profile::master::puppetdb_port` parameter
* Should be set to `[8081]`
3 changes: 3 additions & 0 deletions docs/images/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/pe-compile-master-group-a.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/pe-compile-master-group-b.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/pe-master-a.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/pe-master-b.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/images/pe-xl-classification.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions examples/ruby_task.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/opt/puppetlabs/puppet/bin/ruby
require 'json'
require 'logger'
require 'open3'

# Parameters expected:
# Hash
# String mom_host
# String database_host
# Boolean debug
$params = JSON.parse(STDIN.read)

$logger = Logger.new(STDOUT)
$logger.level = $params['debug'] ? Logger::DEBUG : Logger::INFO

def main
end

def run_command(*command)
stdout, status = Open3.capture2(*command)
unless status.success?
@logger.error "while running command: #{command}"
@logger.error stdout
end
stdout
end

main
11 changes: 11 additions & 0 deletions functions/flatten_compact.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function pe_xl::flatten_compact (
Array $input,
) {
$input.flatten.reduce([]) |$output, $value| {
if ($value == undef) {
$output
} else {
$output << $value
}
}
}
29 changes: 29 additions & 0 deletions functions/install_module.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function pe_xl::install_module(
String[1] $target,
String[1] $module,
String[1] $version,
String[1] $stagingdir = '/tmp',
) {

$module_tarball = "${module.regsubst('/', '-')}-${version}.tar.gz"

pe_xl::retrieve_and_upload(
"https://forge.puppet.com/v3/files/${module_tarball}",
"${stagingdir}/${module_tarball}",
"/tmp/${module_tarball}",
$target
)

run_command(@("HEREDOC"), $target)
/opt/puppetlabs/bin/puppet module install \
--modulepath /etc/puppetlabs/code-staging/environments/production/modules \
--ignore-dependencies \
/tmp/$module_tarball
| HEREDOC

run_command('chown -R pe-puppet:pe-puppet /etc/puppetlabs/code-staging', $target)
run_task('pe_xl::code_manager', $target,
action => 'commit',
)

}
33 changes: 33 additions & 0 deletions functions/retrieve_and_upload.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function pe_xl::retrieve_and_upload(
$source,
$local_path,
$upload_path,
$target,
) {
$exists = without_default_logging() || {
run_command("test -e '${local_path}'", 'local://localhost',
_catch_errors => true,
).ok()
}

unless $exists {
run_task('pe_xl::download', 'local://localhost',
source => $source,
path => $local_path,
)
}

$local_size = run_task('pe_xl::filesize', 'local://localhost',
path => $local_path,
).first['size']

$targets_needing_file = run_task('pe_xl::filesize', $target,
path => $upload_path,
).filter |$result| {
$result['size'] != $local_size
}.map |$result| {
$result.target
}

upload_file($local_path, $upload_path, $targets_needing_file)
}
4 changes: 4 additions & 0 deletions installer/primary-master/csr_attributes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
extension_requests:
pp_role: "pe_xl::primary_master"
pp_environment: "pe_production"
Loading