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