Chapter 4
Ansible utility and Configurations
Host Inventory
Saying hello to the nodes
Host Patterns
Ad Hoc Operations
Invoking Modules
ansible <host-pattern> [options]
ansible --version
ansible --help
Where ?
How ?
Default Path:
/etc/ansible/ansible.cfg
Follows ini style configurations
Contains [blocks] of configurations
with
key = value pairs
[defaults]
inventory = /etc/ansible/hosts
library = /usr/share/my_modules/
forks = 5
sudo_user = root
ask_pass = True
remote_port = 22
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[colors]
highlight = white
verbose = blue
warn = bright purple
error = red
debug = dark gray
deprecate = purple
Configuration file can be created from other paths too (e.g. home dir, current dir)
Parameters can be overridden in ansible-playbook or with command line flags
ANSIBLE_CONFIG environment variable can be used to define configuration path
~/ansible.cfg
./ansible.cfg
Q: When I have so many options to provide configurations,
which one will ansible pick
?
Ans
Based on Precedence Level
ANSIBLE_CONFIG
./ansible.cfg
~/.ansible.cfg
/etc/ansible/ansible.cfg
P1
P2
P3
P4
command line flags
P5
Project Specific
Best Practice: Its a good idea to create project specific configurations inside your workspace
./ansible.cfg
overrides defaults
revision controlled
switch configurations for each project
current directory
[defaults]
remote_user = devops
inventory = environments/prod
retry_files_save_path = /tmp
host_key_checking = False
log_path=~/ansible.log
$ cd chap4
Create project specific ansible.cfg with the following contents
List of servers ansible is to manage
ini format
[app]
app-01.blr.example.org
app-02.blr.example.org
app-01.bom.example.org
app-02.bom.example.org
[db]
db-01.blr.example.org
db-01.bom.exmaple.org
[blr:children]
app
db
think of /etc/hosts file
host groups
connection strings/hosts
group of groups
[app]
app-01.blr.example.org
app-02.blr.example.org ansible_user=vagrant
app-01.bom.example.org
app-02.bom.example.org apache_port=8080 max_connections=4000
[db]
db-01.blr.example.org:5000 ansible_user=centos
db-01.bom.exmaple.org
[blr:children]
app
db
[blr:vars]
dc_loc=bangalore
apache_port=9000
connection info
hostvars
groupvars
groups, hosts
ansible_host
The name of the host to connect to, if different from the alias you wish to give to it.
ansible_port
The ssh port number, if not 22
ansible_user
The default ssh user name to use.
ansible_ssh_pass
The ssh password to use (this is insecure, we strongly recommend using --ask-pass or SSH keys)
Control
lb
app1
app2
db
[local]
localhost ansible_connection=local
[lb]
lb
[app]
app1
app2
[db]
db
[prod:children]
lb
app
db
create directory to hold env
specific hosts
mkdir environments
cd environments
file: environments/prod
Objective of this exercise is to setup connectivity
ansible all -m ping
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.61.12 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.61.13 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.61.11 | SUCCESS => {
"changed": false,
"ping": "pong"
}
between control node and managed nodes in the inventory
using passwordless ssh
Ansible works over ssh transport, instead of creating its own transport.
Ansible
host1
host2
hostn
ssh
ssh-keygen -t rsa
[output]
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
d8:e3:80:aa:d7:36:9b:45:bf:dc:18:c2:b2:6c:02:36 root@ansible
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
| . o |
| . + S |
|.E . o + . |
|..o.. + + |
| .o.== o = |
|.. +=o + . |
+-----------------+
ssh-keygen -t rsa
ssh-copy-id devops@lb
ssh-copy-id devops@app1
ssh-copy-id devops@app2
ssh-copy-id devops@db
ssh-copy-id user@host
# ssh-copy-id root@app1
The authenticity of host '192.168.61.13 (192.168.61.13)' can't be established.
RSA key fingerprint is 32:7f:ad:d7:da:63:32:b6:a9:ff:59:af:09:1e:56:22.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.61.13' (RSA) to the list of known hosts.
vagrant@192.168.61.13's password:
Now try logging into the machine, with "ssh 'vagrant@192.168.61.13'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
Sample Output
ssh devops@lb
ssh devops@app1
ssh devops@app2
ssh devops@db
ssh user@host
ssh root@app1
Last login: Sun Sep 4 03:24:21 2016 from 192.168.61.10
#######################################################################################################
# #
# #
# _____ _ _ ____ __ _____ ____ #
# / ____| | | | | / __ \ / _| | __ \ / __ \ #
# | (___ ___ | |__ ___ ___ | | | | | || |_ | | | | ___ __ __| | | | _ __ ___ #
# \___ \ / __|| '_ \ / _ \ / _ \ | | | | | || _| | | | | / _ \\ \ / /| | | || '_ \ / __| #
# ____) || (__ | | | || (_) || (_) || | | |__| || | | |__| || __/ \ V / | |__| || |_) |\__ \ #
# |_____/ \___||_| |_| \___/ \___/ |_| \____/ |_| |_____/ \___| \_/ \____/ | .__/ |___/ #
# | | #
# |_| #
# www.schoolofdevops.com #
# #
# #
#######################################################################################################
Sample Output
root@control:/workspace/chap4# ansible all -m ping
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
db | SUCCESS => {
"changed": false,
"ping": "pong"
}
lb | SUCCESS => {
"changed": false,
"ping": "pong"
}
app2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
app1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible all -m ping
host pattern
lb | SUCCESS => { "changed": false, "ping": "pong" }
host pattern
define hosts
or group of hosts
being managed
ansible all -m <module> -a <args>
wildcards
all
*
app*
*.example.com
hosts/groups
app1
app1:app2
db
app:lb
exclusion
'prod:!db'
intersection
'prod:&app'
subscripts
app[0]
app[-1]
prod[0:3]
prod[2:]
regex
'~(app|db).*'
--limit
In addition to the host patterns, --limit option can be used along with ansible and ansible-playbook commands to restrict execution to specific set of hosts/groups
ansible all -m ping
ansible '*" -m ping
ansible app* -m ping
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
lb | SUCCESS => {
"changed": false,
"ping": "pong"
}
app1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
db | SUCCESS => {
"changed": false,
"ping": "pong"
}
app2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Commands
ansible app1 -m ping
ansible app1:app2 -m ping
ansible app:db:lb -m ping
ansible prod -m ping
Commands
ansible 'prod:!db' -m ping
ansible 'prod:&lb' -m ping
ansible 'prod:!db:&app' -m ping
Commands
'prod:!db'
Remember to use single quotes ' '
ansible 'app[0]' -m ping
ansible 'app[-1]' -m ping
ansible 'prod[0:3]' -m ping
ansible 'prod[2:]' -m ping
Commands
ansible '~(app|db).*' -m ping
ansible '~(^ap)' -m ping
ansible '~(^app[0:1])' -m ping
Commands
ansible all -m ping --limit app
ansible app -m ping --limit app1
ansible prod -m ping --limit lb
ansible prod -m ping --limit lb:app
ansible prod -m ping --limit 'lb:app:!prod'
Commands
now that we have some nodes to manage, lets run some ad hoc commands
just how you would do it from the CLI
https://github.com/schoolofdevops/ansible-tutorial/blob/master/manuscript/chapter3.md
ansible all -a hostname
[root@ansible chap2]# ansible all -a hostname
localhost | SUCCESS | rc=0 >>
ansible
192.168.61.11 | SUCCESS | rc=0 >>
db
192.168.61.13 | SUCCESS | rc=0 >>
app
192.168.61.12 | SUCCESS | rc=0 >>
app
ansible all -a uptime
# ansible all -a uptime
localhost | SUCCESS | rc=0 >>
03:42:29 up 3:44, 2 users, load average: 0.06, 0.03, 0.01
192.168.61.11 | SUCCESS | rc=0 >>
03:42:30 up 3:41, 1 user, load average: 0.02, 0.01, 0.00
192.168.61.12 | SUCCESS | rc=0 >>
03:42:30 up 3:58, 1 user, load average: 0.00, 0.00, 0.00
192.168.61.13 | SUCCESS | rc=0 >>
03:42:30 up 3:36, 1 user, load average: 0.08, 0.02, 0.01
ansible app -a free
# ansible app -a free
192.168.61.12 | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 372920 128528 244392 452 14428 50872
-/+ buffers/cache: 63228 309692
Swap: 4128764 0 4128764
192.168.61.13 | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 372920 215120 157800 480 15344 136540
-/+ buffers/cache: 63236 309684
Swap: 4128764 220 4128544
# ansible all -a uptime
localhost | SUCCESS | rc=0 >>
03:42:29 up 3:44, 2 users, load average: 0.06, 0.03, 0.01
192.168.61.11 | SUCCESS | rc=0 >>
03:42:30 up 3:41, 1 user, load average: 0.02, 0.01, 0.00
192.168.61.12 | SUCCESS | rc=0 >>
03:42:30 up 3:58, 1 user, load average: 0.00, 0.00, 0.00
192.168.61.13 | SUCCESS | rc=0 >>
03:42:30 up 3:36, 1 user, load average: 0.08, 0.02, 0.01
192.168.3.45 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh.",
"unreachable": true
}
status
ansible db -a "yum install -y vim"
root@control:/workspace/chap3# ansible db -a "yum install vim "
db | FAILED | rc=1 >>
Loaded plugins: fastestmirror, ovlovl: Error while doing RPMdb copy-up:
[Errno 13] Permission denied: '/var/lib/rpm/Sigmd5'
You need to be root to perform this command.
FAILED
ansible db -b -a "yum install -y vim"
192.168.61.13 | SUCCESS | rc=0 >>
dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
docker-engine x86_64 1.7.1-1.el6 local_docker 4.5 M
Transaction Summary
================================================================================
Install 1 Package(s)
Total download size: 4.5 M
Installed size: 19 M
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : docker-engine-1.7.1-1.el6.x86_64 1/1
Verifying : docker-engine-1.7.1-1.el6.x86_64 1/1
Installed:
docker-engine.x86_64 0:1.7.1-1.el6
Complete!
SUCCESS
ansible all -f 1 -a "free"
# ansible all -f 1 -a "free"
192.168.61.14 | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 243904 103500 140404 464 14644 31212
-/+ buffers/cache: 57644 186260
Swap: 4128764 3076 4125688
192.168.61.12 | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 372920 204560 168360 320 18424 127588
-/+ buffers/cache: 58548 314372
Swap: 4128764 5032 4123732
192.168.61.13 | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 372920 203080 169840 312 18452 126692
-/+ buffers/cache: 57936 314984
Swap: 4128764 4944 4123820
192.168.61.11 | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 501944 281180 220764 480 21100 193168
-/+ buffers/cache: 66912 435032
Swap: 4128764 0 4128764
localhost | SUCCESS | rc=0 >>
total used free shared buffers cached
Mem: 372920 342104 30816 904 11712 222508
-/+ buffers/cache: 107884 265036
Swap: 4128764 376 4128388