Defining plan permissions

RBAC for plans is distinct from RBAC for individual tasks. This distinction means that a user can be excluded from running a certain task, but still have permission to run a plan that contains that task.

The RBAC structure for plans allows you to write plans with more robust, custom control over task permissions. Instead of allowing a user free rein to run a task that can potentially damage your infrastructure, you can wrap a task in a plan and only allow them to run it under circumstances you control.

For example, if you are configuring permissions for a new user to run plan infra::upgrade_git, you can allow them to run the package task but limit it to the git package only.

plan infra::upgrade_git (
  TargetSpec $targets,
  Integer $version,
) {
  run_task(‘package’, $targets, name => ’git’, action => ‘upgrade’, version => $version)
}

Use parameter types to fine-tune access

Parameter types provide another layer of control over user permissions. In the upgrade_git example above, the plan only provides access to the git package, but the user can choose whatever version of git they want. If there are known vulnerabilities in some versions of the git package, you can use parameter types like Enum to restrict the version parameter to versions that are safe enough for deployment.

For example, the Enum restricts the $version parameter to versions 1:2.17.0-1ubuntu1 and 1:2.17.1-1ubuntu0.4 only.

plan infra::upgrade_git (
  TargetSpec $targets,
  Enum['1:2.17.0-1ubuntu1', '1:2.17.1-1ubuntu0.4'] $version,
) {
  run_task(‘package’, $targets, name => ‘git’, action => ‘upgrade’, version => $version)
}

You can also use PuppetDB queries to select parameter types.

For example, if you need to restrict the targets that infra::upgrade_git can run on, use a PuppetDB query to identify which targets are selected for the git upgrade.

plan infra::upgrade_git (
   Enum['1:2.17.0-1ubuntu1', '1:2.17.1-1ubuntu0.4'] $version,
) {
  # Use puppetdb to find the nodes from the “other” team's web cluster
  $query = [from, nodes, ['=', [fact, cluster], "other_team"]]
  $selected_nodes = puppetdb_query($query).map() |$target| {
    $target[certname]
  }
  run_task(‘package’, $selected_nodes, name => ‘git’, action => ‘upgrade’, version => $version)
}