Here’s how I got a proof-of-concept etcd cluster up and running with Vagrant. The goal here was to find a clean, minimal process to get things up and running so I can better understand what’s going on. As you’ll see, this approach is clearly for learning and experimentation, not for production!

The one stubling block I ran in to had to do with etcd’s master elections being thrown off due to the guest OS’s system clocks not being sync’d. I resolved this by ensuring tha the guest additions were installed. A simple way to do this is to use the vagrant-vbguest plugin:

vagrant plugin install vagrant-vbguest

Here’s the Vagrantfile:

Vagrant.configure(2) do |config| = "ubuntu/trusty64"
  config.vm.provision "file", source: "./", destination: ""

  config.vm.define "etcd0" do |etcd0| "private_network", ip: ""

  config.vm.define "etcd1" do |etcd1| "private_network", ip: ""

  config.vm.define "etcd2" do |etcd2| "private_network", ip: ""

It creates three VMs, copies to each the script, and assigns each a private IP address. Here’s

#!/bin/bash -x

if [ ! -f /usr/local/bin/etcd ]
  curl -L -s -o - | \
    tar zxf - etcd-v2.3.1-linux-amd64/etcd -O > /usr/local/bin/etcd
  chmod +x /usr/local/bin/etcd

IP=`hostname -I | awk '{ print $2 }'`


case $IP in
$ETCD0) NAME=etcd0;;
$ETCD1) NAME=etcd1;;
$ETCD2) NAME=etcd2;;

etcd --name $NAME \
  --initial-advertise-peer-urls=http://$IP:2380 \
  --listen-peer-urls=http://$IP:2380 \
  --listen-client-urls=http://$IP:2379, \
  --advertise-client-urls=http://$IP:2379 \
  --initial-cluster-token=etcd-cluster-1 \
  --initial-cluster=etcd0=http://$ETCD0:2380,etcd1=http://$ETCD1:2380,etcd2=http://$ETCD2:2380 \

Once provisioned, SSH in to each machine, run as root, and pay attention to the output. The script installs etcd if it’s not already there. It then runs it, passing to it the other IPs in the cluster.

The etcd invocation is more-or-less copied directly from the examples on the etcd project’s github wiki, along with some conditonal logic to grab the machine’s name based on it’s private IP.