Update 2019: We’ve recently developed a Learning Path, Introduction to Ansible, which will help you to get you started using Ansible to automate common IT tasks, you will learn about Configuration Management and you’ll be able to practice your knowledge on Ansible through a series of hands-on labs. Guy Hummel, our expert cloud trainer, has recently written an introductory post on What is Ansible?.
In a previous blog post, we introduced some basic Ansible fundamentals, installation procedures, and a guide to ad-hoc mode.
Ansible can be used in either Ad-Hoc or Playbook mode. As covered in our previous post, the ad-hoc mode allows direct management of your hosts by executing single line commands and leveraging Ansible modules. Ad-hoc mode is useful when you plan to perform a quick and simple activity like shutting down your hosts or checking connectivity between your Ansible server and hosts using ping. But when you plan to manage host configurations and deployments, Ansible playbooks become more attractive.
According to Ansible documentation, “Playbooks are Ansible’s configuration, deployment, and orchestration language. They can describe a policy you want your remote systems to enforce or a set of steps in a general IT process.”
Playbooks are written in human-readable YAML format and can be created either by placing everything in a single file or by following a structure model. Each Ansible playbook contains one or more plays to help you to perform functions on different hosts. The goal of a play is to map roles to hosts and perform tasks under a role on different hosts. Tasks are nothing but modules called on hosts.
Here is sample Ansible playbook:
--- - hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: pkg=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf notify: - restart apache - name: ensure apache is running service: name=httpd state=started handlers: - name: restart apache service: name=httpd state=restarted in more than one way. You
In the above Ansible playbook, we created an entire configuration as one single file. This is fine if you’re writing a playbook for a simple deployment or configuration. However, once you decide to implement complex deployment scenarios, it is better to use a structured model, adding re-usability.
The structure of an Ansible playbook:
site.yml hosts group_vars/ group1 group2 host_vars/ hostname1 hostname2 roles/ common/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/ webservers/ … … applicationservers/ … … databaseservers/ … …
Let’s analyze this structure.
Ansible contains information about the hosts and groups of hosts to be managed in the hosts’ file. This is also called an inventory file. One can also divide hosts files into files with different environment names, i..e, instead of “hosts”, you can create two different files called “production” and “staging”. Apart from mentioning hosts and group of hosts information, you can also include host-specific information (ssh port, db parameters etc) in a hosts file.
Here is a sample hosts file:
[webservers] prod-web01.example.com prod-web02.example.com [databaseservers] prod-db01.example.com prod-db02.example.com
Like the hosts’ inventory file, you can also include hosts and groups of hosts configuration variables in a separate configuration folder like group_vars and hosts_vars. These can include configuration parameters, whether on the application or operating system level, which may not be valid for all groups or hosts. This is where having multiple files can be useful: inside group_vars or hosts_vars, you can create a group or host in more than one way, allowing you to define specific configuration parameters.
A sample group_vars configuration:
--- # file: group_vars/webservers apacheMaxRequestsPerChild: 3000 apacheMaxClients: 900
If you look at the above configuration, the apacheMaxRequestsPerChild or apacheMaxClients configuration parameters are only valid for the webservers hosts group. They don’t apply to the database or application hosts group.
If there is some configuration which you want to apply to all groups, this can be easily done:
--- # file: group_vars/all ntp: ntp-boston.example.com backup: backup-boston.example.com
As you add more and more functionality to your Ansible playbooks, it becomes difficult to manage it as a single file. Roles allow you to prepare a minimal Ansible playbook the defines how a server is supposed to perform rather than specifying the steps to get a server to act in a specific way.
According to Ansible documentation, “Roles in Ansible build on the idea of include files and combine them to form clean, reusable abstractions – they allow you to focus more on the big picture and only dive down into the details when needed.”
To correctly use roles with Ansible, you need to create a roles directory in your working Ansible directory, and then any necessary sub-directories.
The Ansible roles structure:
roles |__ defaults |__ main.yml |__ files |__ templates |__ tasks |__ main.yml |__ meta |__ main.yml |__ vars |__ main.yml |__ handlers |__ main.yml
There are two ways to build the roles directory format, manually or by using Ansible-Galaxy. Ansible galaxy is a free site for finding, reusing and sharing community developed roles. To create a role using ansible galaxy, use the ansible-galaxy command :
# ansible-galaxy init webservers
To understand more about roles, it is important to understand the roles directory structure.
--- webservers_dir: /var/www/html webservers_port: 80
Sample template definition :
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
Sample task definition:
--- # These tasks install http and the php modules. - name: Install http and php etc yum: name={{ item }} state=present with_items: - httpd - php - php-mysql - git - libsemanage-python - libselinux-python
Sample meta definition:
--- dependencies: - { role: apt }
Sample handlers definition:
--- # file: roles/common/handlers/main.yml - name: restart ntpd service: name=ntpd state=restarted
To execute an Ansible playbook, you use the ansible-playbook command.
# ansible-playbook -i hosts site.yml
If you have a different Ansible inventory file for production and staging, you can execute a playbook on a production environment by referencing the production inventory file.
# ansible-playbook –i production site.yml
It's Flash Sale time! Get 50% off your first year with Cloud Academy: all access to AWS, Azure, and Cloud…
In this blog post, we're going to answer some questions you might have about the new AWS Certified Data Engineer…
This is my 3rd and final post of this series ‘Navigating the Vocabulary of Gen AI’. If you would like…