getting started with ansible

Ad hoc server management

Chapter 4

TOPICS

  • 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

ANSIBLE UTILITY

configs

Where  ?

How ?

Configs

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      

Configs

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

Config FILES precedence

ANSIBLE_CONFIG
./ansible.cfg
~/.ansible.cfg
/etc/ansible/ansible.cfg

P1

P2

P3

 

P4

command line flags

P5

Configs

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

BEST PRACTICE

GE

[defaults]
remote_user = devops
inventory   = environments/prod
retry_files_save_path = /tmp
host_key_checking = False
log_path=~/ansible.log

create custom config

$ cd chap4

 

Create project specific ansible.cfg with the following contents

Inventories

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

hosts

Inventories

connection parameters

groups

hostvars

groupvars

could contain

Inventories

[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

SSH Connection options

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)

Inventories

types

static

dynamic

Control
lb
app1
app2
db

GE

Creating inventory

[local]
localhost ansible_connection=local

[lb]
lb

[app]
app1
app2


[db]
db

[prod:children]
lb
app
db

Creating inventory

create directory to hold env 
specific hosts

GE

mkdir environments
cd environments

file: environments/prod

saying hello 

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"
}

GE

between control node and managed nodes in the inventory
using passwordless ssh

setup ssh 

Ansible works over ssh transport, instead of creating its own transport. 

Ansible

host1
host2
hostn

ssh

GE

setup ssh 

Generating SSH Keys on Control Node

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

GE

setup ssh 

copy ssh pub key to all inventory hosts

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

GE

setup ssh 

validate passwordless login

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

GE

say hello to nodes

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

GE

host pattern

lb | SUCCESS => {                                              
    "changed": false,                                          
    "ping": "pong"                                             
}                 

Host patterns

host pattern

define hosts

or group of hosts

being managed

ansible all -m <module> -a <args>

Host patterns

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

wildcards

ansible all -m ping

ansible '*" -m ping

ansible app* -m ping

GE

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

hosts / groups

ansible app1 -m ping

ansible app1:app2 -m ping

ansible app:db:lb -m ping

ansible prod -m ping

GE

Commands

exclusion / intersection

ansible 'prod:!db' -m ping

ansible 'prod:&lb' -m ping

ansible 'prod:!db:&app' -m ping

GE

Commands

'prod:!db'

Remember to use single quotes ' '

subscripts

ansible 'app[0]' -m ping

ansible 'app[-1]' -m ping

ansible 'prod[0:3]' -m ping

ansible 'prod[2:]' -m ping



GE

Commands

regex

ansible '~(app|db).*' -m ping

ansible '~(^ap)' -m ping

ansible '~(^app[0:1])' -m ping

GE

Commands

limit

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'


GE

Commands

now that we have some nodes to manage, lets run some ad hoc commands  
just how you would do it from the CLI

Ad hoc server management

GE

https://github.com/schoolofdevops/ansible-tutorial/blob/master/manuscript/chapter3.md

hostnames

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

GE

uptime

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

GE

check memory on app servers

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

GE

Command STATUS

# 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

GE

installing packages

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

GE

installing packages

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

GE

Running on one host at a time

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

GE

Made with Slides.com