Ansible
Ansible (an IT automation, Configuration Management and Provision tool) is a simple, flexible, and
extremely powerful tool that gives you the ability to automate common infrastructure tasks, run ad
hoc commands, and deploy multitier applications spanning multiple machines.
Main features
● Age tless ● Se u e ● P o isio i g AND deplo e t ● Eas to sta t ● Ide pote t
Controller: This is the only host that needs to have Ansible installed, and works as a controller. This
is used to launch the ansible-playbook commands from the controller.
Ansible is agentless and manages nodes using SSH transport, no additional setup is needed on the
nodes except for ensuring that the SSH service is running.
KEY COMPONENTS
★ Modules (Tools) ★ Tasks ★ Inventory ★ Plays ★ Playbook (Plan)
A playbook consists of one or more plays, which map groups of hosts to well-defined tasks.
YAML – the playbook language:
• The fi st li e of a pla ook should egi ith "--- " (three hyphens) which indicates the beginning
of the YAML document.
• Lists i YAML a e ep ese ted ith a h phe follo ed a white space. A playbook contains a list
of plays; they are represented with "- ". Each play is an associative array, a dictionary, or a map in
terms of key-value pairs.
• I de tatio s a e i po ta t. All e e s of a list should e at the sa e i de tatio le el. • Ea h
play can contain key-value pairs separated by ":" to denote hosts, variables, roles, tasks, and so on.
Creating a host inventory:
Before we even start writing our playbook with Ansible, we need to define an inventory of all hosts
that need to be configured, and make it available for Ansible to use. Later, we will start running plays
against a selection of hosts from this inventory. For text-based local inventory, the default location is
/etc/ansible/hosts.
Tasks:
Plays map hosts to tasks. Tasks are a sequence of actions performed against a group of hosts that
match the pattern specified in a play. Each play typically contains multiple tasks that are run serially
on each machine that matches the pattern.
Modules:
Modules are the encapsulated procedures that are responsible for managing specific system
o po e ts o spe ifi platfo s. Co side the follo i g e a ple: • The apt odule fo De ia a d
the u odule fo RedHat helps a age s ste pa kages • The use odule is responsible for
addi g, e o i g, o odif i g use s o the s ste • The se i e odule ill sta t/stop s ste
services Modules abstract the actual implementation from users. They expose a declarative syntax
that accepts a list of the parameters and states of the system components being managed. All this
can be declared using the human-readable YAML syntax, using key-value pairs.
Bits of code copied to the target system. Executed to satisfy the task declaration.
LIST ALL MODULES
#ansible-doc -l
VIEW MODULE DOCUMENTATION
#ansible-doc <module_name>
The modules and idempotence:
Idempotence is an important characteristic of a module. It is something which can be applied on
your system multiple times, and will return deterministic results. It has built-in intelligence. For
instance, we have a task that uses the apt module to install Nginx and ensure that it's up to date.
Here is what happens if you run it multiple times:
• E e ti e ide pota e is u ultiple ti es, the apt odule ill o pa e hat has been
declared in the playbook versus the current state of that package on the system. The first time it
runs, Ansible will determine that Nginx is not installed, and will go ahead with the installation.
• Fo e e o se ue t u , it ill skip the installation part, unless there is a new version of the
package available in the upstream repositories. This allows executing the same task multiple times
without resulting in the error state. Most of the Ansible modules are idempotent, except for the
command and shell modules. Users will have to make these modules idempotent.
Understanding roles:
Roles provide a way to create modular code, which then can then be shared and reused.
Lab setup:
server1:
# iptables -F
#service iptables stop
# chkconfig iptables
# vi /etc/sysconfig/selinux
SELINUX=disabled
# vi /etc/hosts
IPaddr1 server1
IPaddr2 server2
IPaddr3 server3
#userdd test
# passwd test
# visudo
test ALL=(ALL) NOPASSWD:ALL
# reboot
Perform above steps on server2 and server3.
server1:
# yum install epel-release
# yum install ansible
# cd /etc/ansible
#mv hosts hosts.bak
#vi hosts
[webserver]
server2
server3
# su – test
$ ssh-keygen
$ ssh-copy-id server2
$ ssh-copy-id server3
Discuss about ad-hoc commands in class.
All the below example run as test user.
Example1:
$ vi webserver.yml
--- # webserver setup
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing httpd package
yum: name=httpd state=present
- name: copy index.html
copy: src=index.html dest=/var/www/html
- name: start httpd server
service: name=httpd state=started
$ ansible-playbook webserver.yml
Example2:
$ vi variables.yml
--- # Learning about variables
- hosts: '{{host}}'
remote_user: test
become: yes
vars:
pkg1: httpd
vars_files:
- abc.yml
vars_prompt:
- name: pkg3
prompt: enter package name
private: no
tasks:
- name: installing httpd package
yum: name={{pkg1}} state=present
- name: copy index.html
copy: src=index.html dest=/var/www/html
- name: start httpd server
service: name={{pkg1}} state=started
- name: installing telnet package
yum: name={{pkg2}} state=present
- name: installing user given package
yum: name={{pkg3}} state=present
$ more abc.yml
---
pkg2: telnet
$ ansible-playbook variables.yml –extra-vars hosts=webserver
Example3:
Dealing with errors.
$ vi errors.yml
--- # errors programs
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing httpd package
yum: name=httpd1 state=present
ignore_errors: yes
- name: copy index.html
copy: src=index.html dest=/var/www/html
- name: start httpd server
service: name=httpd state=started
$ ansible-playbook errors.yml
Example4:
Handler usage:
● Spe ial task, u s o l if the e as ha ge.
● Usa le fo se i e esta ts, data ase upload, ...
$ vi handler.yml
--- # handler usage
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing httpd package
yum: name=httpd state=present
- name: copy index.html
copy: src=index.html dest=/var/www/html
notify: start httpd service
handlers:
- name: start httpd service
service: name=httpd state=restarted
$ ansible-playbook handler.yml
Example5:
Command,Shell, Raw amd Script modules.
$ vi commands.yml
--- # commands example
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: create a file
command: touch testfile creates=/home/user1/testfile
- name: list of all files
shell: ls > /tmp/abc
- name: create directory
raw: mkdir /home/user1/testdir3 creates=/home/user1/ppp
- name: execute a script
script: ./xyz.sh
$ more xyz.sh
#! /bin/bash
echo "hello" > /home/user1/file1
$ ansible-playbook commands.sh
Example6:
Gathering facts
$ vi fact.yml
--- # gather facts
- hosts: webserver
remote_user: test
become: yes
gather_facts: yes
tasks:
- name: installing httpd package
yum: name=httpd state=present
- name: copy index.html
copy: src=index.html dest=/var/www/html
- name: start httpd server
service: name=httpd state=started
$ ansible-playbook fact.yml
Example7:
$ vi condition.yml
--- # example on condition
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing httpd package on Redhat
yum: name=httpd state=present
when: ansible_os_family == "RedHat"
- name: installing httpd package on ubuntu
yum: name=apache2 state=present
when: ansible_os_family == "Debian"
- name: copy index.html
copy: src=index.html dest=/var/www/html
- name: start httpd server
service: name=httpd state=started
$ ansible-playbook condition.yml
Example8:
$ vi template.yml
--- # template example
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: copy new index.html
template: src=index.html.j2 dest=/tmp/index.html
$ more index.html.j2
hello
{{ansible_hostname}}
World
$ ansible-playbook template.yml
Example 9:
$ vi register.yml
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing httpd package
yum: name=httpd state=present
- name: copy index.html
copy: src=index.html dest=/var/www/html
- name: start httpd server
service: name=httpd state=started
register: result
- debug: var=result
$ ansible-playbook template.yml
Example10:
$ vi tag.yml
--- # tag example
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing httpd package
yum: name=httpd state=present
tags:
- install
- name: copy index.html
copy: src=index.html dest=/var/www/html
tags:
- copy
- name: start httpd server
service: name=httpd state=started
tags:
- service
$ ansible-playbook tag.yml --tags install
Example11:
Loops:
$ vi loops.yml
- hosts: webserver
remote_user: test
become: yes
tasks:
- name: installing packages
yum: name={{item}}httpd state=present
with_items:
- lynx
- telnet
- curl
$ ansible-playbook loops.yml
Example12:
$ vi unarchive.yml
--- # unarchive example
- hosts: server2
remote_user: test
become: yes
tasks:
- name: unarchiving to server 2 for test
unarchive: src=playbook.tar.gz dest=/home/test
$ ansible-playbook unarchive.yml
Example13:
$ vi url.yml
--- # get url setup
- hosts: server2
remote_user: test
become: yes
tasks:
- name: get url data
get_url: url=http://rediff.com/index.html dest=/home/test/rediff.html
$ ansible-playbook url.yml
Example14:
Roles
$ cd /home/test
$ mkdir roles
$ cd roles; mkdir webservers; cd webservers
$ mkdir {defaults,files,handlers,meta,tasks,templates,vars}
$ cd tasks
$ vi main.yml
---
- name: Install apache package
yum: pkg=httpd state=present
-name: copy index.html
copy: src=index.html dest=/var/www/html
notify: restart httpd
-name: start httpd service
service: name=httpd state=started
$ cd ../files
$ vi index.html
Checking roles concept
$ cd ../handlers
$ vi main.yml
---
-name: restart httpd
Service: name=httpd state=restarted
$ vi role1.yml
--- # role 1 Webserver setup
- hosts: webserver
remote_user: test
become_method: sudo
become: yes
roles:
- webservers
$ ansible-playbook role1.yml
Example15:
Tomcat installation:
$ vi tomcat.yml
--- # tomcat setup
- hosts: server2
remote_user: test
become: yes
tasks:
- name: remove older version of tomcat
file: path=/usr/local/tomcat state=absent
- name: download tomcat
get_url: url=http://mirror.fibergrid.in/apache/tomcat/tomcat-7/v7.0.78/bin/apache-tomcat-
7.0.78.tar.gz dest=/tmp
- name: create tomcat folder
command: mkdir /usr/local/tomcat
- name: extract archive
unarchive: src=/tmp/apache-tomcat-7.0.78.tar.gz dest=/usr/local/tomcat copy=no
- name: create tomcat users
copy: src=/home/user1/tomcat-users.xml dest=/usr/local/tomcat/apache-tomcat-7.0.78/conf/
- name: start tomcat
command: nohup /usr/local/tomcat/apache-tomcat-7.0.78/bin/startup.sh &
$ ansible-playbook tomcat.yml
Example16:
Ansible-vault can encrypt any structured data.
$ ansible-vault encrypt webserver.yml
$ ansible-playbook webserver.yml --ask-vault-pass
Example 17:
Using an Ansible playbook:
1. Change SELINUX to permissive mode on all your hosts
2. Install HTTPD on your web hosts only
3. Start and Enable HTTPD service on web hosts only if a new httpd package is installed.
4. Copy an motd file saying Welcome to my server! to all your hosts
5. Copy an hello world index.html file to your web hosts in /var/www/html
6. Modify the sshd.conf to set PermitRootLogin at no
Solution:
$ vi sol1.yml
--
- hosts: all
remote_user: test
become: yes
vars:
selinux: permissive
tasks:
- name: Configure selinux to {{ selinux }}
selinux: policy: targeted state: "{{ selinux }}"
- name: Copy motd file
copy: src=motd dest=/etc/motd
-hosts: web
remote_user: test
become: yes
tasks:
- name: Install Apache
yum: name=httpd state=present
notify: Restart Apache
- name: Copy Index.html
copy: src=index.html dest=/var/www/html/index.html
- name: Set ssh root login at no
lineinfile: dest=/etc/ssh/sshd_config line="PermitRootLogin no" state=present
notify: RestartSSH
handlers:
- name: Restart Apache
service: name=httpd state=restarted enabled=yes
- name: RestartSSH
service: name=sshd state=restarted enable=yes
$ ansible-playbook sol1.yml
Discuss about Ansible Tower and Ansible Galaxy along with other cases in class.