Working With Ansible

Ansible has picked up well and widely used as it is simple and easy to use IT automation tool. Ansible can be used to  administrate servers farms, deploy applications and systems/VM/containers . Ansible configuration is written in plain English and works on the remote/local server using SSH without needing any agent.

I am using Centos 7 for my Ansible implementation . So let us first install the latest version of Ansible.

Assume that you have installed the Centos OS , lets follow the steps mentioned below. I am using root to install the Ansible.

Deploy Ansible  now.

Update the system

[root@ansibletower ~]# yum update -y
Loaded plugins: fastestmirror
…..

Install the extra EPEL repositories from dl.fedoraproject.org

[root@ansibletower ~]# cd /tmp/
[root@ansibletower tmp]# wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
–2020-04-28 11:47:01– https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
Resolving dl.fedoraproject.org (dl.fedoraproject.org)… 209.132.181.24, 209.132.181.23, 209.132.181.25

Install epel-release-7-11.noarch.rpm,

[root@ansibletower tmp]# ls
epel-release-latest-7.noarch.rpm yum.log
ks-script-MGvkwW yum_save_tx.2020-04-27.11-57.IFljf8.yumtx

[root@ansibletower tmp]# yum install epel-release-latest-7.noarch.rpm
Loaded plugins: fastestmirror
Examining epel-release-latest-7.noarch.rpm: epel-release-7-12.noarch

……..

[root@ansibletower ~]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.excellmedia.net
* epel: mirror.poliwangi.ac.id
* extras: centos.excellmedia.net
* updates: centos.excellmedia.net
repo id repo name status
base/7/x86_64 CentOS-7 – Base 10,070
epel/x86_64 Extra Packages for Enterprise Linux 7 – x86_64 13,243
extras/7/x86_64 CentOS-7 – Extras 342
updates/7/x86_64 CentOS-7 – Updates 159
repolist: 23,814

Install Ansible

[root@ansibletower tmp]# yum install ansible -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.excellmedia.net

Verify Ansible

[root@ansibletower tmp]# ansible –version
ansible 2.9.7
config file = /etc/ansible/ansible.cfg

[root@ansibletower tmp]# python –version
Python 2.7.5

[root@ansibletower ansible]# pwd
/etc/ansible
[root@ansibletower ansible]# ls
ansible.cfg hosts roles

Password less authentication

Create same user (ranjeet) across all managed servers and configure

Provide root privilege to all users.

Ensure PasswordAuthentication Yes in all servers under /etc/ssh/sshd_config file

Generate ssh-keys using ssh-keygen command from user (ranjeet)

Copy the ssh keys using ssh-copy-id command

Update the inventory file by adding managed nodes ip address

Test the connection, you must get pong response.

[root@ansibletower ansible]# ansible -m ping all
192.168.0.31 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}
 

[root@ansibletower ansible]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg
├── hosts
└── roles

1 directory, 2 files

By default inventory file location is /etc/ansible, this can be configured in ansible.cfg configuration file. You can keep the inventory file at any location.

[root@ansibletower ansible]# cat /etc/ansible/ansible.cfg | head -20

# some basic default values…

#inventory = /etc/ansible/hosts
#library = /usr/share/my_modules/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5
[root@ansibletower ansible]#

Organize Inventory file

Create Server groups strategically

[OPENSTACK]

192.168.0.31

192.168.0.31

[STORAGE]

10.255.8.1

10.255.8.2

Disabling ANSIBLE_HOST_KEY_CHECKING

For temporary, use command line

[root@ansibletower ansible]# export ANSIBLE_HOST_KEY_CHECKING=False

For permanent un comment

# uncomment this to disable SSH key host checking
#host_key_checking = False

How ansible.cfg configuration works with different location and priority

ANSIBLE_CONFIG environment variable
./ansible.cfg from the current directory
~/. file present under home directory
/etc/ansible/ansible.cfg the default location

Working With Managed Nodes

There are 2 ways to work with managed nodes
Ad-hoc commands
Playbook

Adhoc Command example

ansible [-i inventory-file] servername:servergroup1:servergroup2 -m module  [-a argument_value] -b

-m module , example ping , to list module use command

-b  become root , execute as root

-a is argument (passing values)

[root@ansibletower ansible]# ansible-doc -l

[root@ansibletower ansible]# ansible-doc -l | grep shel
shell Execute shell commands on tar…
vmware_vm_shell Run commands in a VMware gues…
win_shell Execute shell commands on tar

[root@ansibletower ansible]# ansible-doc shell
> SHELL (/usr/lib/python2.7/site-packages/ansible/modules/commands/shell.py)

The `shell’ module takes the command name followed by a list of
space-delimited arguments. Either a free form command or `cmd’
parameter is required, see the examples. It is almost exactly like
the [command] module but runs the command through a shell
(`/bin/sh’) on the remote node. For Windows targets, use the
[win_shell] module instead.

* This module is maintained by The Ansible Core Team
* note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):

– chdir
Change into this directory before running the command.
[Default: (null)]
type: path
version_added: 0.6

– cmd
The command to run followed by optional arguments.
[Default: (null)]
type: str

Copying a file from Ansible engine to Managed nodes

[root@ansibletower ansible]# ansible all -m copy -a “src=/etc/ansible/hosts dest=/tmp”
192.168.0.31 | CHANGED => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: true,
“checksum”: “54cd800cd3f814544326aeea23d3090142a6519c”,
“dest”: “/tmp/hosts”,
“gid”: 0,
“group”: “root”,
“md5sum”: “372c791ab2c741e8ec6c224379b9b343”,
“mode”: “0644”,
“owner”: “root”,
“secontext”: “unconfined_u:object_r:admin_home_t:s0”,
“size”: 1040,
“src”: “/root/.ansible/tmp/ansible-tmp-1588076431.29-24073-102578663046654/source”,
“state”: “file”,
“uid”: 0
}

Note: Ansible will not repeat copying the same file/rerunning  unless its sees any change.

Create a file with contents on the managed node

ansible all -m copy -a “content=’Please logon to www.ranjeetbadhe.com’ dest=/tmp/website.txt”

ansible all -m copy -a “content=’Please logon to www.ranjeetbadhe.com\n’ dest=/tmp/website.txt”

\n = new line for the managed node.

[root@ansibletower ansible]# ansible all -m copy -a “content=’Please logon to www.ranjeetbadhe.com’ dest=/tmp/website.txt”
192.168.0.31 | CHANGED => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: true,
“checksum”: “cfbb1b212b97228c134d00b9537364834e0f48d9”,
“dest”: “/tmp/website.txt”,
“gid”: 0,
“group”: “root”,
“md5sum”: “7adc62cd32ad8b5fd8737cf82e918fcc”,
“mode”: “0644”,
“owner”: “root”,
“secontext”: “unconfined_u:object_r:admin_home_t:s0”,
“size”: 36,
“src”: “/root/.ansible/tmp/ansible-tmp-1588080812.79-24154-141921069261814/source”,
“state”: “file”,
“uid”: 0
}

Copy from Manged node to Engine , using Fetch Module

ansible all -m fetch -a “src=/tmp.website.txt dest=/tmp/location”

Creating file/directories on managed nodes

ansible all -m file -a “path=/tmp/namo.txt state=touch”

ansible all -m file -a “path=/tmp/namo.txt state=touch”  -b

-b provides  privilege to execute as a root user

Working With Ansible Variables

Variables are used to store the values

Variables should always start with a number.

Types of variables

Default variables
Inventory variables (Host variables and group variables)
Facts and local facts
Registered variables

To display local groups on Ansible Engine

[ranjeet@ansibletower ~]$ ansible localhost -m debug -a “var=groups”
localhost | SUCCESS => {
“groups”: {
“all”: [
“192.168.0.31”
],
“client”: [
“192.168.0.31”
],
“ungrouped”: []
}
}

Debug Module

Debug module  is used to display messages or the values of ansible variables

ansible all -m debug <var/msg> module.

Message module will message only on Ansible engine. DEBUG module will not execute on remote nodes.

[ranjeet@ansibletower ~]$ ansible all -m debug -a “msg=’Namaste all, this is Ranjeet Badhes blog'”
192.168.0.31 | SUCCESS => {
“msg”: “Namaste all, this is Ranjeet Badhes blog”

[ranjeet@ansibletower ~]$ ansible all -m debug -a “var=’inventory_hostname'”
192.168.0.31 | SUCCESS => {
“inventory_hostname”: “192.168.0.31”
}

[ranjeet@ansibletower ~]$ ansible all -m debug -a “msg={{inventory_hostname}}”
192.168.0.31 | SUCCESS => {
“msg”: “192.168.0.31”
}

Variables in Host file

192.168.0.30  ansible_ssh_user=namo ansible_ssh_pass=Nottingham@1234

[clients]

192.168.0.31
192.168.0.32
192.168.0.33

[openstack]
192.168.0.34
192.18.0.35

[openstack:vars]
ansible_ssh_user=namo
ansible_ssh_pass=Nottingham@1234

 Ansible Facts
Facts are the information derived through ssh session with remote systems /managed nodes like 
distribution ,release,processor,python,storage and network configuration etc.
Task of collecting this information from the remote system is called gathering facts and
gathered information/collected is called facts.
We can gather/collect facts using setup module in adhoc commands
Playbook by default will use the setup module.

There are 2 types of facts
custom facts
default facts

[ranjeet@ansibletower ~]$ ansible all -m setup

192.168.0.31 | SUCCESS => {
 "ansible_facts": {
 "ansible_all_ipv4_addresses": [
 "192.168.0.31"
 ],
 "ansible_all_ipv6_addresses": [
 "fe80::3156:b9cb:bee1:d082",
 "fe80::bec1:6e14:11eb:708c"
 ],
 "ansible_apparmor": {
 "status": "disabled"
 },
 "ansible_architecture": "x86_64",
 "ansible_bios_date": "12/01/2006",
 "ansible_bios_version": "VirtualBox",
 "ansible_cmdline": {
 "BOOT_IMAGE": "/vmlinuz-3.10.0-1062.18.1.el7.x86_64",
 "LANG": "en_US.UTF-8",
 "crashkernel": "auto",

Filtering from the facts

[ranjeet@ansibletower ~]$ ansible all -m setup -a "filter=ansible_mounts"
192.168.0.31 | SUCCESS => {
 "ansible_facts": {
 "ansible_mounts": [
 {
 "block_available": 213257,
 "block_size": 4096,
 "block_total": 259584,
[ranjeet@ansibletower ~]$ ansible all -m setup -a "filter=ansible_architecture"
192.168.0.31 | SUCCESS => {
 "ansible_facts": {
 "ansible_architecture": "x86_64",
 "discovered_interpreter_python": "/usr/bin/python"
 },
 "changed": false
}

Creating custom facts, Lets follow the follow step.

1. Create /etc/ansible/facts.d on all managed  nodes. This has to be created manually as
ansible folder/path is not present.
2. Inside the fact.d folder create files with .file extension
3. The output of the fact file must be json
4. The fact file should have execute permissions.

Use the command to create a folder structure on all the managed nodes 

ansible all -m file -a "path=/etc/ansible/facts.d state=directory" -b 
[ranjeet@ansibletower ~]$ ansible all -m file -a "path=/etc/ansible/facts.d state=directory" -b
192.168.0.31 | CHANGED => {
 "ansible_facts": {
 "discovered_interpreter_python": "/usr/bin/python"
 },
 "changed": true,
 "gid": 0,
 "group": "root",
 "mode": "0755",
 "owner": "root",
 "path": "/etc/ansible/facts.d",
 "secontext": "unconfined_u:object_r:etc_t:s0",
 "size": 6,
 "state": "directory",
 "uid": 0
}


Using Loops


– hosts: all
become: yes
gather_facts: true
name: Install multiple applications using loop

tasks:
– yum:
name: “{{item}}”
state: present

loop:
– mariadb
– nginx
– net-tools
– httpd


			

One thought on “Working With Ansible

Leave a Reply

Your email address will not be published. Required fields are marked *