• Stars
    star
    100
  • Rank 339,606 (Top 7 %)
  • Language
    Shell
  • License
    MIT License
  • Created over 10 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An opinionated skeleton for Ansible projects with a development environment powered by Vagrant.

Ansible Skeleton

An opinionated skeleton that considerably simplifies setting up an Ansible project with a development environment powered by Vagrant.

Advantages include:

See also the companion projects:

If you like/use this role, please consider giving it a star. Thanks!

Installation

On the management node, make sure you have installed recent versions of:

  • VirtualBox
  • Vagrant
  • Git and for Windows hosts also Git Bash. If you install Git with default settings (i.e. always click "Next" in the installer), you should be fine.
  • Ansible (only on Mac/Linux)

You can either clone this project or use the provided initialization script.

When cloning, choose another name for the target directory.

> git clone https://github.com/bertvv/ansible-skeleton.git my-ansible-project

After cloning, it's best to remove the .git directory and initialise a new repository. The history of the skeleton code is irrelevant for your Ansible project.

You can find an initialization script in my ansible-toolbox that automates the process (including creating an empty Git repository).

> atb-init my-ansible-project

This will download the latest version of the skeleton from Github, initialize a Git repository, do the first commit, and, optionally, install any specified role.

> atb-init my-ansible-project bertvv.el7 bertvv.httpd

This will create the skeleton and install roles bertvv.el7 and bertvv.httpd from Ansible Galaxy.

Getting started

First, modify the Vagrantfile to select your favourite base box. I use a CentOS 7 base box, from the Bento project. This is probably the only time you need to edit the Vagrantfile.

The vagrant-hosts.yml file specifies the nodes that are controlled by Vagrant. You should at least specify a name:, other settings (see below) are optional. A host-only adapter is created and the given IP assigned to that interface. Other optional settings that can be specified:

VirtualBox configuration:

  • cpus: The number of CPUs assigned to this VM.
  • memory: The memory size in MB, if you want to set a size different from the base box default.
  • synced_folders: A list of dicts that specify synced folders. Two keys, src: (the directory on the host system) and dest: (the mount point in the guest) are mandatory, another one, options: is, well, optional. The possible options are the same ones as specified in the Vagrant documentation on synced folders. One caveat is that the option names should be prefixed with a colon, e.g. owner: becomes :owner:.
- name: srv002
  synced_folders:
    - src: test
      dest: /tmp/test
    - src: www
      dest: /var/www/html
      options:
        :create: true
        :owner: root
        :group: root
        :mount_options: ['dmode=0755', 'fmode=0644']

Network settings:

  • auto_config: If set to false, Vagrant will not attempt to configure the network interface.
  • forwarded_ports: A list of dicts with keys host: and guest: specifying which host port should be forwarded to which port on the VM.
  • intnet: If set to true, the network interface will be attached to an internal network rather than a host-only adapter.
  • ip: The IP address for the VM.
  • mac: The MAC address to be assigned to the NIC. Several notations are accepted, including "Linux-style" (00:11:22:33:44:55) and "Windows-style" (00-11-22-33-44-55). The separator characters can be omitted altogether (001122334455).
  • netmask: By default, the network mask is 255.255.255.0. If you want another one, it should be specified.

Provisioning:

  • playbook: On this host, execute a different playbook than the default ansible/site.yml
  • shell_always: A list of dicts that specify commands to be run after booting the VM. There is one required key, cmd: that contains the command and any options/arguments.

Adding hosts

As an example, a single host with hostname srv001 is already defined. If you want to add new nodes, you should edit the following files:

  • vagrant-hosts.yml so a Vagrant box is created. A few examples that also illustrate the optional settings.
- name: srv002
  ip: 192.168.56.11
  auto_config: false

- name: srv003
  ip: 172.16.0.3
  netmask: 255.255.0.0
  intnet: true

- name: srv004
  ip: 192.168.56.14
  mac: "00:03:DE:AD:BE:EF"
  playbook: server.yml  # defaults to site.yml
  • site.yml to assign roles to your nodes, e.g.:
- hosts: srv003
  become: true
  roles:
    - bertvv.rh-base
    - bertvv.httpd

Defining groups

Ansible allows hosts to be organized into groups. In order to use this functionality, edit the file vagrant-groups.yml. The file should contain a dict with group names as keys and lists of member hosts as values.

In this example, two groups, db and web are defined:

---
db:
  - srv001
web:
  - srv002
  - srv003

Run with custom hosts/groups file

VAGRANT_HOSTS='custom-vagrant-hosts.yml' vagrant up

or

export VAGRANT_HOSTS='custom-vagrant-hosts.yml'
vagrant up

Likewise, set the environment variable VAGRANT_GROUPS to use a custom groups file.

Worked example

Alice wants to set up an environment with several web servers, a load balancer and a database server. She first defines the groups:

# group-vars.yml
---
db:
  - db001

lb:
  - lb001

web:
  - web001
  - web002
  - web003

Next, she assigns IP addresses to each VM in vagrant-hosts.yml:

# vagrant-hosts.yml
---
- name: db001
  ip: 192.168.56.10
- name: lb001
  ip: 192.168.56.11
- name: web001
  ip: 192.168.56.21
- name: web002
  ip: 192.168.56.22
- name: web003
  ip: 192.168.56.23

Next, she starts with the following master playbook site.yml:

# ansible/site.yml
---

- hosts: all
  tasks:
    - debug:
        msg: "This is {{ ansible_hostname }} in group {{ my_group }}"

The variable ansible_hostname is initialized automatically by Ansible, but my_group is not. Therefore, Alice defines it for each group, by editing an appropriately named Yaml file in ansible/group_vars/ (only web and db are shown here):

# ansible/group_vars/web.yml
---
my_group: web
# ansible/group_vars/db.yml
---
my_group: db

Next, she can run vagrant up. The following transcript shows what you should see after running vagrant provision db001 web001:

$ vagrant provision db001 web001
==> db001: Running provisioner: ansible...
    db001: Running ansible-playbook...

PLAY [all] *********************************************************************

TASK [debug] *******************************************************************
ok: [db001] => 
  msg: This is db001 in group db

PLAY RECAP *********************************************************************
db001                     : ok=1    changed=0    unreachable=0    failed=0   

==> web001: Running provisioner: ansible...
    web001: Running ansible-playbook...

PLAY [all] *********************************************************************

TASK [debug] *******************************************************************
ok: [web001] => 
  msg: This is web001 in group web

PLAY RECAP *********************************************************************
web001                     : ok=1    changed=0    unreachable=0    failed=0   

The master playbook can the be refined further, e.g.

# ansible/site.yml
---

- hosts: web
  roles:
    - bertvv.rh-base
    - bertvv.httpd
- hosts: db
  roles:
    - bertvv.rh-base
    - bertvv.mariadb
# ...

Role variables can then be defined in ansible/group_vars/.

Running tests with BATS

There's a discussion on whether Unit tests are necessary for Ansible. Indeed, with its declarative nature, Ansible largely takes away the need to check for certain things independently from the playbook definitions. For a bit more background, be sure to read through this discussion about unit testing for Ansible on Google groups.

However, it is my opinion that playbooks don't cover everything (e.g. whether a config file generated from a template has the expected contents, given the values of variables used). I value some form of testing, independent of the configuration management system. Personally, I'm a fan of the Bash Automated Testing System (BATS). It's basically an extension of Bash, so anyone familiar with it should be able to use BATS.

Put your BATS test scripts in the test/ directory and they will become available on your guest VMs as a synced folder, mounted in /vagrant/test. Scripts that you want to run on each host should be stored in the test/ directory itself, scripts for individual hosts should be stored in subdirectories with the same name as the host (see example below). Inside the VM, run

> sudo /vagrant/test/runbats.sh

to execute all tests relevant for that host. The script will install BATS if needed.

Suppose the test/ directory is structured like the example below:

test/
├── common.bats
├── runbats.sh
├── db001
│   └── db.bats
└── web001
    └── web.bats

On host db001, the scripts common.bats and db.bats will be executed, on host web001, it's common.bats and web.bats.

Tests must be defined for each host individually. If you want to run identical tests on several hosts, it's best to create a symlink, e.g.:

$ ln -s web001 web002

Now, web.bats will also be executed on host web002.

Contributors

More Repositories

1

cheat-sheets

Cheat sheets for various stuff
Makefile
311
star
2

ansible-role-bind

Sets up ISC BIND as an authoritative DNS server on several Linux distros & FreeBSD
Jinja
255
star
3

ansible-role-samba

Ansible role for managing Samba as a file server on RedHat- and Debian-based linux distros.
Shell
189
star
4

ansible-role-mariadb

Install MariaDB on RHEL/CentOS 7 or Fedora.
Shell
143
star
5

dotfiles

My configuration for Bash, Ruby, Git, Todo.txt, Vim, etc. See Wiki for usage instructions.
Vim Script
64
star
6

ansible-role-dhcp

Ansible role for setting up ISC DHCPD on RHEL/CentOS 7
Jinja
58
star
7

github-org-mgmt

Scripts for automating Github organisation management, e.g. creating teams with a repo and adding members.
Python
48
star
8

ansible-dnsmasq

An Ansible role for managing Dnsmasq on RHEL/CentOS 7 of Fedora with basic DNS and DHCP capabilities.
46
star
9

scripts

A bunch of (mostly Bash) scripts that may be useful. Or not.
Shell
45
star
10

ansible-role-pxeserver

Ansible role to set up a PXE server on RHEL/CentOS 7
Ruby
38
star
11

ansible-role-rh-base

Ansible role for basic setup of a server with a RedHat-based Linux distribution (CentOS, Fedora, RHEL, ...)
Shell
32
star
12

ansible-role-hosts

An Ansible role for managing the hosts file (`/etc/hosts`).
32
star
13

ansible-role-httpd

A simple Ansible role for installing and configuring the Apache web server for RHEL/CentOS 7 and Fedora 28
Jinja
31
star
14

ansible-role-vsftpd

Set up an FTP server with Vsftpd on RHEL/CentOS 7, Ubuntu 12.04, or 14.04
26
star
15

vagrant-shell-skeleton

Scaffolding code for a multi-VM Vagrant environment with Shell provisioning.
Shell
19
star
16

ansible-role-wordpress

Installs Wordpress on RHEL/CentOS 7
PHP
17
star
17

ansible-toolbox

A collection of scripts to be used with ansible-skeleton and ansible-role-skeleton
Shell
15
star
18

ansible-role-skeleton

My scaffolding code for Ansible roles. Setting up manually is not recommended. A script to initialise a new role can be found here: https://github.com/bertvv/ansible-toolbox/
Shell
13
star
19

linux-network-troubleshooting

Guide for troubleshooting network services on a Linux system
13
star
20

ansible-role-el7

An Ansible role for basic configuration of RHEL/CentOS 7 based machines.
Shell
11
star
21

ansible-role-jblicense

Installs JetBrains License Server on RHEL/CentOS 7
Ruby
10
star
22

ansible-role-tftp

Installs a TFTP server on RHEL/CentOS 7
10
star
23

ansible-role-mailserver

Installation of a complete mail server (Postfix, Cyrus, ...) on Enterprise Linux 7
10
star
24

docker-images-ansible

Docker images for testing Ansible roles
Dockerfile
7
star
25

ansible-role-tomcat

An Ansible role for setting up Tomcat on RHEL/CentOS 7 or Fedora.
7
star
26

presentation-el7-basics

My presentation at CentOS Dojo 2017 Brussels, "Basic commands for Enterprise Linux 7"
CSS
6
star
27

vagrant-presentation

Presentation slides of my Vagrant tutorial at LOADays 2014
HTML
6
star
28

ansible-role-collectd

Installs collectd (client and server) and, optionally, collectd-web on RHEL/CentOS 7
Jinja
5
star
29

bachproef-gids

**LET OP** deze repo is verhuisd naar
4
star
30

presentation-network-troubleshooting

My presentation for CentOS Dojo 2018 Brussels, and LOADays 2018: Basic troubleshooting of network services in EL7
Shell
4
star
31

ansible-role-sambadc

Proof-of-concept Samba4 as Domain Controller on CentOS7
3
star
32

presentation-clean-bash

Slides and supporting material for my "Clean Bash" talk at Loadays 2019
3
star
33

travispoc

Proof-of-Concept for running an Ansible playbook inside a Docker container with CentOS on Travis-CI
3
star
34

presentation-linux-hogent

Slide deck for my talk "Linux curriculum at HOGENT" for LOADays 2019
2
star
35

server-dotfiles

Configuration for Bash, Vim, Tmux, etc.
Vim Script
2
star
36

ansible-role-cobbler

Installs and configures Cobbler (with Dnsmasq) on RHEL/CentOS 7 (not ready for release)
Ruby
2
star
37

vagrant-example

The example I used in my Vagrant tutorial at LOADays 2014
Puppet
2
star
38

hogent-latex-sjablonen

LaTeX sjablonen met de huisstijl van HoGent (Bedrijf en Organisatie) LET OP, voor een recente versie van het sjabloon voor de bachelorproef, ga naar https://github.com/HoGentTIN/bachproef-latex-sjabloon
TeX
2
star
39

presentation-cfgmgmtcamp2017

Slides for my presentation at Configuration Management Camp Ghent 2017
CSS
1
star
40

docker-sandbox

Vagrant environment of a Fedora 27 VM running Docker and Cockpit
Shell
1
star
41

ansible-role-drupal

Install Drupal on RHEL/CentOS 7
PHP
1
star
42

notes-to-self

Content of my blog
Shell
1
star
43

gitbash-dotfiles

Dotfiles for my Git Bash (on Windows) environment
Shell
1
star
44

fedora-testbox

A minimal Fedora installation for experimenting with Linux
Shell
1
star
45

today-i-learned

Today, I learned...
Shell
1
star
46

talks

Slide decks for talks I've given
CSS
1
star