Search code examples
dockerpuppetdocker-swarm

Pass dynamic data to an exported resource


For my work, we are trying to spin up a docker swarm cluster with Puppet. We use puppetlabs-docker for this, which has a module docker::swarm. This module allows you to instantiate a docker swarm manager on your master node. This works so far.

On the docker workers you can join to docker swarm manager with exported resources:

node 'manager' {
  @@docker::swarm {'cluster_worker':
    join           => true,
    advertise_addr => '192.168.1.2',
    listen_addr    => '192.168.1.2',
    manager_ip     => '192.168.1.1',
    token          => 'your_join_token'
    tag            => 'docker-join'
  }
}

However, the your_join_token needs to be retrieved from the docker swarm manager with docker swarm join-token worker -q. This is possible with Exec.

My question is: is there a way (without breaking Puppet philosophy on idempotent and convergence) to get the output from the join-token Exec and pass this along to the exported resource, so that my workers can join master?


Solution

  • My question is: is there a way (without breaking Puppet philosophy on idempotent and convergence) to get the output from the join-token Exec and pass this along to the exported resource, so that my workers can join master?

    No, because the properties of resource declarations, exported or otherwise, are determined when the target node's catalog is built (on the master), whereas the command of an Exec resource is run only later, when the fully-built catalog is applied to the target node.

    I'm uncertain about the detailed requirements for token generation, but possibly you could use Puppet's generate() function to obtain one at need, during catalog building on the master.

    Update

    Another alternative would be an external (or custom) fact. This is the conventional mechanism for gathering information from a node to be used during catalog building for that node, and as such, it might be more suited to your particular needs. There are some potential issues with this, but I'm unsure how many actually apply:

    • The fact has to know for which nodes to generate join tokens. This might be easier / more robust or trickier / more brittle depending on factors including

      • whether join tokens are node-specific (harder if they are)
      • whether it is important to avoid generating multiple join tokens for the same node (over multiple Puppet runs; harder if this is important)
      • notwithstanding the preceding, whether there is ever a need to generate a new join token for a node for which one was already generated (harder if this is a requirement)
    • If implemented as a dynamically-generated external fact -- which seems a reasonable option -- then when a new node is added to the list, the fact implementation will be updated on the manager's next puppet run, but the data will not be available until the following one. This is not necessarily a big deal, however, as it is a one-time delay with respect to each new node, and you can always manually perform a catalog run on the manager node to move things along more quickly.

    • It has more moving parts, with more complex relationships among them, hence there is a larger cross-section for bugs and unexpected behavior.