How do I separate stages of multi-machine cluster

2019-05-29 07:02发布

问题:

Let's say I have 4 Vagrant boxes.

3 are variations of the same configuration, say, Consul, and one has a completely different configuration, say a database.

I need to run a provisioning step with slight variations on the three similarly configured Consul VMs.

Then, I need to run a provisioning step against 1 of those Vault VMs.

Only after this provisioning step run on 1 of the VMs can I successfully run the next provisioning step, with slight variations, on the three similarly configured Vault VMs.

I've read through the docs on Vagrant with multiple machines, looping over VM definitions, and provisioning parameters. The preserve_order: true parameter didn't work for me, at least not the way I was using it.

Here's what I've been trying so far, anonymized to protect the guilty:

~ $cat Hark_TisAVagrant
Vagrant.configure("2") do |config|

    ##  1.
    ##  Do This on 3 VMs
  (1..3).each do |i|
    config.vm.define "node-#{i}" do |node|
      node.vm.provision "shell",
        inline: "echo FIRST from node #{i}"
      node.vm.provider "docker" do |d|
        d.image = "consul"
      end
    end
  end

    ##  2.
    ##  Afterwards, do this on one VM from that set
  node3.vm.provision "then-this",
    type: "shell",
    preserve_order: true,
    inline: "echo SECOND from node3!"

    ##  3.
    ##  Finally, on all 3, do this
  (1..3).each do |i|
    config.vm.define "node-#{i}" do |node|
      node.vm.provision "shell",
        inline: "echo FINAL from node #{i}"
    end
  end

    ##  4.
    ##  On the side, no order needed
  config.vm.define "db" do |db|
    db.vm.provision "shell", inline: "echo an irrelevant dbtard meme-ing in the peanut gallery"
    db.vm.provider "docker" do |d|
      d.image = "postgres"
    end
  end

end

I'll spare you the massive Vagrant logs, but I'm getting the equivalent of the following:

FIRST (1-Consul)
SECOND (Fails due to lack of 3-Consul Quorum)
FINAL
FIRST
FINAL
FIRST
FINAL
DB

What I'm looking for is more like this: FIRST
FIRST
FIRST (3-Consul Quorum achieved)
SECOND (API Call)
FINAL
FINAL
FINAL
DB

I'm also going to research doing this with a .yaml file, and on Vagrantfile hierarchies.

This answer seems to indicate that what I'm looking for isn't possible using a mere Vagrantfile, but it's from 2 years ago: https://stackoverflow.com/a/25065243/2146138

And this answer looked promising at first, but seems to focus mostly on Ansible:

Vagrant multi-machine provisioning

The main problem motivating this question, for me, at least, is that all 3 machines need to be provisioned for a Consul Cluster "Quorum".

After we get a 3-Consul "Quorum" a single call needs to be made against the Consul Cluster's API to ACL it.

After that call, provisioning of other services can continue properly, and they can register in the newly initialized and ACL'd Consul Cluster.

Regardless of my particular motivating problem, though, I am curious about the capabilities of the Vagrant DSL's features for multi-machine control flow for cases like this, because I suspect this will come up again.