In this example we are going to use Vagrant and Ansible to build a Ubuntu server.


System


I am using Ansible 2.4.3.0 and Vagrant 1.9.5 on MacOS.


Structure


$ tree
.
├── Vagrantfile
├── provisioning
│   ├── group_vars
│   │   └── all
│   ├── hosts.yml
│   ├── roles
│   │   └── common
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │   └── ntp.conf.j2
│   └── site.yml
└── vagrant_hosts.yml

Tasks



Files


vagrant_hosts.yml


# Reflect any "hostname" and "ip" changes in "provisioning/hosts.yml" file

- name: This is for Linux 1 box
label: Linux 1 - 192.168.99.31
hostname: linux1
ip: 192.168.99.31


Vagrantfile


# -*- mode: ruby -*-
# vi: set ft=ruby :

require "yaml"

boxes = YAML.load_file("vagrant_hosts.yml")

Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"

ANSIBLE_RAW_SSH_ARGS = []
i = 0

boxes.each do |box|
ANSIBLE_RAW_SSH_ARGS << "-o IdentityFile=.vagrant/machines/#{box["hostname"]}/virtualbox/private_key"

config.vm.define box["hostname"] do |machine|
machine.vm.hostname = box["hostname"]
machine.vm.network "private_network", ip: box["ip"]
machine.vm.synced_folder box["hostname"], "/srv/www", create: true, nfs: true, mount_options: ["actimeo=2"]
machine.vm.provider :virtualbox do |virtualbox|
virtualbox.name = box["label"]
end
i += 1

if i == boxes.count
machine.vm.provision :ansible do |ansible|
ansible.raw_ssh_args = ANSIBLE_RAW_SSH_ARGS
ansible.verbose = "-vvv"
ansible.limit = "all"
ansible.inventory_path = "provisioning/hosts.yml"
ansible.playbook = "provisioning/site.yml"
end
end
end
end
end

provisioning/hosts.yml


# Reflect any "hostname" and "ip" changes in "../vagrant_hosts.yml" file

all:
hosts:
linux1:
ansible_host: 192.168.99.31

provisioning/site.yml


---
# This playbook sets up whole stack.

- name: Apply common configuration to "all" hosts
hosts: all
remote_user: root
become: yes
roles:
- common

provisioning/group_vars/all


---
# Variables listed here are applicable to "all" host

ansible_python_interpreter: /usr/bin/python3

provisioning/roles/common/handlers/main.yml


---
# This playbook contains common handlers that can be called in tasks.

# sudo service ntp restart (whether running or not)
- name: Restart ntp
service:
name: ntp
state: restarted
enabled: yes

provisioning/roles/common/tasks/main.yml


---
# This playbook contains common actions that will be run on "all" hosts.

# sudo apt-get update
- name: Update apt packages
apt:
update_cache: yes
tags:
- system

# sudo timedatectl set-timezone Europe/London
- name: Set time zone to Europe/London
timezone:
name: Europe/London
tags:
- system

# sudo apt-get install ntp
- name: Install ntp
apt:
name: ntp
state: present
update_cache: yes
tags:
- ntp

# sudo cp provisioning/common/templates/ntp.conf.j2 /etc/ntp.conf
- name: Configure ntp file and restart
template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify: Restart ntp
tags:
- ntp

# sudo apt-get install nano
- name: Install nano
apt:
name: nano
state: present
update_cache: yes
tags:
- nano

# sudo apt-get autoclean
- name: Remove useless apt packages from the cache
apt:
autoclean: yes
tags:
- system

# sudo apt-get autoremove
- name: Remove dependencies that are no longer required
apt:
autoremove: yes
tags:
- system

provisioning/roles/common/templates/ntp.conf.j2


driftfile /var/lib/ntp/drift

# Specify UK NTP servers.
server 0.uk.pool.ntp.org
server 1.uk.pool.ntp.org
server 2.uk.pool.ntp.org
server 3.uk.pool.ntp.org

# Use Ubuntu's NTP server as a fallback.
server ntp.ubuntu.com

# Local users may obtain data from NTP servers.
restrict 127.0.0.1
restrict ::1

Build


$ vagrant up
...
PLAYBOOK: site.yml *************************************************************
1 plays in provisioning/site.yml
PLAY [Apply common configuration to "all" hosts] *******************************
TASK [Gathering Facts] *********************************************************
TASK [server : Update apt packages] ********************************************
TASK [server : Set time zone to Europe/London] *********************************
TASK [server : Install ntp] ****************************************************
TASK [server : Configure ntp file and restart] *********************************
TASK [server : Install nano] ***************************************************
TASK [server : Remove useless apt packages from the cache] *********************
TASK [server : Remove dependencies that are no longer required] ****************
RUNNING HANDLER [server : Restart ntp] *****************************************
META: ran handlers
META: ran handlers
PLAY RECAP *********************************************************************
linux1 : ok=9 changed=5 unreachable=0 failed=0

References