Showing with 336 additions and 234 deletions.
  1. +18 −0 CHANGELOG.md
  2. 0 project.yaml → bolt-project.yaml
  3. +7 −1 documentation/convert.md
  4. +7 −1 documentation/upgrade.md
  5. +27 −0 lib/puppet/functions/peadm/plan_step.rb
  6. +1 −1 metadata.json
  7. +131 −91 plans/convert.pp
  8. +138 −134 plans/upgrade.pp
  9. +7 −6 plans/util/add_cert_extensions.pp
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# PEADM module

## 2.3.0
### Summary

Add ability to resume peadm::upgrade or peadm::convert at an intermediate step, rather than requiring re-runs to perform all plan actions from the beginning.

### Features

- Added `begin_at_step` parameter and documentation to peadm::upgrade and peadm::convert

### Bugfixes

- In peadm::convert plan, stop the Puppet agent before writing the csr\_attributes.yaml file, to prevent possible agent interference
- In the peadm::convert plan during finalization, run the Puppet agent on the primary server first, then the rest, to avoid the possibility of a puppetserver restart impacting Puppet agent runs on other systems.

### Improvements

- In the peadm::convert plan, when no peadm\_availability\_group trusted fact is present to identify if compilers should be members of the A pool or B pool, check for pp\_cluster being used to designate this configuration before falling back to a simple even/odd split. This is to catch systems provisioned with the old pe\_xl module, which used pp\_cluster to designate A/B.

## 2.2.1
### Summary

Expand Down
File renamed without changes.
8 changes: 7 additions & 1 deletion documentation/convert.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Convert infrastructure for use with the peadm module

The peadm::convert plan can be used to adopt manually deployed infrastructure for use with peadm, or to adopt infrastructure deployed with a version of peadm older than 1.0.0.
The peadm::convert plan can be used to adopt manually deployed infrastructure for use with peadm, or to adopt infrastructure deployed with an older version of peadm.

## Convert an Existing Deployment

Expand All @@ -24,3 +24,9 @@ See the [provision](provision.md#reference-architectures) documentation for a li
```
bolt plan run peadm::convert --params @params.json
```

## Retry or resume plan

This plan is broken down into steps. Normally, the plan runs through all the steps from start to finish. The name of each step is displayed during the plan run, as the step begins.

The `begin_at_step` parameter can be used to facilitate re-running this plan after a failed attempt, skipping past any steps that already completed successfully on the first try and picking up again at the step specified. The step name to resume at can be read from the previous run logs. A full list of available values for this parameter can be viewed by running `bolt plan show peadm::convert`.
8 changes: 7 additions & 1 deletion documentation/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ Pre-staging the installation media and using an inventory definition such as the
bolt plan run peadm::upgrade --params @params.json
```

## Retry or resume plan

This plan is broken down into steps. Normally, the plan runs through all the steps from start to finish. The name of each step is displayed during the plan run, as the step begins.

The `begin_at_step` parameter can be used to facilitate re-running this plan after a failed attempt, skipping past any steps that already completed successfully on the first try and picking up again at the step specified. The step name to resume at can be read from the previous run logs. A full list of available values for this parameter can be viewed by running `bolt plan show peadm::upgrade`.

## Manual Upgrades

In the event a manual upgrade is required, the steps may be followed along by reading directly from [the upgrade plan](../plans/upgrade.pp), which is itself the most accurate technical description of the steps required. In general form, the upgrade process is as given below.
Expand Down Expand Up @@ -128,5 +134,5 @@ The following steps apply _only_ if upgrading from 2019.5 or older

To upgrade to PE 2019.7 or newer from PE 2018.1:

1. Run the peadm::convert plan with `configure_node_groups = false`
1. Run the peadm::convert plan
2. Run the peadm::upgrade plan
27 changes: 27 additions & 0 deletions lib/puppet/functions/peadm/plan_step.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

Puppet::Functions.create_function(:'peadm::plan_step', Puppet::Functions::InternalFunction) do
dispatch :plan_step do
scope_param
param 'String', :step_name
block_param
end

def plan_step(scope, step_name)
first_step = scope.bound?('begin_at_step') ? scope['begin_at_step'] : nil
first_step_reached = if first_step.nil? || scope.bound?('__first_plan_step_reached__')
true
elsif step_name == first_step
scope['__first_plan_step_reached__'] = true
else
false
end

if first_step_reached
call_function('out::message', "# Plan Step: #{step_name}")
yield
else
call_function('out::message', "# Plan Step: #{step_name} - SKIPPING")
end
end
end
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "puppetlabs-peadm",
"version": "2.2.1",
"version": "2.3.0",
"author": "puppetlabs",
"summary": "Bolt plans used to deploy an at-scale Puppet Enterprise architecture",
"license": "Apache-2.0",
Expand Down
222 changes: 131 additions & 91 deletions plans/convert.pp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
Optional[String] $internal_compiler_a_pool_address = undef,
Optional[String] $internal_compiler_b_pool_address = undef,
Array[String] $dns_alt_names = [ ],

Optional[Enum[
'convert-primary',
'convert-replica',
'convert-database',
'convert-database-replica',
'convert-compilers-a',
'convert-compilers-b',
'convert-node-groups',
'finalize']] $begin_at_step = undef,
) {
# TODO: read and validate convertable PE version

Expand Down Expand Up @@ -42,6 +52,8 @@
$compiler_hosts,
)

out::message('# Gathering information')

# Get trusted fact information for all compilers. Use peadm::target_name() as
# the hash key because the apply block below will break trying to parse the
# $compiler_extensions variable if it has Target-type hash keys.
Expand Down Expand Up @@ -76,16 +88,26 @@
if $arch['high-availability'] {
$compiler_a_targets = $compiler_targets.filter |$index,$target| {
$exts = $cert_extensions[$target.peadm::target_name()]
$exts[peadm::oid('peadm_availability_group')] in ['A', 'B'] ? {
true => $exts[peadm::oid('peadm_availability_group')] == 'A',
false => $index % 2 == 0,
if ($exts[peadm::oid('peadm_availability_group')] in ['A', 'B']) {
$exts[peadm::oid('peadm_availability_group')] == 'A'
}
elsif ($exts[peadm::oid('pp_cluster')] in ['A', 'B']) {
$exts[peadm::oid('pp_cluster')] == 'A'
}
else {
$index % 2 == 0
}
}
$compiler_b_targets = $compiler_targets.filter |$index,$target| {
$exts = $cert_extensions[$target.peadm::target_name()]
$exts[peadm::oid('peadm_availability_group')] in ['A', 'B'] ? {
true => $exts[peadm::oid('peadm_availability_group')] == 'B',
false => $index % 2 != 0,
if ($exts[peadm::oid('peadm_availability_group')] in ['A', 'B']) {
$exts[peadm::oid('peadm_availability_group')] == 'B'
}
elsif ($exts[peadm::oid('pp_cluster')] in ['A', 'B']) {
$exts[peadm::oid('pp_cluster')] == 'B'
}
else {
$index % 2 != 0
}
}
}
Expand All @@ -94,107 +116,125 @@
$compiler_b_targets = []
}

# If PE version is older than 2019.7
if (versioncmp($pe_version, '2019.7.0') < 0) {
apply($master_target) {
include peadm::setup::convert_pre20197
}
}

# Modify csr_attributes.yaml and insert the peadm-specific OIDs to identify
# each server's role and availability group

run_plan('peadm::util::add_cert_extensions', $master_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/master',
peadm::oid('peadm_availability_group') => 'A',
},
)
peadm::plan_step('convert-primary') || {
# If PE version is older than 2019.7
if (versioncmp($pe_version, '2019.7.0') < 0) {
apply($master_target) {
include peadm::setup::convert_pre20197
}
}

# If the orchestrator is in use, get certs fully straightened up before
# proceeding
if $all_targets.any |$target| { $target.protocol == 'pcp' } {
run_task('peadm::puppet_runonce', $master_target)
peadm::wait_until_service_ready('orchestrator-service', $master_target)
wait_until_available($all_targets, wait_time => 120)
run_plan('peadm::util::add_cert_extensions', $master_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/master',
peadm::oid('peadm_availability_group') => 'A',
},
)
}

run_plan('peadm::util::add_cert_extensions', $master_replica_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/master',
peadm::oid('peadm_availability_group') => 'B',
},
)
peadm::plan_step('convert-replica') || {
# If the orchestrator is in use, get certs fully straightened up before
# proceeding
if $all_targets.any |$target| { $target.protocol == 'pcp' } {
run_task('peadm::puppet_runonce', $master_target)
peadm::wait_until_service_ready('orchestrator-service', $master_target)
wait_until_available($all_targets, wait_time => 120)
}

run_plan('peadm::util::add_cert_extensions', $puppetdb_database_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/puppetdb-database',
peadm::oid('peadm_availability_group') => 'A',
},
)
run_plan('peadm::util::add_cert_extensions', $master_replica_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/master',
peadm::oid('peadm_availability_group') => 'B',
},
)
}

run_plan('peadm::util::add_cert_extensions', $puppetdb_database_replica_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/puppetdb-database',
peadm::oid('peadm_availability_group') => 'B',
},
)
peadm::plan_step('convert-database') || {
run_plan('peadm::util::add_cert_extensions', $puppetdb_database_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/puppetdb-database',
peadm::oid('peadm_availability_group') => 'A',
},
)
}

run_plan('peadm::util::add_cert_extensions', $compiler_a_targets,
master_host => $master_target,
remove => ['1.3.6.1.4.1.34380.1.3.13'], # OID form of pp_auth_role
extensions => {
'pp_auth_role' => 'pe_compiler',
peadm::oid('peadm_availability_group') => 'A',
},
)
peadm::plan_step('convert-database-replica') || {
run_plan('peadm::util::add_cert_extensions', $puppetdb_database_replica_target,
master_host => $master_target,
extensions => {
peadm::oid('peadm_role') => 'puppet/puppetdb-database',
peadm::oid('peadm_availability_group') => 'B',
},
)
}

run_plan('peadm::util::add_cert_extensions', $compiler_b_targets,
master_host => $master_target,
remove => ['1.3.6.1.4.1.34380.1.3.13'], # OID form of pp_auth_role
extensions => {
'pp_auth_role' => 'pe_compiler',
peadm::oid('peadm_availability_group') => 'B',
},
)
peadm::plan_step('convert-compilers-a') || {
run_plan('peadm::util::add_cert_extensions', $compiler_a_targets,
master_host => $master_target,
remove => ['1.3.6.1.4.1.34380.1.3.13'], # OID form of pp_auth_role
extensions => {
'pp_auth_role' => 'pe_compiler',
peadm::oid('peadm_availability_group') => 'A',
},
)
}

# Create the necessary node groups in the console, unless the PE version is
# too old to support it pre-upgrade. In that circumstance, we trust that
# the existing groups are correct enough to function until the upgrade is
# performed.
if (versioncmp($pe_version, '2019.7.0') >= 0) {
apply($master_target) {
class { 'peadm::setup::node_manager_yaml':
master_host => $master_target.peadm::target_name(),
}
peadm::plan_step('convert-compilers-b') || {
run_plan('peadm::util::add_cert_extensions', $compiler_b_targets,
master_host => $master_target,
remove => ['1.3.6.1.4.1.34380.1.3.13'], # OID form of pp_auth_role
extensions => {
'pp_auth_role' => 'pe_compiler',
peadm::oid('peadm_availability_group') => 'B',
},
)
}

class { 'peadm::setup::node_manager':
master_host => $master_target.peadm::target_name(),
master_replica_host => $master_replica_target.peadm::target_name(),
puppetdb_database_host => $puppetdb_database_target.peadm::target_name(),
puppetdb_database_replica_host => $puppetdb_database_replica_target.peadm::target_name(),
compiler_pool_address => $compiler_pool_address,
internal_compiler_a_pool_address => $internal_compiler_a_pool_address,
internal_compiler_b_pool_address => $internal_compiler_b_pool_address,
require => Class['peadm::setup::node_manager_yaml'],
peadm::plan_step('convert-node-groups') || {
# Create the necessary node groups in the console, unless the PE version is
# too old to support it pre-upgrade. In that circumstance, we trust that
# the existing groups are correct enough to function until the upgrade is
# performed.
if (versioncmp($pe_version, '2019.7.0') >= 0) {
apply($master_target) {
class { 'peadm::setup::node_manager_yaml':
master_host => $master_target.peadm::target_name(),
}

class { 'peadm::setup::node_manager':
master_host => $master_target.peadm::target_name(),
master_replica_host => $master_replica_target.peadm::target_name(),
puppetdb_database_host => $puppetdb_database_target.peadm::target_name(),
puppetdb_database_replica_host => $puppetdb_database_replica_target.peadm::target_name(),
compiler_pool_address => $compiler_pool_address,
internal_compiler_a_pool_address => $internal_compiler_a_pool_address,
internal_compiler_b_pool_address => $internal_compiler_b_pool_address,
require => Class['peadm::setup::node_manager_yaml'],
}
}
}
}
else {
out::message(@("EOL"/L))
NOTICE: Node groups not created/updated as part of convert because PE \
version is too old to support them. Node groups will be updated when \
the peadm::upgrade plan is run.
| EOL
else {
out::message(@("EOL"/L))
NOTICE: Node groups not created/updated as part of convert because PE \
version is too old to support them. Node groups will be updated when \
the peadm::upgrade plan is run.
| EOL
}
}

# Run Puppet on all targets to ensure catalogs and exported resources fully
# up-to-date
run_task('peadm::puppet_runonce', $all_targets)
peadm::plan_step('finalize') || {
# Run Puppet on all targets to ensure catalogs and exported resources fully
# up-to-date. Run on master first in case puppet server restarts, 'cause
# that would cause the runs to fail on all the rest.
run_task('peadm::puppet_runonce', $master_target)
run_task('peadm::puppet_runonce', $all_targets - $master_target)
}

return("Conversion to peadm Puppet Enterprise ${arch['architecture']} succeeded.")
}
Loading