Ansible For Beginners - KodeKloud PDF
Ansible For Beginners - KodeKloud PDF
Ansible For Beginners - KodeKloud PDF
www.kodekloud.com
Ansible
For the
Absolute Beginner
MUMSHAD
w w w . k o d e k l o u d . c o m
MANNAMBETH
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Variables
Conditionals
Loops
Roles
Hands-On Exercises
www.kodekloud.com
Note
• Do not copy code from this file directly as it may affect the
formatting.
• Always refer to git repositories to access code.
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Variables
Conditionals
Loops
Roles
Ansible
Introduction
Why Ansible?
• Time • Simple
• Coding Skills • Powerful
• Maintenance • Agentless
Scripts
Scripts vs Ansible Playbook
#!/bin/bash
# Script to add a user to Linux system
if [ $(id -u) -eq 0 ]; then - hosts: all_my_db_servers
all_my_web_servers_in_DR
all_my_web_servers_on_cloud
localhost
$username=johndoe tasks:
read -s -p "Enter password : " password - user:
egrep "^$username" /etc/passwd >/dev/null name: johndoe
if [ $? -eq 0 ]; then
echo "$username exists!"
exit 1
else
useradd -m -p $password $username
[ $? -eq 0 ] && echo "User has been added
to system!" || echo "Failed to add a user!"
fi
fi
Use case example - Simple
Use case example - complex
Use case example - complex
Ansible Documentation
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Variables
Conditionals
Loops
Roles
Ansible
Install
Control Node
Redhat or CentOS – $ sudo yum install ansible
https://docs.ansible.com/ansible/latest/installation_guide/
Install Control Node on Redhat or CentOS
www.kodekloud.com
https://www.kodekloud.com
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Variables
Conditionals
Loops
Roles
https://www.kodekloud.com
Ansible
Inventory
inventory
server1.company.com
server2.company.com
[mail]
server3.company.com
server4.company.com
[db]
server5.company.com
server6.company.com
[web]
server7.company.com
server8.company.com
Linux – SSH
Windows – Powershell Remoting
inventory
/etc/ansible/hosts Agentless
More on inventory files
#Sample Inventory File
web
server1.company.com
ansible_host= ansible_connection=ssh ansible_user=root
db
server2.company.com
ansible_host= ansible_connection=winrm ansible_user=admin
mail
server3.company.com
ansible_host= ansible_connection=ssh ansible_ssh_pass=P@#
web2
server4.company.com
ansible_host= ansible_connection=winrm
localhost ansible_connection=localhost
https://www.kodekloud.com
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Variables
Conditionals
Loops
Roles
https://www.kodekloud.com
Ansible
Playbooks
Ansible playbooks
# Simple Ansible Playbook # Complex Ansible Playbook
-
name: Play 1
hosts: localhost
tasks:
- name: Execute command ‘date’
command: date
-
name: Play 2
hosts: localhost
tasks:
- name: Install web service
yum:
name: httpd
state: present
https://www.kodekloud.com
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Modules
Variables
Conditionals
Loops
Roles
https://www.kodekloud.com
Ansible
Modules
modules
• System - Win_copy
Mongodb
User
Command
Acl
Amazon
- Win_command
Mssql
Group
Expect
Archive
Atomic
• Commands - Win_domain
Mysql
Hostname
Raw
Copy
Azure
- Win_file
Postgresql
Iptables
Script
File
Centrylink
• Files - Win_iis_website
Proxysql
Lvg
Shell
Find
Cloudscale
- Win_msg
vertica
Lvol
Lineinfile
Cloudstack
• Database - Win_msi
Make Ocean
Replace
Digital
• Cloud -
-
Win_package
Mount
Stat
Docker
Win_ping
Ping
Template
Google
• Windows - Win_path
Timezone
Unarchive
Linode
- Win_robocopy
Systemd
Openstack
• More.. - Win_regedit
Service
Rackspace
- Win_shell
Smartos
- Win_service
Softlayer
- Win_user
VMware
- And more
command
Executes a command on a remote node
playbook.yml
parameter comments -
chdir cd into this directory before running the command name: Play 1
hosts: localhost
creates a filename or (since 2.0) glob pattern, when it already exists, this step tasks:
will not be run. - name: Execute command ‘date’
command: date
executable change the shell used to execute the command. Should be an absolute
path to the executable.
- name: Display resolv.conf contents
free_form the command module takes a free form command to run. There is no command: cat /etc/resolv.conf
parameter actually named 'free form'. See the examples!
- name: Display resolv.conf contents
command: cat resolv.conf chdir=/etc
removes a filename or (since 2.0) glob pattern, when it does not exist, this step
will not be run. - name: Display resolv.conf contents
command: mkdir /folder creates=/folder
warn if command warnings are on in ansible.cfg, do not warn about this
(added in 1.8) particular line if set to no/false.
playbook.yml
-
name: Play 1
hosts: localhost
1. Copy script to remote systems tasks:
2. Execute script on remote systems - name: Run a script on remote server
script: /some/local/script.sh -arg1 -arg2
Scripts
Service
• Manage Services – Start, Stop, Restart
playbook.yml playbook.yml
- -
name: Start Services in order name: Start Services in order
hosts: localhost hosts: localhost
tasks: tasks:
- name: Start the database service - name: Start the database service
service: name=postgresql state=started service:
name: postgresql
state: started
- name: Start the httpd service
service: name=httpd state=started
playbook.yml script.sh
- #Sample script
name: Add DNS server to resolv.conf
hosts: localhost echo “nameserver 10.1.250.10” >> /etc/resolv.conf
tasks:
- lineinfile:
path: /etc/resolv.conf
line: 'nameserver 10.1.250.10'
/etc/resolv.conf
https://www.kodekloud.com
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Modules
Variables
Conditionals
Loops
Roles
https://www.kodekloud.com
Ansible
Variables
Variable
• Stores information that varies with each host
inventory
Web1 ansible_host=server1.company.com ansible_connection=ssh ansible_shh_pass=P@ssW
db ansible_host=server2.company.com ansible_connection=winrm ansible_shh_pass=P@s
Web2 ansible_host=server3.company.com ansible_connection=ssh ansible_shh_pass=P@ssW
Playbook.yml variables
- variable1: value1
name: Add DNS server to resolv.conf variable2: value2
hosts: localhost
tasks:
vars:
- lineinfile:
dns_server: 10.1.250.10
path: /etc/resolv.conf
line: 'nameserver 10.1.250.10'
Using variables
Playbook.yml
-
name: Add DNS server to resolv.conf
hosts: localhost
vars:
dns_server: 10.1.250.10
tasks:
- lineinfile:
path: /etc/resolv.conf
line: 'nameserver {{ dns_server }}’
10.1.250.10'
-
#Sample Inventory File
name: Set Firewall Configurations
hosts: web Web http_port= snmp_port= inter_ip_range=
tasks:
- firewalld:
service: https
permanent: true #Sample variable File – web.yml
state: enabled
http_port: 8081
- firewalld: snmp_port: 161-162
port: 8081
‘{{/tcp
http_port }}’/tcp inter_ip_range: 192.0.2.0
permanent: true
state: disabled
- firewalld:
161-162
port: ‘{{ snmp_port
/udp }}’/udp
permanent: true
state: disabled {{ }}
- firewalld: Jinja2 Templating
source: 192.0.2.0
‘{{ inter_ip_range
/24 }}’/24
Zone: internal
state: enabled source: {{ inter_ip_range }}
https://www.kodekloud.com
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Modules
Variables
Loops
Conditionals
Roles
https://www.kodekloud.com
Ansible
Loops
LOOPS
- - var: item=joe
name: Create
user: users
name= “{{ item }}” state=present
hosts: localhost
tasks:
- user: name= joe
‘{{ item }}’ state=present
- loop:
user: name=george state=present
- user:
- joename=ravi state=present
- user: name=mani
- george state=present
- user: name=kiran
- ravi state=present
- user: name=jazlan
- mani state=present
- user: name=emaan
- kiran state=present
- user: name=mazin
- jazlan state=present
- user: name=izaan
- emaan state=present
- user: name=mike
- mazin state=present
- user: name=menaal
- izaan state=present
- user: name=shoeb
- mike state=present
- user: name=rani
- menaal state=present
- shoeb
- rani
LOOPS - Visualize
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
- user: name=‘{{ item }}’ state=present
loop: - var: item=
- joe user: name= “{{ item }}” state=present
- george
- ravi - var: item=
- mani user: name= “{{ item }}” state=present
- kiran - var: item=
- jazlan user: name= “{{ item }}” state=present
- emaan
- var: item=
- mazin
user: name= “{{ item }}” state=present
- izaan
- mike - var: item=
- menaal user: name= “{{ item }}” state=present
- shoeb - var: item=
- rani user: name= “{{ item }}” state=present
- var: item=
user: name= “{{ item }}” state=present
- var: item=
user: name= “{{ item }}” state=present
- var: item=
user: name= “{{ item }}” state=present
LOOPS - Visualize
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
- user: name=‘{{ item }}’ state=present
loop: - var: item=joe
- joe user: name= “{{ item }}” state=present
- george
- var: item= george
- ravi
- mani user: name= “{{ item }}” state=present
- kiran - var: item= ravi
- jazlan user: name= “{{ item }}” state=present
- emaan
- var: item= mani
- mazin
user: name= “{{ item }}” state=present
- izaan
- mike - var: item= kiran
- menaal user: name= “{{ item }}” state=present
- shoeb - var: item= jazlan
- rani user: name= “{{ item }}” state=present
- var: item= emaan
user: name= “{{ item }}” state=present
- var: item= mazin
user: name= “{{ item }}” state=present
- var: item= izaan
user: name= “{{ item }}” state=present
LOOPS - Visualize
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
item }}’
- user: name=‘{{ ???? ‘{{ ? }}’
state=present uid=1010
loop: - var: item=joe
-- name:
joe 1010
joe user: name= “{{ item }}” state=present
- uid:
george 1011
1010
- var: item=george
-- name:
ravi george
1012
- uid:
mani 1011
1013 user: name= “{{ item }}” state=present
-- name:
kiran ravi
1014 - var: item=ravi
- uid:
jazlan 1015
1012 user: name= “{{ item }}” state=present
-- name:
emaan mani
1016
- var: item=mani
- uid:
mazin1013
1017
user: name= “{{ item }}” state=present
-- name:
izaan kiran
1018
- uid:
mike 1014
1019 - var: item=kiran
-- name:
menaaljazlan
1020 user: name= “{{ item }}” state=present
- uid:
shoeb1015
1021 - var: item=jazlan
-- name:
rani emaan
1022 user: name= “{{ item }}” state=present
uid: 1016 - var: item=emaan
- name: mazin user: name= “{{ item }}” state=present
uid: 1017 - var: item=mazin
- name: izaan user: name= “{{ item }}” state=present
uid: 1018 - var: item=izaan
- name: mike user: name= “{{ item }}” state=present
LOOPS - Visualize
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
item }}’
- user: name=‘{{ ???? ‘{{ ? }}’
state=present uid=1010 - var:
loop: item:
-- name:
joe joe1010
- uid:
george10101011
-- name:
ravi george
1012 user: name= “{{ ???? }}” state=present uid=“{?}”
- uid:
mani 10111013 - var:
-- name:
kiran ravi1014 item:
- uid:
jazlan10121015
-- name:
emaan mani1016
- uid:
mazin10131017 user: name= “{{ ???? }}” state=present uid=“{?}”
-- name:
izaan kiran
1018
- uid:
mike 10141019 - var:
-- name:
menaaljazlan
1020 item:
- uid:
shoeb10151021
-- name:
rani emaan1022
uid: 1016 user: name= “{{ ???? }}” state=present uid=“{?}”
- name: mazin - var:
uid: 1017 item:
- name: izaan
uid: 1018
- name: mike user: name= “{{ ???? }}” state=present uid=“{?}”
LOOPS - Visualize
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
item }}’
- user: name=‘{{ ???? ‘{{ ? }}’
state=present uid=1010 - var:
loop: item:
-- name:
joe joe1010 name: joe
- uid:
george10101011 uid: 1010
-- name:
ravi george
1012 user: name=‘{{
“{{ ???? }}”
item.name }}’ state=present uid=“{?}”
‘{{ item.uid }
- uid:
mani 10111013
- var:
-- name:
kiran ravi1014
item:
- uid:
jazlan10121015 name: george
-- name:
emaan mani1016 uid: 1011
- uid:
mazin10131017
user: name=‘{{
“{{ ???? }}”
item.name }}’ state=present uid=“{?}”
‘{{ item.uid
-- name:
izaan kiran
1018
- uid:
mike 10141019 - var:
-- name:
menaaljazlan
1020 item:
- uid:
shoeb10151021 name: ravi
-- name:
rani emaan1022 uid: 1012
uid: 1016 user: name= ‘{{
“{{item.name
???? }}”}}’ state=present uid=“{?}”
‘{{ item.uid }
- name: mazin - var:
uid: 1017 item:
- name: izaan name: mani
uid: 1018 uid: 1013
- name: mike user: name=‘{{
“{{ ???? }}”
item.name }}’ state=present uid=“{?}”
‘{{ item.uid }
LOOPS - Visualize
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
- user: name= ‘{{ item }}’
‘{{item.name
???? ‘{{item.uid
}}’ state=present uid=1010
‘{{ ? }}’ }}’ - var:
loop: item:
1010 name: joe
-- name:
joe joe - { name: joe, uid: 1010 }
- uid:
george 1011 uid: 1010
1010
1012 user: name=‘{{
“{{ ???? }}”
item.name }}’ state=present uid=“{?}”
‘{{ item.uid }
-- name:
ravi george - { name: george, uid: 1011 }
- uid: 1013
mani 1011
1014 - var:
-- name:
kiran ravi - { name: ravi, uid: 1012 } item:
- uid:
jazlan 1015 name: george
1012
1016
-- name:
emaan mani - { name: mani, uid: 1013 } uid: 1011
- uid: 1017
mazin1013 user: name=‘{{
“{{ ???? }}”
item.name }}’ state=present uid=“{?}”
‘{{ item.uid
1018
-- name:
izaan kiran - { name: kiran, uid: 1014 }
- uid: 1019
mike 1014 - var:
1020
-- name:
menaaljazlan - { name: jazlan, uid: 1015 } item:
- uid: 1021
shoeb1015 name: ravi
1022 uid: 1012
-- name:
rani emaan - { name: emaan, uid: 1016 }
uid: 1016 user: name= ‘{{
“{{item.name
???? }}”}}’ state=present uid=“{?}”
‘{{ item.uid }
- name: mazin - { name: mazin, uid: 1017 } - var:
uid: 1017 item:
- name: izaan - { name: izaan, uid: 1018 } name: mani
uid: 1018 uid: 1013
- name: mike - { name: mike, uid: 1019 } user: name=‘{{
“{{ ???? }}”
item.name ‘{{ item.uid
}}’ state=present uid=“{?}” }
With_*
- -
name: Create users name: Create users
hosts: localhost hosts: localhost
tasks: tasks:
- user: name=‘{{ item }}’ state=present - user: name=‘{{ item }}’ state=present
loop: with_items:
- joe - joe
- george - george
- ravi - ravi
- mani - mani
With_*
- -
name: Create users name: View Config Files
hosts: localhost hosts: localhost
tasks: tasks:
- user: name=‘{{ item }}’ state=present - debug: var=item
with_items: with_file:
- joe - “/etc/hosts”
- george - “/etc/resolv.conf”
- ravi - “/etc/ntp.conf”
- mani
- -
name: Get from multiple URLs name: Check multiple mongodbs
hosts: localhost hosts: localhost
tasks: tasks:
- debug: var=item - debug: msg=“DB={{ item.database }} PID={{ item.pid}}”
with_url: with_mongodb:
- “https://site1.com/get-servers” - database: dev
- “https://site2.com/get-servers” connection_string: “mongodb://dev.mongo/”
- “https://site3.com/get-servers” - database: prod
connection_string: “mongodb://prod.mongo/”
With_*
with_items With_redis
with_file With_sequence
with_url With_skydive
with_mongodb With_subelements
With_template
with_dict
With_together
with_etcd
with_env With_varnames
with_filetree
With_ini
With_inventory_hostnames
With_k8s
With_manifold
With_nested
With_nios
With_openshift
With_password
With_pipe
With_rabbitmq
Coding
Exercise
www.kodekloud.com
https://www.kodekloud.com
www.kodekloud.com
The Curriculum
RedHat Ansible for Beginners
Introduction to Ansible
Introduction to YAML
Inventory Files
Playbooks
Modules
Variables
Loops
Conditionals
Roles
https://www.kodekloud.com
Ansible
Conditionals
--- ---
- name: Install NGINX - name: Install NGINX
hosts: debian_hosts hosts: redhat_hosts
tasks: tasks:
- name: Install NGINX on Debian - name: Install NGINX on Redhat
apt
apt: yum
yum:
name: nginx name: nginx
state: present state: present
---
- name: Install NGINX
hosts: all
tasks:
- name: Install NGINX on Debian
apt:
apt
name: nginx
state: present
when: ansible_os_family
<< condition >> == “Debian”
- mail:
to: [email protected]
subject: Service Alert
body: Httpd Service is down
when: result.stdout.find('down') != -1
Coding
Exercise
www.kodekloud.com
https://www.kodekloud.com
www.kodekloud.com
Ansible
Roles
Doctor
Engineer
Astronaut
Police
Chef
Doctor mysql
Engineer nginx
Astronaut redis
Police backup
Chef monitor
Doctor mysql
• Go to medical school
• Installing Pre-requisites
• Earn medical degree
• Installing mysql packages
• Complete Residency Program
• Configuring mysql service
• Obtain License
• Configuring database and users
Engineer nginx
• Installing Pre-requisites
• Go to engineering school • Installing nginx packages
• Earn bachelor’s degree • Configuring nginx service
• Gain field experience • Configuring custom web pages
• Gain postgraduate degree
- name: Install and Configure MySQL
hosts: db-server
tasks: mysql
- name: Install Pre-Requisites
yum: name=pre-req-packages state=present • Installing Pre-requisites
• Installing mysql packages
• Configuring mysql service
- name: Install MySQL Packages • Configuring database and users
yum: name=mysql state=present
nginx
- name: Start MySQL Service
service: name=mysql state=started • Installing Pre-requisites
• Installing nginx packages
• Configuring nginx service
- name: Configure Database
• Configuring custom web pages
mysql_db: name=db1 state=present
mysql
• Installing Pre-requisites
• Installing mysql packages
Re-Use • Configuring mysql service
• Configuring database and users
MySQL-Role
README.md
templates
tasks
/etc/ansible/ansible.cfg handlers
roles_path = /etc/ansible/roles vars
defaults
meta
Organize Re-Use Share
playbook.yml roles:
- mysql
roles
mysql
README.md
templates
tasks
handlers
vars
defaults
meta
Find Roles
$ ansible-galaxy search mysql
Found 1126 roles matching your search. Showing first 1000.
Name Description
---- -----------
0utsider.ansible_zabbix_agent Installing and maintaining zabbix-agent for
1mr.unattended install and configure unattended upgrade
1nfinitum.mysql Simply installs MySQL 5.7 on Xenial.
4linuxdevops.mysql-server Instalacao e Configuracao do servidor MySQL
5KYDEV0P5.skydevops-mysql Install and configure MySQL Database
AAbouZaid.yourls Manage Yourls, a URL shortener web app.
AAROC.AAROC_fg-db your description
aaronpederson.ansible-autodeploy Simple deployment tool with hooks
abednarik.mysqld-exporter Install and configure mysqld_exporter
abelboldu.openstack-glance
abelboldu.openstack-keystone
abelboldu.openstack-neutron-controller OpenStack Neutron controller node
abelboldu.openstack-nova-controller OpenStack Nova controller node
achaussier.mysql-backup configure mysql-backup with xtrabackup and
achaussier.mysql-server Install mysql-server package
achilleskal.ansible_mysql8 your description
adarnimrod.mysql Provision a MySQL server
Use Role
$ ansible-galaxy install geerlingguy.mysql
- downloading role 'mysql', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-mysql/archive/2.9.5.tar.gz
- extracting geerlingguy.mysql to /etc/ansible/roles/geerlingguy.mysql
- geerlingguy.mysql (2.9.5) was installed successfully
playbook.yml
- -
name: Install and Configure MySQL name: Install and Configure MySQL
hosts: db-server hosts: db-server
roles: roles:
- geerlingguy.mysql - role: geerlingguy.mysql
become: yes
vars:
mysql_user_name: db-user
Use Role
Playbook-all-in-one.yml Playbook-distributed.yml
- -
name: Install and Configure MySQL name: Install and Configure MySQL
hosts: db-and-webserver hosts: db-server
roles: roles:
- geerlingguy.mysql - geerlingguy.mysql
- nginx
-
name: Install and Configure Web Server
hosts: web-server
roles:
- nginx
mysql
mysql
nginx
List Roles
$ ansible-galaxy list
- geerlingguy.mysql
- kodekloud1.mysql
www.kodekloud.com
https://www.kodekloud.com
Getting Started
www.kodekloud.com