Featured post

Quiz: Data PreProcessing

Wednesday, 12 June 2019

Ansible - 1


Chapter 1

Introduction


1.1  About Ansible


Ability to give instructions to hundreds of servers.
Perform four different functions which are not standalone.
·       Change Management
·       Provisioning
·       Automation
·       Orchestration


1.2  Change Management




1.3  Provisioning


·       transition from one system state to another system state that's expected and this is generally used in building servers.
·       It’s actually installing and configuring the software each time rather than just copying the image which is not a clean method.
e.g: On a server having basic operating system, we want to make it a Web server. Below are the automated steps.
1> Installation
2> Copy configuration
3> Copy web files or some testing codes
4> Install security updates
5> Start the service

1.4  Automation


·       Automation is the most basic part of Ansible
·       Can update files, change network devices, update the system
E.g:
There is urgent requirement to update a security file on 500 servers ASAP.
Just update the playbook and it will be pushed automatically. If there is any issue with a particular server, remove it from load balancer and investigate the cause.




1.5  Orchestration


·       It’s different from automation. Automation used on a single system whereas orchestration takes the automation and coordinates the process between multiple systems.
·       Cannot have orchestration without automation.




1.6  Why Use Ansible


·       Agentless
·       Very less dependencies -. More stable, very fast to implement
·       No database requirement make it portable. Can move from system to system.
·       No need of DBA to manage performance, indexes or backups, or dealing with software upgrades when you're trying to upgrade or update it.
·       Its clean – after playbooks finishes it tasks, modules and software that was running on it is now gone after it completes its task.
·       Upgrade is easy as there is no other systems dependencies. No schema updates on a database server or deployment of agent upgrades.

1.7  YAML


·       It’s not Yet Another Markup Language
·       A Markup language is where you define the kind of text or the data that you're entering.
·       it's more of the structure of the formatting of the text than anything else.


1.8  Built-in Security


·       Primary Mode of communication – SSH
·       So, no need to waste time over setup and security issues
·       Understands using root and on those systems that can’t use roots. E,g: Ubuntu
·       Ubuntu – uses built in sudo to run its plays.
·       Ansible Vault: encrypt passwds and other confidential information while still allowing Ansible to use it
·       No need to maintain PKI (Passwd Key Infra) as it uses SSH.














Chapter 2

Architecture and Process Flow





2.1 System Requirement


  The process starts by having an Ansible control server talking to a remote system(client).


Control Server:
Ansible is installed here.
Deploys all plays and playbooks.




Minimum Requirement:
1>   Ansible is python based. Python 2.6 or higher is required.
2>   Operating System – Unix or Linux type of environment.
3>   SSH should be running.
Note: Python 3.x is not supported but don’t uninstall it.





2.2 Components Overview


Five basic components of Ansible's processing:
1>   Inventory ( can be considered Ansible hosts file )
-        A text file that describes the servers and systems
-        Need to define host-level variables, groups and roles here.
-        User account details for each systems can be defined here
-        This file can be static text file or an executable script to get the managed systems, so no need of a database for Ansible.

2>   Modules
-        Command center of the system
-        Each modules contain set of actions that can be performed.
-        Core Modules – Ansible developers will fully support them
-        Extra Modules – comes from community Ansible-Galaxy

3>   Playbook
-        Collection of plays
-        can install an application, copy over a configuration file and then switch over to your database servers and configure the databases in that order
 e.g: Yum module can run on Redhat but can’t be run on Debian. For Debian apt module need to be used. We can add logic in Playbook to select the module accordingly.

4>   Configuration File
-        sets up the global configuration variables for Ansible, and allows to change its defaults
-        how many parallel operations can your system perform at the same time, or whether you want Ansible to tell you if a host was skipped or not - these items can be configured here

5>   Python
-        Ansible takes all of those components and kind of pushes it through the Python component to build a package to be delivered to the remote systemsb
-        Python framework also helps in building variables
-        Three kind of variables
-        Host Variables: define in the inventory file where host is defined and is specific to this host only
-        Fact Variables: environment data of the host
-        Dynamic Variables: created during the course of playbook and destroyed after that.


2.3 Process of Execution and Flow


The process that Ansible takes in order to talk to remote server.
Evaluate the playbook ->
Playbook identifies the systems to deploy to, and the modules to grab ->
Playbook packages everything up into a neat little Python package ->
Identifies the systems to deploy to using the inventory module ->
Establish an SSH session to the remote system->
Deploy the package according to the Ansible configuration parameters in /tmp directory on remote system->
Python framework on the remote system will then execute this package ->
PF will identify which steps completed successfully ->
Remote system will return the results back to Ansible using JSON->
And before the SSH connection is terminated, the package will be deleted.
Note: Ansible can be used to target multiple machines at the exact same time



2.4 Execution Types


Two types:
1>   Default : Remote execution
2>   Local execution:
the local Ansible server is actually executing the package, not the remote system that is targeted as it can't receive a Python module. Will discuss this later in detail.












Chapter 3

Setting up Environment



3.1 Installing Ansible


Installation:
Download file from below link:
https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
#yum install ./epel-release-latest-7.noarch.rpm
Below command will update all the packages. It is required before we go and install ansible.
#yum update
#yum install ansible



3.2 Start Using Ansible


# mkdir /exercise1
# cat inventory
192.168.56.102

# ansible 192.168.56.102 -i inventory -u root -m ping -k
SSH password:
192.168.56.102 | FAILED! => {
    "failed": true,
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}

The issue is because from this system we never did ssh to 192.168.56.102 system. So, the entry in known_hosts file is not there. We need to create it first.

# ssh root@192.168.56.102
The authenticity of host '192.168.56.102 (192.168.56.102)' can't be established.
ECDSA key fingerprint is d3:8b:10:b5:ef:a2:c1:30:de:e5:b1:69:4a:12:52:db.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.102' (ECDSA) to the list of known hosts.
root@192.168.56.102's password:

We can see the file and entry inside it.
# cd /root/.ssh
# ls
known_hosts

# more known_hosts
192.168.56.102 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyN
TYAAABBBD8bNX2TllC8n1lYbjTPuIOHJtlOaic6+rZmvjNHMwEOXcPqElAJzWkw/79Gu7bnpGVPYV98T
Sk1Y//BUxwK338=

Now go back to /exercise and run the ping command again.

# cd exercise1/
# ansible 192.168.56.102 -i inventory -u root -m ping -k
SSH password:
192.168.56.102 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

# ssh root@192.168.56.103
#ansible all -i inventory -u root -m ping -k



For Debugging:
# ansible 192.168.56.102 -i inventory -u root -m ping -k -vvv


Run command
# ansible 192.168.56.102 -i inventory -u root -m command -a "yum list installed" -k

No need to mention module command, command is the default  module.
# ansible 192.168.56.102 -i inventory -u root -a "yum list installed" -k


Difference between Command Module and Shell Module both run shell commands.

Command Module: Run executable inside python.


Shell Module: Run executables inside shell. It allows to use SHELL variables. E.g: $HOME, $PATH, etc

































Chapter 4

Inventory and Configuration



Inventory Fundamentals


·       Can be present anywhere on the server, path need to be specified properly.







Behavioral Parameters: Configuration can be applied to a system or group of systems.


Groups: We can group our systems together. E.g: Test servers, prod servers


Groups of Groups: E.g: East data centre, West data centre.


Assign Variables: E.g: Create variable called  ntp server and attach to a group.


Scaling out using multiple files: Use multiple files to scale up inventory file.


Static/Dynamic: Can create inventory file dynamically and ansible can use this file.













Sample  File:




Inventory Basics



# cat inventory
ansible2 ansible_ssh_host=192.168.56.102 ansible_ssh_user=root ansible_ssh_pass=creative

# ansible ansible2 -i inventory -m ping


Now create group:

# cat inventory
ansible2 ansible_ssh_host=192.168.56.102 ansible_ssh_user=root ansible_ssh_pass=creative
ansible3 ansible_ssh_host=192.168.56.103 ansible_ssh_user=root ansible_ssh_pass=creative

[testservers]
ansible2
ansible3

# ansible testservers -i inventory -m ping

Now  create group of groups

# cat inventory
ansible2 ansible_ssh_host=192.168.56.102 ansible_ssh_user=root ansible_ssh_pass=creative
ansible3 ansible_ssh_host=192.168.56.103 ansible_ssh_user=root ansible_ssh_pass=creative

[testservers]
ansible2

[devserver]
ansible3

[datacenter:children]
testservers
devserver

# ansible datacenter -i inventory -m ping


Now create a parameter group

# cat inventory
ansible2 ansible_ssh_host=192.168.56.102
ansible3 ansible_ssh_host=192.168.56.103

[testservers]
ansible2
[devserver]
ansible3

[datacenter:children]
testservers
devserver

[datacenter:vars]
ansible_ssh_user=root
ansible_ssh_pass=creative

# ansible datacenter -i inventory -m ping







Creating Prod and  Dev Env:

# pwd
/exercise1/production
# ls -ltr
drwxr-xr-x. 2 root root   6 Apr 24 08:27 host_vars
-rw-r--r--. 1 root root 241 Apr 24 08:35 inventory_prod
drwxr-xr-x. 2 root root  33 Apr 24 08:37 group_vars

# cat group_vars/all
---

# This is all file
username: all_username

# ansible testservers -i inventory_prod -m user -a "name={{username}} password=12345"
ansible2 | SUCCESS => {
    "changed": true,
    "comment": "",
    "createhome": true,
    "group": 1000,
    "home": "/home/all_username",
    "name": "all_username",
    "password": "NOT_LOGGING_PASSWORD",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 1000
}


#  cat group_vars/testservers
---
# comments here
username: group_user


# ansible testservers -i inventory_prod -m user -a "name={{username}} password=12345"
ansible2 | SUCCESS => {
    "changed": true,
    "comment": "",
    "createhome": true,
    "group": 1001,
    "home": "/home/group_user",
    "name": "group_user",
    "password": "NOT_LOGGING_PASSWORD",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 1001
}

Note: Group variable take precedence on all user.



# cat host_vars/ansible2
---
#comments here
username: ansible3

# ansible testservers -i inventory_prod -m user -a "name={{username}} password=12345"
ansible2 | SUCCESS => {
    "changed": true,
    "comment": "",
    "createhome": true,
    "group": 1002,
    "home": "/home/ansible3",
    "name": "ansible3",
    "password": "NOT_LOGGING_PASSWORD",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 1002
}

















Ansible Config






·       Defines how ansible works.
·       Can change how many parallel connection Ansible can make
·       Can handle unknown ssh keys



Configuration Settings: Order-of-Operations

As multiple teams use Ansible in same Env, so there is order of operations rule to load configuration.


1.     $ANSIBLE_CONFIG: First thing - Env Variable, if variable exists Ansible load the files it points to first.

2.     ./ansible.cfg :  Second place, in the current directory. This is commonly used when you're sharing plays and playbooks between multiple members or your team using, let's say, a version repository like Git. If they're running Ansible on their local machines and using Git to synchronize all their data, you can add the configuration file with that playbook, and the configuration will move with it.

3.     ~/.ansible.cfg : Home directory of currently logged in account. This place is best used when you're using a shared system and you want to run your Ansible plays, but you want to configure it for each user specification.

4.     /etc/ansible/ansible.cfg: Global configuration file.This file can be created only if we use “pip” or package manager to install ansible. If you installed Ansible and building by source, this file won't exist, but you can still put it in there.

Environment Variables Overrides:

$ANSIBLE_<configsetting>
Overrides specific settings by prefixing ANSIBLE_ to the name

#export ANSIBLE_FORKS=10
Great way to override specific settings on-the fly.


Now we try to disable the host key checking. For that first delete the ssh key footprint from known_hosts file.
# cat ansible.cfg
[defaults]
host_key_checking=True


# ansible ansible2 -i inventory_prod -m ping
ansible2 | FAILED! => {
    "failed": true,
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}


Now make the host_key_checking=False

# ansible ansible2 -i inventory_prod -m ping
ansible2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

As we know that environment variable is having highest precedence, we try to override the variable host_key_checking.


#export ANSIBLE_HOST_KEY_CHECKING=True
#echo $ANSIBLE_HOST_KEY_CHECKING

Delete the ssh footprint
#vi /root/.ssh/known_hosts
# ansible ansible2 -i inventory_prod -m ping
ansible2 | FAILED! => {
    "failed": true,
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}




Working with Python3 based system


#which python
/usr/bin/python
# whereis python
python: /usr/bin/python /usr/bin/python2.7 /usr/lib/python2.7 /usr/lib64/python2.7 /etc/python /usr/include/python2.7 /usr/share/man/man1/python.1.gz

Since, here we are having python 2.7 so our commands will not fail, but if we use python3 then ansible commands will fail.
In case if python3 is installed, no need to uninstall it and then install 2.7. Just run the python2.7 executable or use the below env parameter.
ansible_python_interpreter=/usr/bin/python2.7












Chapter 5

Ansible Module



Fundamentals


·       Are used inside your plays, playbooks, or adhoc commands
·       Provide the necessary steps for Ansible to follow in order to accomplish something
·       Its like a command center, it holds all the possibilities in a single repository for you to pick and use whenever you need it



Types:
1>   Core
2>   Extra
3>   Deprecated

To list and check module present
#ansible-doc -l
#ansible-doc <name>
#ansible-doc cloudtrail
#ansible-doc -s cloudtrail



Copy Module


·       Copies a file from local box to remote system
·       Has “backup” capability
·       Can do validation remotely


Fetch Module



·       Pulls a file from remote host to local system
·       Can use md5 checksums to validate


Yum Module


·       Manages installed applications on Redhat-based systems
·       Can install, update or delete packages
·       Can update entire system

Service Module


·       Can stop, start or restart services
·       Can enable services to start on boot





















Chapter 6

Hands-on Modules



Yum Module


#cat /exercise/inventory
ansible2 ansible_ssh_host=192.168.56.102
ansible3 ansible_ssh_host=192.168.56.103

[testservers]
ansible2
[devserver]
ansible3

[datacenter:children]
testservers
devserver

[datacenter:vars]
ansible_ssh_user=root
ansible_ssh_pass=creative

#ansible-doc yum
=name
-state

Below Command will take around 5 mins to complete.
# ansible testservers -i inventory -m yum -a "name=httpd state=present"
ansible2 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [ Output Truncated.

Run the command again, changed value will be “false”.
# ansible testservers -i inventory -m yum -a "name=httpd state=present"
ansible2 | SUCCESS => {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "httpd-2.4.6-45.el7.centos.4.x86_64 providing httpd is already installed"
    ]
}



Service Module


First we check the man page
#ansible-doc service
- enabled
        Whether the service should start on boot. *At least one of
        state and enabled are required.*
        (Choices: yes, no)[Default: (null)]
= name
        Name of the service.
- state
        `started'/`stopped' are idempotent actions that will not run
        commands unless necessary.


Now run the command on ansible server to start the service on client.

# ansible testservers -i inventory -m service -a "name=httpd state=started"
ansible2 | SUCCESS => {
    "changed": true,
    "name": "httpd",
    "state": "started",
    "status": {





My-Sql Server



# ansible devserver -i inventory -m yum -a "name=mariadb-server state=present"
ansible3 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [ Output Truncated


Now start the service:
# ansible devserver -i inventory -m service -a "name=mariadb state=started"
ansible3 | SUCCESS => {
    "changed": true,
    "name": "mariadb",
    "state": "started",
    "status": {




Firewalld Service


If you try to open 192.168.56.102 to open in browser, it will not open. As firewalld is blocking it.
Stop this service on both clients

# ansible testservers:devserver -i inventory -m service -a "name=firewalld state=stopped"
ansible2 | SUCCESS => {
    "changed": true,
    "name": "firewalld",
    "state": "stopped",
    "status": {

ansible3 | SUCCESS => {
    "changed": true,
    "name": "firewalld",
    "state": "stopped",
    "status": {

Now open again in browser ( http://192.168.56.102)
We used here testservers:devserver, will see in next session what is it.



Host/Group Target Patterns








Setup Module


·       Gather facts on remote systems
·       Used in playbooks


# ansible testservers -i inventory -m setup
ansible2 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.2.15",
            "192.168.56.102"
"ansible_architecture": "x86_64",
        "ansible_bios_date": "12/01/2006",
        "ansible_bios_version": "VirtualBox",


Use Filter for refined output
# ansible testservers -i inventory -m setup -a  "filter=ansible_enp*"
ansible2 | SUCCESS => {
    "ansible_facts": {
        "ansible_enp0s3": {
            "active": true,
            "device": "enp0s3",
            "features": {
                "busy_poll": "off [fixed]",
                "fcoe_mtu": "off [fixed]",
                "generic_receive_offload": "on",
                "generic_segmentation_offload": "on"
"ipv4": {
                "address": "10.0.2.15",
                "broadcast": "10.0.2.255",
                "netmask": "255.255.255.0",
                "network": "10.0.2.0"


Another example:
# ansible testservers -i inventory -m setup -a  "filter=ansible_mounts"
ansible2 | SUCCESS => {
    "ansible_facts": {
        "ansible_mounts": [
            {
                "device": "/dev/mapper/cl-root",
                "fstype": "xfs",
                "mount": "/",
                "options": "rw,seclabel,relatime,attr2,inode64,noquota",
                "size_available": 7227125760,
                "size_total": 8466202624,
                "uuid": "0fd71a9e-2428-4083-b883-763de03e754b"
            },
            {
                "device": "/dev/sda1",
                "fstype": "xfs",
                "mount": "/boot",
                "options": "rw,seclabel,relatime,attr2,inode64,noquota",
                "size_available": 872513536,
                "size_total": 1063256064,
                "uuid": "eae9c880-0bc0-4713-bb1d-d8e71ac6dfd9"
            }
        ]
    },
    "changed": false
}




Collect All data from the servers:
Below command will create a directory setup and inside it create file for each server having full system data.

# ansible all -i inventory -m setup --tree ./setup
#ls  -ltr setup
-rw-r--r--. 1 root root 14505 Apr 26 11:14 ansible2
-rw-r--r--. 1 root root 14401 Apr 26 11:14 ansible3

#cd setup
#cat ansible2
{"ansible_facts": {"ansible_all_ipv4_addresses": ["10.0.2.15", "192.168.56.102"], "ansib
le_all_ipv6_addresses": ["fe80::a00:27ff:fe5a:6ca7", "fe80::23b2:78dc:3be8:9a10", "fe80:
:1baa:9868:f581:9efa", "fe80::4304:30b4:68df:8672"], "ansible_architectur
Output Truncated
















No comments:

Post a Comment