This worked for me pretty well: I've used per VM provision scripts, and in the last script I've called post provision script via ssh on the first VM.
In Vagrantfile
:
require 'fileutils'
Vagrant.require_version ">= 1.6.0"
$max_nodes = 2
$vm_name = "vm_prefix"
#...<skipped some lines that are not relevant to the case >...
Vagrant.configure("2") do |config|
config.ssh.forward_agent = true
config.ssh.insert_key = false
#ubuntu 16.04
config.vm.box = "ubuntu/xenial64"
(1..$max_nodes).each do |i|
config.vm.define vm_name = "%s-%02d" % [$vm_name, i] do |config|
config.vm.hostname = vm_name
config.vm.network "private_network", ip: "10.10.0.%02d" % [i+20], :name => 'vboxnet2'
config.vm.network :forwarded_port, guest: 22, host: "1%02d22" % [i+20], id: "ssh"
config.vm.synced_folder "./shared", "/host-shared"
config.vm.provider :virtualbox do |vb|
vb.name = vm_name
vb.gui = false
vb.memory = 4096
vb.cpus = 2
vb.customize ["modifyvm", :id, "--cpuexecutioncap", "100"]
vb.linked_clone = true
end
# Important part:
config.vm.provision "shell", path: "common_provision.sh"
config.vm.provision "shell", path: "per_vm_provision#{i}.sh"
end
end
end
On disk:
(ensure that post_provision.sh has at least owner execute permissions: rwxr..r..)
vm$ ls /vagrant/
...<skipped some lines that are not relevant to the case >...
config.sh
common_provision.sh
per_vm_provision1.sh
per_vm_provision2.sh
per_vm_provision3.sh
...
per_vm_provisionN.sh
post_provision.sh
Vagrantfile
...<skipped some lines that are not relevant to the case >...
In config.sh
:
num_vm="2" # should equal the $max_nodes in Vagrantfile
name_vm="vm_prefix" # should equal the $vm_name in Vagrantfile
username="user1"
userpass="abc123"
...<skipped some lines that are not relevant to the case >...
In common_provision.sh
:
source /vagrant/config.sh
...<skipped some lines that are not relevant to the case >...
sed -r -i 's/\%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/' /etc/sudoers
sed -r -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
service ssh reload
# add user ${username}
useradd --create-home --home-dir /home/${username} --shell /bin/bash ${username}
usermod -aG admin ${username}
usermod -aG sudo ${username}
/bin/bash -c "echo -e \"${userpass}\n${userpass}\" | passwd ${username}"
# provision additional ssh keys
# copy ssh keys from disk
cp /vagrant/ssh/* /home/vagrant/.ssh
cat /vagrant/ssh/id_rsa.pub >> /home/vagrant/.ssh/authorized_keys
mkdir /home/${username}/.ssh
cp /vagrant/ssh/* /home/${username}/.ssh
cat /vagrant/ssh/id_rsa.pub >> /home/${username}/.ssh/authorized_keys
# not required, just for convenience
cat >> /etc/hosts <<EOF
10.10.0.21 ${name_vm}-01
10.10.0.22 ${name_vm}-02
10.10.0.23 ${name_vm}-03
...
10.10.0.2N ${name_vm}-0N
EOF
...<skipped some lines that are not relevant to the case >...
In per_vm_provision2
.sh:
#!/bin/bash
# import variables from config
source /vagrant/config.sh
...<skipped some lines that are not relevant to the case >...
# check if this is the last provisioned vm
if [ "x${num_vm}" = "x2" ] ; then
ssh [email protected] -o StrictHostKeyChecking=no -- '/vagrant/post_provision.sh'
fi
In per_vm_provisionN.sh
:
#!/bin/bash
# import variables from config
source /vagrant/config.sh
...<skipped some lines that are not relevant to the case >...
# check if this is the last provisioned vm. N represents the highest number
if [ "x${num_vm}" = "xN" ] ; then
ssh [email protected] -o StrictHostKeyChecking=no -- '/vagrant/post_provision.sh'
fi
I hope, I didn't skip anything important, but I think the idea is clear in general.
Note: ssh keys for interVM access is provisioned by Vagrant by default. You can add your own ssh keys if needed using common_provision.sh