Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible Playbooks vs Roles

Tags:

ansible

People also ask

What is the difference between Ansible playbook and roles?

Playbooks and roles are similar. Different at the same time. A playbook is a standalone file that Ansible can run that contains all of the information required to set a machine's state to what you expect. A playbook can contain variables, tasks, handlers, roles, and even other playbooks, all in the same file.

What are Ansible roles?

Ansible roles allow you to develop reusable automation components by grouping and encapsulating related automation artifacts, like configuration files, templates, tasks, and handlers. Because roles isolate these components, it's easier to reuse them and share them with other people.

Where do you create role vs Playbook vs task in Ansible?

Roles are a way to make code in playbooks reusable by putting the functionality into generalized "libraries" that can be then used in any playbook as needed. tasks do stuff. playbooks organize and launch tasks. roles organize bunches of tasks, handlers, etc that perform a particular function.

What is a Ansible playbook?

Ansible Playbooks are lists of tasks that automatically execute against hosts. Groups of hosts form your Ansible inventory. Each module within an Ansible Playbook performs a specific task. Each module contains metadata that determines when and where a task is executed, as well as which user executes it.


Playbook vs Role vs [databases] and similar entries in /etc/ansible/hosts

[databases] is a single name for a group of hosts. It allows you to reference multiple hosts by a single name.

Role is a set of tasks and additional files to configure host to serve for a certain role.

Playbook is a mapping between hosts and roles.

Example from documentation describes example project. It contains two things:

  • Playbooks. site.yml, webservers.yml, fooservers.yml are playbooks.
  • Roles: roles/common/ and roles/webservers/ contain definitions of common and webservers roles accordingly.

Inside playbook (webservers.yml) you have something like:

---
- hosts: webservers <- this group of hosts defined in /etc/ansible/hosts, databases and mail_servers in example from your question
  roles: <- this is list of roles to assign to these hosts
     - common
     - webservers

If Playbooks are defined inside of YAML files, then where are Roles defined?

They are defined inside roles/* directories. Roles are defined mostly using YAML files, but can also contain resources of any types (files/, templates/). According to documentation role definition is structured this way:

  • If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play
  • If roles/x/handlers/main.yml exists, handlers listed therein will be added to the play
  • If roles/x/vars/main.yml exists, variables listed therein will be added to the play
  • If roles/x/meta/main.yml exists, any role dependencies listed therein will be added to the list of roles (1.3 and later)
  • Any copy tasks can reference files in roles/x/files/ without having to path them relatively or absolutely
  • Any script tasks can reference scripts in roles/x/files/ without having to path them relatively or absolutely
  • Any template tasks can reference files in roles/x/templates/ without having to path them relatively or absolutely
  • Any include tasks can reference files in roles/x/tasks/ without having to path them relatively or absolutely

The most important file is roles/x/tasks/main.yml, here you define tasks, which will be executed, when role is executed.

Aside from the ansible.cfg living on the Ansible server, how do I add/configure Ansible with available Playbooks/Roles? For instance, when I run ansible-playbook someplaybook.yaml, how does Ansible know where to find that playbook?

$ ansible-playbook someplaybook.yaml

Will look for a playbook inside current directory.

$ ansible-playbook somedir/somedir/someplaybook.yaml

Will look for a playbook inside somedir/somedir/ directory.

It's your responsibility to put your project with all playbooks and roles on server. Ansible has nothing to do with that.


Playbook vs Role vs [databases] and similar entries in /etc/ansible/hosts

Roles are a way to group tasks together into one container. You could have a role for setting up MySQL, another one for setting up Postfix etc.

A playbook defines what is happening where. This is the place where you define the hosts (hostgroups, see below) and the roles which will be applied to those hosts.

[databases] and the other entries in your inventory are hostgroups. Hostgroups define a set of hosts a play will run on.

A play is a set of tasks or roles (or both) inside a playbook. In most cases (and examples) a playbook will contain only one single play. But you can have as many as you like. That means you could have a playbook which will run the role postfix on the hostgroup mail_servers and the role mysql on the hostgroup databases:

- hosts: mail_servers
  roles:
    - postfix

- hosts: databases
  roles:
    - mysql

If Playbooks are defined inside of YAML files, then where are Roles defined?

In Ansible pretty much everything is defined in YAML, that counts for roles and playbooks.

Aside from the ansible.cfg living on the Ansible server, how do I add/configure Ansible with available Playbooks/Roles? For instance, when I run ansible-playbook someplaybook.yaml, how does Ansible know where to find that playbook?

AFAIK you have to provide the path to the playbook when invoking ansible-playbook. So ansible-playbook someplaybook.yaml would expect someplaybook.yaml to be in you current directory. But you can provide the full path: ansible-playbook /path/to/someplaybook.yaml


It's a terminology/semantic question. It can be subjective, even though there is a baseline definition.

My view is as follows:

Any configuration management/deployment system has:

  1. source data - data used to create target host's configuration
  2. target data - data used to identify target hosts
  3. config changes - list/set of rules/actions we apply with source data over target host based on target data

In Ansible terms:

  1. source data - is the various places we can put data - group_vars, playbook vars, role vars, etc., These places affect precedence (if a variable named the same is re-defined in different locations, there are very specific rules of what would be the value of the variable during ansible/ansible-playbook execution
  2. target data - is the inventory (And, It's also possible to define inventory/hostgroup variables inside inventory!)
  3. config changes - ansible has 4 levels of abstraction for it:
    1. task - single action
    2. task list - list of actions
    3. role - list of actions (or list of lists) grouped by the same 'subject', usually all targets are operating on the same host/hostgroup
    4. playbook - list of plays, each operating on possibly different hostgroup, applying several roles/tasks/tasklists (and special tasks like handlers)

From 'software' aspect - role should be generic enough to be reused.

Also in some (rather big) organizations, 'roles' are shipped by group A, while used in playbooks maintained by group B.

summary

All the above allows grouping of similar configurations - into a role. grouping related subsystems/components into one playbook. Also, worth mentioning, 1 YAML item in a playbook (including hosts: and either or tasks, pre_tasks, post_tasks, roles) is called a play

Now for your question:

Yes, it is confusing at first.

You usually connect your source data to your role's semantics, so when you see that role setup_db is applied in a play onto related hostgroup (e.g. db_hosts) But a play can be running over a union of several hostgroups. It's just a matter of convention vs flexibility.

P.S.

Please write me back whether this added to the confusion, or clarified. Thanks.


Simply put:

A playbook is like the main program, it contents complete instructions to finish the job. However, for big projects, it is not desirable to actually put every detail in it. So you need role.

A role is a subroutine and usually achieves one goal, e.g. setup a database server. You can put it in roles/ directory, or download 3rd party roles by providing URIs in rolesfile.yml and ask ansible-galaxy to download them for you.

The [database] is a host group defined in inventory file that lists hosts that belong to the database group. You can also specify a group of web servers by specifying something like

[web]
web1.example.com
web2.example.com

Group web or database can then be used in playbooks or roles to specify the hosts to apply.

The groups can also be used in command ansible to run ad-hoc commands.


Also keep in mind a playbook can call more than one role if a meta file is used that is intended to affect the different roles.

Example Playbook: dual_role-playbook.yml

- name: Some Action for two roles
  hosts: localhost

  vars_files:
    - roles/dual_role/meta/main.yml

  roles:
    - dual_role/container-1
    - dual_role/container-2

The role folder and files scheme will look like this:

dual_role-playbook.yml
  -- roles
     -- dual_role
        -- meta/main.yml
        -- container-1
           -- tasks/main.yml
           -- templates/template.j2
        -- container-2
           -- tasks/main.yml
           -- templates/template.j2