Ansible – Playbook
Playbooks are Ansible’s configuration, deployment, and orchestration language. Playbooks can be used to manage configurations of and deployments to remote machines.
Playbook Language Example
-
Playbooks are expressed in YAML format.
-
Each playbook is composed of one or more ‘plays’ in a list.
-
Playbooks can contain multiple plays. You may have a playbook that targets first the web servers, and then the database servers. For example:
---
- hosts: webservers
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum:
name: httpd
state: latest
- name: write the apache config file
template:
src: /srv/httpd.j2
dest: /etc/httpd.conf
- hosts: databases
remote_user: root
tasks:
- name: ensure postgresql is at the latest version
yum:
name: postgresql
state: latest
- name: ensure that postgresql is started
service:
name: postgresql
state: started
Playbook Explanation
Hosts and Users
For each play in a playbook, you get to choose which machines in your infrastructure to target and what remote user to complete the tasks.
---
- hosts: webservers
remote_user: root
Remote users can also be defined per task:
---
- hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
remote_user: yourname
Ansible Supports for running things as another user is also available, using become:yes variable
---
- hosts: webservers
remote_user: yourname
become: yes
You can also login as you, and then become a user different than root:
---
- hosts: webservers
remote_user: yourname
become: yes
become_user: postgresql
Tasks
Each play contains a list of tasks. Tasks are executed in order, one at a time, against all machines matched by the host pattern, before moving on to the next task.
tasks:
- name: make sure apache is running
service:
name: httpd
state: started
-
Every task should have a name, which is included in the output from running the playbook.
-
The goal of each task is to execute a module(in above - its `service`), with very specific arguments. Variables can be used in arguments to modules.
-
Tasks can be declared using the legacy `action: module options` format, but it is recommended to use `module: options` format.
-
Each module may `key=value` arguments
The command and shell modules are the only modules that just take a list of arguments.
tasks:
- name: enable selinux
command: /sbin/setenforce 1
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
Playbook Variables
Playbook variables are Similar to YAML dictionaries. To define a variable in a playbook, simply use the keyword vars before writing your variables with indentation.
To access the value of the variable ``
Here’s a simple playbook example:
- hosts: all
vars:
greeting: Hello world!
tasks:
- name: Ansible Basic Variable Example
debug:
msg: ""
Example: Copy file to hosts Example
-
create a file called tmp/file in all hosts `– hosts: all`
-
create a file only in [web] hosts `– hosts: web`
-
create a file in all hosts, except [db] hosts
-
create a file in all hosts & [backup] hosts, except [web] hosts
-
Touch – will create the file if doesn’t exist
-
Absent – will remove specified files
1.Inventory file
I have following hosts, which are placed in an Inventory file in this location (/home/vagrant/Ansible/inventory)
# /home/vagrant/Ansible/inventory
[all]
web1 ansible_ssh_host=192.168.33.11
web2 ansible_ssh_host=192.168.33.12
db1 ansible_ssh_host=192.168.33.13
db2 ansible_ssh_host=192.168.33.14
[web]
web1
web2
[db]
db1
db2
[backup]
db2
Here we have [Groups], each group have hosts
Test the Connection , by ping
Here I’m trying to connect to machines and run a ping command on nodes using
ansible.
ansible -i inventory all -m ping
2.Playbook yml
Remember – all playbooks start with —(there dashs) because its YAML file. Save playbook in .yml extension(playbook1_copyfile.yml)
---
- hosts: all
tasks:
- name: create a file on a remote machine
file:
dest: /tmp/file
state: ''
- hosts: web
tasks:
- name: create file on web machines
file:
dest: /tmp/web-file
state: ''
- hosts: all:!db
tasks:
- name: create file on all hosts - Except DB hosts
file:
dest: /tmp/all-but-not-db-file
state: ''
- hosts: all:&backup:!web
tasks:
- name: create file on all hosts and BACKUP hosts- Except DB hosts
file:
dest: /tmp/all-and-backup-file-not-web
state: ''
** - we are passing `` variable at RUNTIME
3.Run play in inventory hosts
Syntax:
ansible-playbook -i <inventory_file> <playbook_yml_file>.yml -e <envi_varible>=<value>
ansible-playbook -i inventory playbook1_copyfile.yml -e file_state=touch
Login to each node, check files created under /tmp/ folder
Reusable Playbooks
In Ansible, we have three ways to reuse playbooks
-
includes
-
imports
-
roles
Includes and imports allow users to break up large playbooks into smaller files, which can be used across multiple parent playbooks or even multiple times within the same Playbook.
Roles allow more than just tasks to be packaged together and can include variables, handlers, or even modules and other plugins. Unlike includes and imports, roles can also be uploaded and shared via Ansible Galaxy.
You can then use import_tasks or include_tasks to execute the tasks in a file in the main task list:
tasks:
- import_tasks: common_tasks.yml
# or
- include_tasks: common_tasks.yml
Importing Playbooks
It is possible to include playbooks inside a master
playbook. For example:
- import_playbook: webservers.yml
- import_playbook: databases.yml
Roles are ways of automatically loading certain vars_files, tasks, and handlers based on a known file structure. Grouping content by roles also allows easy sharing of roles with other users.
Role Directory Structure
## Example project structure:
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
Roles expect files to be in certain directory names. Roles must include at least one of these directories, however it is perfectly fine to exclude any which are not being used. When in use, each directory must contain a main.yml file, which contains the relevant content: