Node Sets
Node Sets are how you tell the playbook about groups of nodes that exist on your network, today you can use MCollective Discovery, PQL Queries, YAML files, Shell Scripts and Terraform outputs to create the node sets.
In all cases the node sets must produce a list of certnames that will match what MCollective expects, in cases where you want to use MCollective based tasks. In the future task types will be pluggable and you just have to produce whatever node sets your type of task needs.
Common Node Set options
There are a few common options you can supply to all node sets, here’s a sample shell discovery with some common options set, these apply to all discovery types:
$nodes = choria::discover("shell",
"script" => "/usr/local/bin/nodes.sh",
"at_least" => 1,
"when_empty" => "Could not find any nodes from nodes.sh",
"limit" => 10,
"test" => true,
"uses" => {
"appmgr" => "> 1.0.1"}
}
)
Option | Description | Sample |
---|---|---|
at_least | Fail if not at least this many nodes found | at_least => 10 |
when_empty | A custom error message when no nodes are found | when_empty => "Could not find any web servers" |
limit | Accept only this many nodes from the discovery source, if more are found, discard the excess ones | limit => 10 |
test | When true performs a mco rpc rpcutil ping against the discovered nodes to ensure they are operational | test => true |
uses | Use MCollective to audit the discovered nodes and ensure the stated agents conform to the SemVer specification given | |
empty_ok | Typically when no nodes are found an error is raised, you might want to retry discovery till you find a node, this enables that (since 0.16.0) | empty_ok => true |
MCollective Nodes
The most basic MCollective node set can be:
$nodes = choria::discover(
"discovery_method" => "choria",
"test" => true,
"classes" => ["apache"],
"uses" => {"rpcutil" => "~ 1.0.0"},
"facts" => ["country=uk"]
)
You can also make it explicit that this is an mcollective type discovery:
$nodes = choria::discover("mcollective",
"discovery_method" => "choria",
"test" => true,
"classes" => ["apache"],
"uses" => {"rpcutil" => "~ 1.0.0"}
)
This tells it to use the MCollective choria discovery method and since that is based on PuppetDB I set test => true
to cause it to ping the nodes it discovered to verify their connectivity.
It uses a classes filter to limit the nodes, other examples below, and declare these nodes to use the rpcutil agent.
The rpcutil agent above in the uses section is specified as needing version ~ 1.0.0 - a SemVer range - and it will verify that this is true on the discovered nodes.
Option | Description | Sample |
---|---|---|
discover_method | Which MCollective Discovery plugin to use, see mco plugin doc for a list | discovery_method => choria |
identities | Discover nodes with these identities, corresponds to the MCollective CLI -I flag | identities => ["/dev/"] |
classes | Discover nodes with these classes, corresponds to the MCollective CLI -C flag | classes => [“apache”] |
agents | Discover nodes with these agents, corresponds to the MCollective CLI -A flag | agents => [“puppet”] |
facts | Discover nodes with these facts, corresponds to the MCollective CLI -F flag | facts => [“country=uk”] |
compound | Discover nodes that match a compound query, forces the mc discovery method, corresponds to the MCollective CLI -S flag | compound => “fstat(’/etc/hosts’).md5=/baa3772104/ and environment=development” |
uses | A list of agents to this node set should have, references a previous declared agent in the uses section. Will be confirmed prior to running the playbook | uses => {“rpcutil” => “~ 1.0.0”} |
YAML Nodes
A YAML file is supported as an input format, it can have groups inside it like the example here:
web_servers:
- node1.example.net
- node2.example.net
db_servers:
- db1.example.net
- db2.example.net
Put this in a file and you can use it as a Node Set source:
$nodes = choria::discover("yaml",
"group" => "web_servers",
"source" => "/etc/your_co/nodes.yaml"
)
Option | Description | Sample |
---|---|---|
group | A set of nodes declared in the YAML file | group => web_servers |
source | Full path to a YAML file with your node sets | source => /etc/your_co/nodes.yaml |
PQL Nodes
While the Choria discovery method supports PQL it’s a bit strict on format, within the playbook system we have some more freedom so you can just make arbitrary PQL queries:
$nodes = choria::discover("pql",
"query" => "facts { name = 'country' and value = '${country}' }",
"test" => true
)
All non deactivated certnames will be extracted and used as discovery source. This also shows how to use a input variable and a reminder you should test MCollective connectivity to this sort of node set.
Option | Description | Sample |
---|---|---|
query | A PQL query that should return certname as part of result sets | query => “nodes { }” |
Shell Nodes
A shell script - or any program really - can be used to extract your nodes:
$nodes = choria::discover("shell",
"script" => "/usr/local/bin/nodes.sh"
)
The script should just output one certname per line. It supports any arguments you might need and of course you can use variable interpolation to put inputs there.
I strongly suggest you validate any input you use as arguments here to not include things that might cause shell escapes. You can do this using the Choria::ShellSafe
data type.
Option | Description | Sample |
---|---|---|
script | Shell command to run with any arguments etc | script => “/usr/local/bin/nodes.sh” |
Terraform Nodes
Retrieves a Terraform output from a state file, only outputs of the list type are supported. No effort to first pull remote states is currently made.
$nodes = choria::discover("terraform",
"statefile" => "/path/to/terraform.tfstate",
"output" => "webservers"
)
This would run terraform output -state /path/to/terraform.tfstate -json webservers
Option | Description | Sample |
---|---|---|
statefile | Path to a terraform statefile | statefile => “/path/to/terraform.tfstate” |
terraform | Optional path to the terraform executable, path is checked otherwise | terraform => /usr/local/bin/terraform |
output | The name of the defined output | output => webservers |