Ansible structure layout – the best approach

This is called Ansible structure layout – the best approach that we used to use it as a template for our projects. This may be not the best but you can customized it as to fit your own.

Directory Layout

The top level of the directory would contain files and directories like so:

production.in             # inventory file for production servers
stage.ini                 # inventory file for stage environment

group_vars/
   group1                 # here we assign variables to particular groups
   group2                 # ""
host_vars/
   hostname1              # if systems need specific vars, put them here
   hostname2              # ""

site.yml                  # master playbook
webservers.yml            # playbook for webserver tier
dbservers.yml             # playbook for dbserver tier

roles/{ common, nginx, php7.1,...}

How to Arrange Inventory, Stage vs Production

  • production.ini: contains the inventory of all production hosts
  • stage.ini: contains the inventory of all staging hosts

It is suggested that you define groups based on the purpose of the host (roles) and also geography or data center location (if applicable):

# file: production

[atlanta-webservers]
www-atl-1.example.com
www-atl-2.example.com

[boston-webservers]
www-bos-1.example.com
www-bos-2.example.com

[atlanta-dbservers]
db-atl-1.example.com
db-atl-2.example.com

[boston-dbservers]
db-bos-1.example.com

# webservers in all geos
[webservers:children]
atlanta-webservers
boston-webservers

# dbservers in all geos
[dbservers:children]
atlanta-dbservers
boston-dbservers

# everything in the atlanta geo
[atlanta:children]
atlanta-webservers
atlanta-dbservers

# everything in the boston geo
[boston:children]
boston-webservers
boston-dbservers

Group And Host Variables

We can also assign variables to all hosts in a group or specific group or specific hosts. Let’s set those now:

---
# file: group_vars/atlanta
ntp: ntp-atlanta.example.com
backup: backup-atlanta.example.com
---
# file: group_vars/webservers
apacheMaxRequestsPerChild: 3000
apacheMaxClients: 900

If we had any default values or values that were universally true, we would put them in a file called group_vars/all:

---
# file: group_vars/all
ntp: ntp-boston.example.com
backup: backup-boston.example.com

We can define specific hardware variance in systems in a host_vars file, but avoid doing this unless you need to:

---
# file: host_vars/db-bos-1.example.com
foo_agent_port: 86
bar_agent_port: 99

Playbooks Are Separated By Role

Playbook webservers.yml is used for all hosts in group webservers with roles common, nginx

---
# file: webservers.yml
- hosts: webservers
  roles:
    - common
    - nginx

Task And Handler Organization For A Role

Below is an example tasks file that explains how a role works. Our common role here just sets up NTP, but it could do more if we wanted:

---
# file: roles/common/tasks/main.yml

- name: be sure ntp is installed
  yum: pkg=ntp state=installed
  tags: ntp

- name: be sure ntp is configured
  template: src=ntp.conf.j2 dest=/etc/ntp.conf
  notify:
    - restart ntpd
  tags: ntp

- name: be sure ntpd is running and enabled
  service: name=ntpd state=running enabled=yes
  tags: ntp

Here is an example handlers file. As a review, handlers are only fired when certain tasks report changes and are run at the end of each play:

---
# file: roles/common/handlers/main.yml
- name: restart ntpd
  service: name=ntpd state=restarted

Let’s run your playbook

What about just reconfiguring NTP on everything? Easy.:

ansible-playbook -i production webserver.yml --tags ntp

What about just reconfiguring my webservers?:

ansible-playbook -i production webservers.yml

What about just my webservers in Boston?:

ansible-playbook -i production webservers.yml --limit boston

What about just the first 10, and then the next 10?:

ansible-playbook -i production webservers.yml --limit boston[0-10]
ansible-playbook -i production webservers.yml --limit boston[10-20]

And of course, just basic ad-hoc stuff is also possible.:

ansible boston -i production -m ping
ansible boston -i production -m command -a '/sbin/reboot'

Stage vs Production

As also mentioned above, a good way to keep your stage (or testing) and production environments separate is to use a separate inventory file for stage and production. This way you pick with -i what you are targeting. Keeping them all in one file can lead to surprises!


Also published on Medium.

Leave a Reply

Your email address will not be published. Required fields are marked *