From charlesreid1

This page covers how to set up Vagrant machines to test out the example playbook at Ansible/Full Stack Playbook.

Full Stack Playbook: Vagrant Setup

Vagrant multi-machine setup

Here we walk through how to get set up with Vagrant before writing and testing the playbook.

Note: before running any vagrant boxes, destroy and clean up prior boxes via

vagrant destroy ---force

Vagrantfile

Create a Vagrantfile with 3 hosts:

Vagrantfile

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  # Use the same key for each machine
  config.ssh.insert_key = false

  config.vm.define "vagrant1" do |vagrant1|
    vagrant1.vm.box = "ubuntu/xenial64"
    vagrant1.vm.network "forwarded_port", guest: 80, host: 8080
    vagrant1.vm.network "forwarded_port", guest: 443, host: 8443
  end
  config.vm.define "vagrant2" do |vagrant2|
    vagrant2.vm.box = "ubuntu/xenial64"
    vagrant2.vm.network "forwarded_port", guest: 80, host: 8081
    vagrant2.vm.network "forwarded_port", guest: 443, host: 8444
  end
  config.vm.define "vagrant3" do |vagrant3|
    vagrant3.vm.box = "ubuntu/xenial64"
    vagrant3.vm.network "forwarded_port", guest: 80, host: 8082
    vagrant3.vm.network "forwarded_port", guest: 443, host: 8445
  end
end

Note that without config.ssh.insert_key=false each machine would use its own SSH key, which would be a bit of a headache. With this directive, we can define a single SSH key in our ansible config file.

Ansible config file

Now the ansible.cfg file should be modified to configure Ansible. Most important is the location of the private key:

[defaults]
inventory = inventory
remote_user = vagrant
private_key_file = ~/.vagrant.d/insecure_private_key
host_key_checking = False

Run vagrant

Run the vagrant machines with

vagrant up

See details about SSH ports using

vagrant ssh-config

which will output something like this

Host vagrant1
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/lorin/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Host vagrant2
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/lorin/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Host vagrant3
  HostName 127.0.0.1
  User vagrant
  Port 2201
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/lorin/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Create Ansible inventory file

Once we know the SSH port for each machine, we can create an inventory file.

A basic playbook/hosts file would contain:

vagrant1 ansible_host=127.0.0.1 ansible_port=2222
vagrant2 ansible_host=127.0.0.1 ansible_port=2200
vagrant3 ansible_host=127.0.0.1 ansible_port=2201

This, together with the playbook, tells Ansible how to reach and how to connect to each of the remote hosts. Now we can run a test command on the machines with Ansible:

ansible vagrant2 -a "ip addr show dev eth0"

Group the Ansible hosts file

As the hosts file gets more complicated, we may want to perform actions only on a group of machines. Toward this purpose we can group the machines under [headings] that indicate they are part of a group.

If we added many more hosts to the hosts file, we would want to group the Vagrant machines, so the host file would look like this:

ontario.example.com
newhampshire.example.com
maryland.example.com
virginia.example.com
newyork.example.com
quebec.example.com
rhodeisland.example.com

[vagrant]
vagrant1 ansible_host=127.0.0.1 ansible_port=2222
vagrant2 ansible_host=127.0.0.1 ansible_port=2200
vagrant3 ansible_host=127.0.0.1 ansible_port=2201

Note on inventory files

Inventory files can define a number of parameters for each host. Above, we define the host and port, but other variables are also available:

  • ansible_host
  • ansible_port
  • ansible_user
  • ansible_password
  • ansible_private-key_file
  • ansible_shell_type
  • ansible_python_interpreter

(But apparently only ansible_port, ansible_user, ansible_private_key_file,and ansible_shell_type can be changed in Ansible config file???)

Next steps

We will modify this inventory file as needed for the actual full stack application, but this gets you going with a basic multi-machine Vagrantfile.