Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

How to Work With Ansible?

How to Work With Ansible?

The Ansible tutorials will cover the following topics.

  • What is Ansible?
  • How to install Ansible?
  • The Ansible architecture
  • Configuration of Ansible
  • How to work with Playbook in Ansible?
  • How to work with Inventory Files in Ansible?
  • How to work with modules in Ansible?
  • How to develop test and release a playbook?
  • How to take Ansible to Production?
  • How to handle Errors in Ansible?
  • How to Rollback in Ansible?
  • How to work with Reporting in Ansible?
  • How to create a custom module in Ansible?
  • How to create provisioning for Docker?
  • How to deploy Ansible in large organization?
  • What is Ansible tower?

What is Ansible?

Ansible is a very simple IT automation engine that automate provisioning ,configuration, application deployment, intra service orchestration whose aim is to provide enlarge productivity. It is written in Python and can be installed as Linux machine only.

Ansible is the infrastructure automation tool. It can set up several built agents in continuous integration(CI) system. Using ansible building or rebuilding infrastructure is easy, fast and error free. All setup can be done by just one click. Ansible provides a fuel towards devops journey.The primary aim of configuration management is to provide  machines to a denied state as fast as possible.

Other infrastructure automation tools are-

  • Chef
  • Puppet
  • Satt
  • etc

Infrastructure testing tools are: –

  • Serverspce
  • Test kitchen
  • etc.

Provisioning tools are: –

    • Docker
    • Lxca
    • Vagrant
    • etc

Deployment tools are:-

  • Thoughtworks Go
  • Atlassion bamboo
  • Jenkins
  • etc

Orchestration tools are

  • Mcollective
  • Satt
  • Serf
  • Chef

Monitoring tools are:-

  • Nagi OS
  • Ganglia
  • Zenoss
  • Graphite
  • Sensu
  • Riemann

Logging tools are:-

  • Logstash-kibana
  • Sumologic
  • Psyslog

Ansible needs to be installed on a single machine which will manage your whole infrastructure.For remaining clients machine either we need their hostname or IP address.

Push and pull based mechanism

There are two mechanisms available.Pull based mechanism and push based mechanism.

Pull based

In pull based mechanism,client will contact the server and check if any config applicable for the machine.If any, server will provide the client with the configuration or other details.

Puppet and chef follow pull based mechanism.Agent on the server periodically checks for the configuration information from central server.

Push based

In push based mechanism, server will push the applicable config/or other details to client if applicable without the agent.

Ansible follows push based mechanism.Central server pushes the configuration information on target client.

Normal/ pull based
ServerClient
Responsible for providing the serviceAccess the server
 Need some utility to access the server
Ansible/ push based
Ansible server config changes in serverNo need to install some utility to access the server
The Architecture of Ansible
Agent Based SystemAgentless  system
These kind of system needs an external agent along with the dependencies.No agent is required only a proper SSH daemon setup is required.
Agent based systems need to invoke the agent in order to run and pull the latest configuration .Either the agent runs as service or cron job.These system pushes the configuration remotely without the agent.
Parallel agents execution may slow down the server. Serverless execution can make the process faster.Parallel execution is faster as long as parallel execution count is lesser than SSH connection allowed count.
Agents installation and permissions are headache.Only SSH based remote connection is required.

Puppet needs agent on puppet server .Agent program needs some space and CPU prioritization.

Ansible by default runs on push mode but using ansible –pull, ansible provides an agent that can work as pull mode.To make default SSH connections faster, we can always enable control persist and pipeline mode.

Tools like chef, puppet are agent based and they by default work on pull mode. Using serverless chef and master less puppet we can scale up large machines.

Ansible architecture

Ansible tasks defined in the playbooks can execute sequentially by default. However, we can insert conditions and loops so that selective execution can happen.Ansible provides set of API s to run a script. Mostly when we create our own task set we call these APIs with the help of custom wrappers.All playbooks are written in YAML language. They are simple and declarative.Ansible can execute N threads in parallel.

Features of Ansible

  • Open source
  • Written on python so easy to read and extend(Built on top of python)
  • Easy installation and configuration
  • Highly scalable
  • Agent less client connection
  • SSM for secure connection
  • Simple English Language confirmation setup

Who uses Ansible

If we want to push one software or patch or want to install some packages. Manual installation is very tedious and time consuming.They are error prone too. To simplify the process we can use Ansible.These activities can be done very easily by ansible script/command/playbook.

Below are the guys who uses Ansible

  • System administrator
  • Data engineers
  • Devops Professionals
  • Developers
  • Testers
  • Database administrator
  • Network administrator

How to install Ansible?

Ansible software is available in EPEL repositories.Ansible does not come with normal unix or linux distribution.So we need to activate epel.In order to install Ansible, yum will try to contact internet and download the required software and other dependency files.

Prerequisites of Ansible

  • SSH client(Open SSH)
  • Python(PyYaml,jinja2)
  • Paramiko
  • Vagrant
  • Serverspce
  • PIP
  • Git
  • httplib2

Ansible system requirements for clients(node)

  • 2 GB RAM
  • 20 GB Hard disk
  • SSH(OpenSSH)
  • os-RHEL/CENTOS/UBUNTU/ORACLE LINUX/HAC/BSD/Solaris/Windows OS

Ansible system requirements for ansible server

  • LINUX(RHEL/CENTOS/ ORACLE LINUX)operating system.
  • 4GB RAM
  • 40 GB Hard disk space
  • SSH(open SSH)
  • Enabled EPEL repository for centos(6.8 or 7.2)
  • Internet Connection

Installing Ansible

If you have an existing infrastructure but need a server version of Ansible,we can install Ansible with “pip”.Pip tool managesthe packages of python along with library.The advantage of Pip is that all ansible releases are pushed automatically.Hence no more manual updation is required.

After Git installation
PATH=/home/vagrant/ansible/bin:/usr/local/bin:/ bin:/usr/bin:/usr/loal/sbin:/usr/sbin:/sbin:/home/vagrant/bin.
PYTHONPATH=/home/vagrant/ansible/lib
MANPATH=/home/vagrant/ansible/docs/man

Once we have installed ‘Easy_install’we can further install the remaining packages.

>sudo easy_install pip   // install pip.package

Then we need to install paramiko,PyYAML,jinja2 and httplib2

>Sudo pip install paramiko PyYAML,jinja2 and httplib2

This command will install all the other packages.

By default, ansible checks out development branch. Just in case we want some other branch we need to provide the following command-

>git branch  -a
//like
>git checkout release1.7.3

Example Once the checkout is finished and ansible switches to our denoted branch, we can cross verify the version using the following command

>ansible--version
Install Ansible from a RPM file-
>sudo rpm –uvh~/rpmbuild/ansible-*.noarch.rpm
Install via Apt

Ansible is available in ubuntu under personal package Archive(PPA)

>sudo apt-get install apt-add-repository
>sudo apt-add-repository ppa:rquillo/ansible
>sudo apt-get update
>sudo apt-get install.ansible
Installing via brew(Homebrew)
>brew update
>brew install ansible
Installing via pip(pythons package manager)
>sudo easy_install pip
>sudo pip install ansible

For installing multiple other package it is always better to install ‘easy_install’package.
Since Ansible can be installed in Linux flavour.Below are the modules to install and get the packages-

For Fedora,Red Hat enterprise Linux,CentOS and other compatible Linux distribution,all head to use the following command-

> yum install ansible

Yum is a package management .It resolves enterprise dependency for installing epel.

>yum install –y epel –release
>Yum install –y ansible //This will install ansible.

For Ubuntu,Debian and other compatible Linux distribution,We need to use the following command—

>apt --get install ansible

If using pip the following command need to be used-

>pip install ansible

Pip tool will resolve the other dependencies, Download the required packages and install.

If you want to install from source code then you need to use the following command

>git clone git://github. com/ansible/ansible.git 
>cd ansible/ 
>sudo make install/source ./hacking/env_setup

Ansible is originally put in github.All releases are posted to git regularly.
How to check if Ansible is installed properly?

>ansible --version

This command will provide you the version of Ansible If Ansible is installed successfully.

alternatively,

>rpm-qa|grep ansible
>ansible -version.el.noarch

This shows that ansible is installed correctly.

To get help in ansible
>ansible --help

Usage:

ansible [options]

Options:

-a MODULE_ARGS,--args= MODULE_ARGS

Module arguments

-i INVENTORY,--inventory_file=INVENTORY

Provide which inventory host file to pick (default=/etc/ansible/hosts)

-m MODULE_NAME,--module_name= MODULE_NAME

Name of the module to run(default=command)

How to check details of ansible package?

>rpm-ql ansible-version.el.noarch|more
/etc/ansible->main file
/etc/ansible/hosts->Clients ip and details
/etc/ansible/roles->all roles are defined
/user/bin/ansible->ansible commands
/user/bin/ansible-console->console command
/user/bin/galaxy-predefined templates
/user/bin/ansible-playbook->configure playbook
/user/bin/ansible-pull->enable pull mode
/user/bin/ansible-vault-> Ansible vault
[Python library]
---
---
[ansible modules]
---
---
[extras]
---
---

Now we need to create user who can access Ansible . By default, everything will be created as a root user.
How to check who is logged  in?

>whoami

this command will tell who is the user currently logged in.

How to create a new user for ansible?

>useradd ansuser/usedadd-d/home/ansadm-m 
>password ansuser
>new password
>Retype password     [ You need to done steps in all clients]
Password-x-1 ansuser(create a non expiry password)
The Ansible architecture

Once we have created an User for Ansible, we need to switch to new user.

How to switch to other user?

>su -ansuser

su-switch user is the command to switch user from one account to another account.

How to generate public and private key?

>su -ansuser
>ssh-keygen
>Enter passphase-No data (extra security)
//This will generate public and private key.
//We need to copy the public key to all the clients.
>ssh-copy-id-i id-rsa.pub [email protected]

Alternatively:

>su-ansuser
>ssh-keygen-t rsa
>cat rsa.pub

Copy the key.In client we have to follow the same step

>mkdir .ssh
>chmod700 .ssh
>chown ansuser:ansuser.ssh
>cd.ssh/
>vi authorized-keys

paste the key.

>chown ansuser:ansuser.authorized-keys
>chmod 600 authorized-keys

Can we avoid password while logging in to clients?

In case of SSH password less login we can avoid providing password while logging in to clients.In server we generate public and private key and send the public key to client.The client’s response is decrypted using the private key.

This is how the password less login happens between each of the client machine.

Components of Ansible

Program

  • ansible
  • ansible-doc
  • ansible-playbook
  • ansible-pull

Module

  • Perform configuration and system management.Like Copy,service,user,group,etc.

Ansible Architecture: Agentless configuration

Ansible follows a client server architecture where server is called the ansible control server. The server has to be a Linux system.The control server is written on python. The server machine is called controller machine and server is command line based.

Since ansible is config management automation tool, it neither does store huge files or server nor it places lesser files or clients.

Ansible clients are otherwise known as nodes(manage host or manage node).Clients can be on linux,Unix,(BSD,Solaris,HP-UX,MAC)or windows system. Client does not have any agent to receive the data from server.Clients gets connected over SSH with the command.

>SSH [email protected]

Server consists of inventory file, Host information (Client machine’s host and ip address). We can alter content by adding details inventory parameters in the server.

How to work with Playbook in Ansible?

A playbook is a collection of different tasks.(Even though via command line we can perform one task at a time.).Manual way of performing tasks are time consuming and tedious.They are error prone too. In case if we have to manage hundreds of machines,playbook comes handy.Playbook in ansible is written in YAML Language and ansible uses a standard YAML parser.Hence a playbook is a collection of tasks and placed in a .yaml file.

Playbook governs the task that needs to be executed so Playbook is the list of tasks (called plays). Plays are human readable YAML files. The output of YAML plays will be a JSON format.

Structure of a playbook

The playbook is a simple text file .The playbook should start with 3 hyphens(-)and optionally ends with 3 dots(…).

Playbook consists of –

  • Lists of remote hosts
  • User variables
  • Tasks
  • Handlers

Playbook tasks should for KISS principle (keep it simple stupid).It will be simple, easy to read and easy to maintain.

An ansible playbook is having one or more plays.Each play will have 4 sections.

  • Section-1-target section[Target section on says the host,mode,how the execution will happen and other SSH related settings.]
  • Section-2-variable section[Variable section talks about the variables that we will use while running.]
  • Section-3-task section[Task section is the actual tasks that needs to be performed.]
  • Section-4-(Optional)Handler section[Handler section talks about a section or set of code that needs to be run if a change happens.]

Each play consists in a list .as per YAML list each line must start with a dash(-).

Target section consists of the followings

  • host-Where the play will be fired.
  • user-The username that connects to the machine.
  • become- state of the current user
  • become_method- the method used as become
  • Sudo-set yes if ansible uses sudo to become root on client machine.
  • Sudo_user-The user via which ansible will connect the client machine and become using sudo.
  • Connection-This will tell ansible what transport to use to connect to the client machine.(ssh or paramiko)
  • gather-facts-Automatically run the setup module on remote machine and gather the facts.

Variable section

Variables make a playbook more versatile and allow not being hard coded.Variables and data are easily modified.Variables defined in playbook however can be overridden by global variable or inventory variables.Variables defined in variable section are called vars.

Like

vars:
packages:httpd

Variables can also be loaded from external YAML files by providing ansible a set of list of variables to load.To load external yaml variable file we need to use vars – files directive.

var_files:
/conf/india.yml
/conf/china.yml
/conf/bangladesh.yml

Now each yaml file will look like the below-

india.yml
- - -
Web:'webserver.techtravelhub.com'
TZ:'Kolkata/India'

We can further make the session more interactive (not suitable for automation through)

vars-prompt:
-name:'https-paraphrases'
 prompt:'key passphrase'
 private:yes

Here the pass phrase becomes private and not printed to the screen.

To use the variable we can use three below written formats.

  1. {{variableName}}
  2. ${variableName}
  3. $ variableName

Ansible supports complex variable structures like dictionaries in playbook.

Like 
{{variableName.key}}
Example-{{ansible_etho.ip4.address}}

Scope of the variables

Variables that are defined in variable section applicable to that play only.Variables are not shared among plays.

Task section

Task section consists of actual tasks that the play needs to perform.

 tasks:
  -name:install httpd
   yum:
     name:httpd
     state:installed

This can be written as

  tasks:
  -name:install httpd
   action :yum name =httpd state installed

For tasks names are not required .They are optional property but for better documentation, it is good to have name of each task.Name of tasks also become handy when we try to incorporate handlers, Names will show in console that depicts what task is being done.

Note:

Ansible does not provide a fully featured dependency system.however ansible guarantees that all our changes will be executed in order they are written in playbook.If any module depends on another module so we need to write the code in playbook and place before our target module.

Handlers

The handlers are similar to task structure and support the same format for calling modules.However the only difference is that the tasks execute by default but handlers are executed once they are called .Even if the handlers are called multiple times ,unless there is a change handlers run only once.

The most frequent use of handlers is to restart the machine after a development or restart the daemons after they are upgraded and configured.

- - -
  -hosts:db
    tasks:
      -name:upgrade the DHCP
        action:yum name=dhcp state=latest
        notify:restart dhcp
      -name:configure file copy
        copy:
        src:dhcp/dhcpd.conf
        dest:/etc/dhcp/dhcpd.conf
        notify:restart dhcp
      -name:start dhcp
        action:servicename=dhcpd state=started enabled=yes
     handlers:
      -name:restart dhcp
       action:service name= dhcp state=restarted

We can include multiple handlers in a playbook .They may be attached to different tasks.

How to work with Ansible modules?

Refer Ansible modules to get more in depth information about Ansible modules.Ansible modules takes argument as key value pair (key=value)to perform a task in the remote machine.The response comes in JSON format.

Ansible modules do not do any changes if they are not required.This makes ansible very fast in execution It will simply say skipped about the command,otherwise it will say success.

How to get help about a module?

Ansible provides a command called ansible-doc which is the help file about the module we want to inspect.

To get a list of all modules along with a short description of each module.

>ansible-doc-l

To see help file for a particular module

>ansible-doc modulename/file

Setup Module:

One of the important module of Ansible is setup module.Setup module connects to the clients and gathers data about the system and then returns those values.
To run any ansible module,we need to pass two/three parameters-

  • Host Pattern -> Host pattern to match the machine.(client)
  • Module name -> Which module we want to use.

Host pattern supports group name, a machine name,a glob,a tilde(~) with regular expression. We can select all or * to select all machines.

>ansible-u root -k -m setup
>ansible-m setup
FieldExampleDetails
ansible_architecturex86_64The client machine’s architecture
ansible_distributionREHLThe client machine’s Linux or Unix distribution.
ansible_distribution_version8.0The client machine’s Linux or Unix distribution version.
ansible_domaintechtravelhub.comThe domain name part of server’s hostname.
ansible_fqdnwebserver.techtravelhub.comfully qualified domain name of the client machine.
ansible_interfaces[“lo”,”etho”]A list of all the interfaces including loopback interfaces of the client machine.
ansible_kernal2.9.32_842.el6.X86_64The kernel version of the client machine.
ansible_memtotal_mb10000The total memory in MB available in client machine.
ansible_processor_count2The client machines CPU available.
ansible_virtualization_roleguestif the client machine is a guest or a host machine.
ansible_virtualization_typekvmThe client machines virtualization setup.

If you have installed tractor or Ohai installed on the client machine,the servers Python automatically fetch these information.

Command module

Command module allows us to write and execute any arbitrary command on the managed machine.

The arbitrary command can be

  • Pre Provided installer.
  • Self written custom script.
  • rebooting of machine.

Command module does not run the command within shell, so redirection is not possible (Like pipe,expand shell,background command).

How to work with modules in Ansible?

Ansible modules

>ansible-doc-l|more
>ansible-doc-l|wc-l =>1378
>ansible-doc-s file (attribute)

These commands are used to list the modules and check its functionalities.

Playbook Modules

The command line usage of module is different than playbook module as many facts may come from another modules.Apart from these few modules just do not work in ansible command line as the required access may not be obtained.

The popular modules for playbook are-

  • The template module
  • The set-fact module
  • The pause module
  • The wait-for module
  • The assemble module
  • The add_host module
  • The group_by module

The template module

The template module allows us to design an outline of a configuration file.The actual values can be inserted later.The template is predefined set of contents where we just need to put data as per requirements and situations.Whenever,there is a need for dynamic change in the content,we use template in ansible.Templates are written in Jinja2 format.

>ansible-doc-s template

will show the details of template.Destination and source are two required parameter for ansible.Jinja2 format template can hold conditions,for loops,and other macro.

The template creation-
>vi index.j2(jinja2 file)



The host is {{ansible_hostname}}
The page is copied at {{ansible_date_time.time}}
//These two variables are coming from facts
Please contact system admin{{name}}for any issue.
//variable coming from playbook .

Lets create a playbook

- - -
  -hosts:all
    user:ansadmin
    become:true
    become_method:sudo
   vars:
    name:"techtravelhub"
   tasks:
    -name:copy the jinja2 template on the client machine
   -template:
     src:"/etc/ansible/index.j2"
     dest:"temp/index.html"
…

Note-Since the content is dynamic inture,copy module does not work. Copy module only works on static content.So, in this condition we need to use template module.

Loop in jinja2 file
Options{
listen_on port 80{
127.0.0.1
{% for ip in ansible_all_ipv4_addresses%}
{{ip}}
{%endfor%}
};
Comments in Jinja2 file:

Anything in between {# and #} is ignored by jinjaz processor.Comments are not required but best practice to include what we are trying to do.Jinja2 supports if and end if.To enable if loop,we need to put if tag as true.Otherwise anything between {% if %} and { % endif %} is ignored.

{#variables for zone config#}
{% if 'authorative names' in group_names%}
{%set zone_type='test'%}
{%set zone_dir='testdir'%}
{%else%}
{%set zone_type='actual'%}
{%set zone_dir='actualdir'%}
{%endif%}

The set_fact module:

The set_fact module allows us to build our facts on an ansible play.These facts can be used inside templates or variables in the playbook.Facts may come from setup module.

This helps to avoid complex logic inside template.

Example of set_fact module
- - -
   -name:configure DB server
    hosts:db
    tasks:
     -name:install mysql
       Yum:
        name:"mysql_server"
        state:"installed"
      -name:Calculating InnoDB buffer pool size
        set_fact:innodb-buffer-pool-size-mb={{ansible_memtotal_mb/3}}

This will calculate the memory and ensures 1/3 memory is empty.

pause module

The pause module acts as a synchronization point and halts the execution of a playbook for a certain period of time.This pause or wait can be configured.This pause module is very effective while using with playbook but not much of useful when run via command prompt.

Pause module  is useful when we want users to provide input like confirmation.It is also useful when manual intervention is required.It is like through automation we installed something and manually check if everything is working fine.Playbook will wait for an ‘enter’ key from user as a confirmation to proceed.

Example of pause module
- - -
  -hosts:web
    tasks:
     -name:wait for user input
      pause:
        prompt="Enter to continue and ctrl+c to quit"
      -name:timed wait
        pause:
            seconds:60
…

This module can wait for an indefinite time which may delay the execution.

The wait-for module

The wait-for module helps to poll a particular/predefined TCP port.It will halt until that port accepts a remote connection.The polling operation is done with the remote client machines.This module is mostly applicable to the processes or service that takes long time to start or for processes that we want to run in the backend.For such services we need to use wait-for module.

- - -
   -hosts:web
     tasks:
       -name:Install tomcat
          yum:
            name:tomcat 7.1
            state:"installed"
       -name:start tomcat
          service:
            name:tomcat 7.1
            state:"started"
      -name:wait to start tomcat
          wait_for:
            port:"9999"
            state:"started"
…

The Assemble module:

This module helps us to assemble several files that are combined on client machine.This is applicable when config file does not allow includes,globbing.This is also helpful for the authorized_key file.

- - -
   hosts:all
     tasks:
       -name:Build the authorized_key file
         assemble:
           src:"/opt/sshkeys"
           dest:"/root/.ssh/authorized_keys"
           owner:"root"
           group:"root"
           mode:"0700"
…

The add_host module:

This module allows us to dynamically add new client machines into a play.Add_host module adds our host to a group dynamically by creating a non existent group.The module takes hostname and groupname as an argument primarily.But it can accept other arguments like ansible_ssh_user,ansible_ssh_port etc.

The group_by module:

This module creates groups depending upon the facts available about the machine.The group_by module accepts one argument called key.(Key is the group name where the client machine will be added).

- - -
    -name:create operating system group
      hosts:all
      tasks:
       -group_by:
          Key:"os_{{ansible_distribution}}"

The debug module

Please refer the ansible playbook debug section to get the details.

Let us assume a task given as-
task-

  • Subtask1:install a package called
  • httpd using yum module.
  • Subtask2: Start the httpd service using service module.

The playbook will look like –

- - -
-hosts:dbserver.techtravelhub.com or
-hosts:db or
-hosts:127.10.20.25
User:ansadmin
become:true
become_method:sudo
tasks:
     -name:Installing httpd package
       yum:
         name:"httpd"
         state:"present" or "installed"
     -name:starting httpd service
       service:
         name:"httpd"
         state:"started"
...

Now before we run we need to check if httpd is installed or if the httpd service is up or not(we need to check this information in client or in the target machine ).

>rpm-q httpd =>(if software is installed)
>systemctl status httpd =>(Is the service up?)

If they are not installed or service is up,it is time to run the playbook.

How to run playbook in server?

In order to run playbook in server ,first we need to check if we have written playbook correctly.To check the syntax we have the playbook by the following command.

>ansible-playbook playbookname.yml --syntax-check

If there is no syntax error you can execute the playbook by the following command

>ansible-playbook playbookName.yml

In case we can see if the playbook is executed correctly.

Note:-The tasks can have the following status

  • Ok
  • Changed
  • Unreachable
  • Failed

Note:

Now no. of ok+no. of changed+no. of unreachable+no. of failed=Total number of tasks.We can redirect these output to another file.

How to use variable in inventory file and playbook?

Let us create one more playbook named myplaybook.yml

-
  -hosts:web
   user:ansibleadmin
   become:true
   become_method:sudo
   vars:
     {all variables goes here}
     Package_name="httpd"
     Space="500"
    tasks:     
       -name:Install the package {{package_name}}
        yum:
           name: "{{package_name}}"
           state:"installed"
        -name:Make the service {{package_name}} up and running
        service:
           name:"{{package-name}}"
           state:"started"
...

Ansible Playbook to work with debug module

Lets create a playbook named as debug play.

>v1 debugplay.yml
- - -
  -hosts:web
   user:ansibleadmin
   become:true
   become_method:sudo
   tasks:
     -name:To display the time zone
    debug:
      msg:the time zone is {{ ansible-date-time.tz}}
...

How to store results in Ansible?

Like all other modules, debug module provides output. However, debug module helps to extract the output which can be used later, this makes the Playbook more versatile and flexible.

The storing of results can be applied to-

  1. Getting a list of files in a remote directory and downloading them all with fetch.
  2. Running tasks when a previous task changes before the handlers run.
  3. Getting the contents of the remote host SSH key and building a known hosts file.

How to debug a playbook?

Ansible provides two ways to debug a Playbook. They are as follows

  1. A verbose mode
  2. A debug module
  3. The check mode
The verbose mode

Verbose is the basic method to debug a playbook. It just prints out all the values that were returned by each modules after it executes. It is most useful while using register keyword.

Syntax for verbose mode
>Ansible –playbook --verbose playbook name.yml
Debug Module:

Debug module is the little enhanced than verbos but very simple way to debug a Playbook. The debug module text two optional arguments-

  • msg
  • tail

msg sets the message that will be printed if a module fails, if set as yes, it indicates a failure to ansible. If a module fails, It stop the processing the Playbook for the client machine.

-
  -name: show the debug
    hosts:all
    user:root
     vars:
       hostcount:5
     tasks:
       -name: print interfaces
         debug:
              msg:{{item}}"
              with_ items: ansible_interfaces
...

Debug option will help us to understand on what is happening with the Playbook.To enable debug option we can run command with verbose(-v) switch.

level of varbose-

-V-->Provides default output.
-VV-->Provides an extra information than default.
-VVV-->Provides more information than -VV including SSH commands.
The check mode and diff mode

ansible also supports a check mode a diff mode.To enable check mode we need to use -check command and to enable diff mode we need to use -diff command. However, please remember check mode may not provide correct result always.

The diff mode shows the changes that are made by the template module as it works best on text files.The diff mode can be attached to check mode.

How to segregate playbook into different small plays?

Ansible supports to separate our playbook into different files and include them from some other locations. Ansible also supports roles to include multiple files that perform a similar functions. Ansible supports several other methods for increasing the speed at which ansible configures our machine.

Techniques for supporting larger projects

As and when we create complex infrastructure, our playbook bound to become huge in size. A large playbook is very difficult to read and maintain. Debugging and fault finding becomes tedious job.To avoid these issues, ansible supports divide and rule principal by providing includes.

Includes

Includes split the playbook into diff sections containing related plays. These small or granular level plays can be assembling into main playbook.

There are four types of includes available in ansible-

  • Variable Includes-They put out variables in external YAML files.
  • Playbook Includes-They put plays from another files in a single play.
  • Task Includes-They put tasks in another file, later includes them in main playbook.
  • Handler includes-All handlers can be put in a single file and later can be called from main playbook.

Task includes

Task includes are useful when we have lots of common tasks that need to be repeated on client machines. We can put all these tasks into a separate YAML file and include them from main task.

Task includes inherit the facts from the play they are included from. However, we can create and use our own variables.

We can include conditions on each tasks. Conditions will separately be added to each included task. The tasks are still included.

An example of task includes in ansible playbook

-setupuser.yml

-
   -name:create user account
     user:
       name:"{{user}}"
       state:present
   -name:create user SSH directory
      file:
       path:"/home/{{user}}/.ssh"
       owner:"{{user}}"
       group:"{{user}}"
       mode:"0600"
       state:"directory"
   -name:copy public key
     copy:
      src:"keys/{{user}}.pub"
      dest:"/home/{{user}}/.ssh/authorized_keys"
      mode:"0600"
      owner:"{{user}}"
      group:"{{user}}"
...

Actual playbook

- - -
  -host:all
   user:ansadmin
    tasks:
      -include:setupuser.yml user={{item}}
        with_item: 
          -abc
          -xyz
          -mno
...
Handler includes

Similar to tasks includes, we can place all handlers into a different yaml file an and later calls them into playbook.

-restart.yml-

-
  name :Restarting the service
   service:
    name:"{{pname}}"
    state:restarted
...

The Handler includes file contents several common tasks that we want to handle after the task has been done. They are reusable in nature. Handler can further trigger other handlers. Thus we can set up a series of cascading handlers one after another.

-
   tasks:
    name: install httpd
     yum:
      name:"httpd"
      state:"installed"
     notify: restart service
.
.
.
.
.
    handlers:
     -include :restart.yml
...

Playbook includes

Play Book includes allows us to include whole plays. These plays can be embedded as fully self contained files.

-
  -include "myplay1.yml"
  -include "myplay2.yml"
  -include "myplay3.yml"
.
.
.
.
...

Filter operation on Playbook

>ansible- i hosts playbooks/anyplaybook.yml-- list tasks

This command provides the tasks.

>ansible- i hosts playbooks /myplaybook.yml-- start -at-task='install httpd package'(package)

This command will start executing the task we specify.

>ansible-playbook-i hosts playbooks /my playbook.yml--step

This command will prompt user to execute task in the form of y/n.

Ansible pull mode

To improve playbooks scalability to a larger extent for large project ansible supports a pull mode. In this mode ansible does not connect over SSH rather it runs only on the machine it is working. It downloads the already configured configuration file from git repository.

We need to use ansible pull in the below written scenarios
  • If the node is a member of auto scaling server farm and not available when configuring them.
  • We have a large machine base to configure with equally higher numbers of forks. They make fake huge time to get configured.
  • All our machines need to update their configuration automatically when repository in updated.
  • We are working on a machine where we do not have network access.
The disadvantages of pull mode
  • We need credentials to access other machines, gather variables and a copy of files.
  • We need to manually co-ordinate to run the playbooks across a server farm.
  • Servers may be behind Strict firewalls that may not allow SSH connection(incoming)

Pull mode does not require any major changes in the playbook rather, we need to setup a cron job that will run the ansible-pull mode configuration on every predefined minutes.

Playbook example of pull mode

-
  -name: setup cron
    cron:
     name:"ansible-pull"
     user: ansadmin
     minute:"/10"
     state:"present"
     job:"ansible-pull-u" http://git.int.example.com.com/gitrepos/ansiblepull.git-D/opt/ansiblepull
         {{inventory_ hostname_short}}.yml
...

How to test connectivity between server and clients?

Ansible provides a module called ping that helps us to test the connectivity.

>ansible appserver1.techtravelhub.com—u root—m ping

O/P-

appserver1.techtravelhub.com | success >>{
"changed" : false ,
"ping":"pong"
}

In case if you have setup SSH key you don’t need to use –k argument.If you have set up ansible user then you do not need to specify the user(root) also.

How to setup username globally?

In order to set up username globally we need to configure ansible.cfg.Open the same file in vi editor and the file will look like below-

Now navigate to remote—user under default section .We can also change the default part where ansible connects using SSH.To add username in the inventory file we need to add the below line—

ansible—ssh—user

like

[Web] 
webserver1.techtravelhub.com ansible—ssh—user = ansadmin
webserver2.techtravelhub.com ansible—ssh—user = testuser

Provide user a sudo privileges

To provide an user a sudo privileges, we need to use -–become command.

Open sudoers. in vi editor

>vi /etc/ sudoers

Now goto the line

Root ALL = (ALL) ALL

Provide your user name like

ansadmin | ALL =(ALL) NO PASSWD:ALL

Now we need to change this line (add this line) in all client machines in order to provide this user (ansadmin) sudo privilege in every machine.

>ansible all – m user-a  "name=ansadmin state=present” -- become

You can use password with sudo or you can use passwordless sudo.

If you want to use the password ,you need to use-k argument or set the ask –sudo-pass value to true .You can use – – sudo command in command line as well.

Adhoc Commands

Adhoc commands are useful to provide some generic commands.Like copy a file ,ping a machine.Assume that we have the below inventory file

[Web]
webserver1.techtravelhub.com
[db] 
dbserver1.techtravelhub.com

We want to copy a file from to web server.
The ad hoc command syntax –

>ansible-m-a
>ansible-all /web/10.0.0.1 -m file/copy/user/yum/ping

Like

>ansible all-m ping =>pings all machines
>ansible all-m shell-a "hostname" =>Gives hostname
>ansible all-m shell-a "uname" =>Gives username
>ansible all-m shell-a "etc/os_release"=> Gives OS name
>ansible all-m user-a "name=techtravelhub state=present"

This command checks all machines where name = techtravelhub is present.

Variables in Ansible

Concept of variables in Ansible is defined in the variable section.

Ansible facts

Ansible facts are the info of the node or client machine.Like

  • host_name
  • ipaddress(ipv 4,ipv 6…)
  • karnel version
  • network devices
  • hard disk etc

Ansible facts are the read only information and cannot be changed from ansible server.

>ansible web –m setup =>(provides us the setup info)

The info will give us lots of other information which we may not be interested.So we can filter the information that we require.

>ansible web –m setup -a "filter=ansible-architecture”

Provides you all client related OS details

>ansible web –m setup -a "filter=ansible-distribution"
>ansible web -m setup -a "filter=ansible-date-time"

To print these information ,we can use debug module and use “msg” command to get these.

How to work with Inventory files in Ansible?

Inventory files plays a great roles in Ansible configuration.

Configuring Inventory File

Basic editing of inventory file (just like an .ini file ) needs to be done manually using any text editor (I personally like Vi editor). However you can also download and install inventory plugins. By default the default inventory file is called hosts and is placed at /etc/ansible. The default file resembles to .ini file.

Some basic default values of inventory(.cfg)file

#inventory                   =/etc/ansible/hosts
#library                     =/usr/share/my_modules
#module_utils                =/usr/share/my_modules_utils
#remote_tmp                  =~/.ansible/tmp
#local_tmp                   = ~/.ansible/tmp
#forks                       =5
#poll_interval               =15
#sudo-user                   =root
#ask-sudo-pass               =True
#ask-pass                    =True
#transport                   =smart
#remote_port                 =22
#module_lang                 =c
#module_set_locale           =False

How to work with Inventory Files in Ansible?

Inventory file contains the lists of nodes(client machine details).Inventory files of Ansible has two entries

  1. Static inventory –where ip does not change
  2. Dynamic inventory-where ip may change(cloud platform)
Static Inventory

Default ansible inventory is located at /etc/Ansible/Hosts.Depending on the inventory modules, inventory file may be in any format.(Best practice to use an .ini format)

Ansible inventory parameters

There are two variables that controls how ansible will interact will hosts.

  • ansible_host-This variable is used to specify the FQDN or ip address of the server.
web ansible_host=webserver1.techtravelhub.com
db ansible_host= dbserver1.techtravelhub.com
  • ansible_connection-This variable is used to specify how the ansible will connect the target servers.
webserver1.techtravelhub.com ansible_connection=ssh

How to change default inventory?

To change default inventory we need to open hosts in a vi editor. In the content section everything starts with a # is commented.We can edit the file in insert mode.

Like

10.2.5.25
abc.myhost.com

How to list out host names?

>ansible all --list--hosts

This command will lists out the hosts and ip address from host file.

How to create customized host file without the default host file?

To create a customized host file without touching the default host file, we need to create a .ini file( extension is not mandatory but best practice).

>vi myInventory.ini
190. 125. 9. 5
190. 125. 9. 10
190. 125. 9. 15

this is how we reinsert new hosts or ips. Once we entered the details, we need to provide the below command to apply this new host file

>ansible all-- list --hosts -i myInventory.ini

Note:

In the above command if you do not give -i switch and the inventory file name the command will fetch details from the default inventory

>ansible all-- list --hosts

If by mistake if we put ip address and host name, will ansible try to push both the time?

No, it will try to do the same but as it is already done previously and no changes happened in between, it will only say ok.

How to create logical grouping in inventory file?

Groups:

Group names are enclosed with a square bracket([ ]) and everything written below to it before next group starts or an end of inventory file characters encountered (…) is part of the above group.

A machine can be in many groups .However Ansible will run the module on the entire group at once.

In inventory file create the groups by providing the group name in square bracket.like [group name]

1.[ web] 
webServer1.techtravelhub.com
webServer2.techtravelhub.com
. 
.
.
.
webServerN.techtravelhub.com
2.[db] 
dbServer1.techtravelhub.com
dbServer2.techtravelhub.com
.
.
.
.
dbServerN.techtravelhub.com
3.[app] 
appServer1.techtravelhub.com
appServer2.techtravelhub.com
.
.
.
. 
appServerN.techtravelhub.com

Instead of hostname you can give ip address or ip and hostname combined.

How to create child group inside the Inventory file?

Ansible supports groups and subgroup concept in inventory file.

Like—

[India]
S1.techtravelhub.com
S2.techtravelhub.com
[Africa]
A1.techtravelhub.com
A2.techtravelhub.com
[China]
C1.techtravelhub.com
C2.techtravelhub.com
[asia:children]
India
China
>ansible india --list-hosts =>o/p-2
>ansible asia --list-hosts =>o/p-4

In subgroup we can use IP addresses as well(along with host names).Ansible supports shorter name instead of long host names.

[Servers]
web ansible –host= S1.techtravelhub.com
>ansible web -- list-host => o/p-1

Apart from these ansible supports to mention connection information.

[Servers]
Server2.techtravelhub.com ansible-connection='ssh'
Server1.techtravelhub.com ansible-connection='coinrun'

Incase you have not mentioned the connection information,the default is SSH.

Along with these ansible supporters ansible-user ,ansible-ssh-pass,ansible-port with the host information.

Like

[Servers]
Server1.techtravelhub.com ansible-user='admin'
ansible-ssh-pass="[email protected]"
ansible-port='8080'

How to filter inventory file?

> ansible web--list-hosts //fitters all hosts name present in web group.
> ansible db--list-hosts //fitters all hosts name present in db group.
> ansible app--list-hosts //fitters all hosts name present in app group .
> ansible all--list-hosts //fitters all hosts name present in the inventory file.

How to insert two groups in filter command?

>ansible web && db -–list-host(need to confirm)

Regular Expression in Ansible Filter

Ansible supports regular expression – pattern matching in inventory file. Say we have the following servers under web groups

[web]
webserver1.techtravelhub.com
webserver2.techtravelhub.com
.
.
.
.
webserver10.techtravelhub.com

The same can be written as —

webserver[1:10].techtravelhub.com
>ansible web--list-host

Command will bring all ten web servers.

How to Work with Ansible Loop and conditions?

Loops and Conditions are powerful tool to customize the Ansible tasks.This section of the post talks about Ansible loops,ansible loop with_subelements,ansible loops examples,ansible loops tutorial,ansible loops with_items,ansible loop vs with_items,ansible loops variables,ansible advanced loops,ansible loops explained,ansible loops in playbook.

 Ansible loops

Loops are used to perform repetitive tasks.Ansible allows us to perform repetitive tasks over several times with different inputs the repetition can be done using looping.

Ansible supports three looping structure.

  • Simple loop
  • Lists of Hashes
  • Nested loops
Simple loop

Simple loop can be done using with_items key and iterate over a set of values provided to the list of items. Here ‘item’ becomes the variable. The list of items are fixed or static.

Let us assume,we need to install three different packages in all client machines.

The package are-

  • vsftpd
  • httpd
  • postfix

So,in general we will create one playbook where all these 3 tasks will be defined.Lets us create a playbook named noloopplay.yml

>vi noloopplay.yml

The structure will be:

- - -
   -hosts:db
    user:ansadmin
    become:true
    become_methods:sudo
    tasks:
      -name:Install package vsftpd
       yum:
         name:"vsftpd"
         state:"installed"
      -name:Install package httpd
       yum:
         name:"httpd"
         state:"installed"
      -name:Install package postfix
       yum:
         name:"postfix"
         state:"installed"
…

Now if we see the tasks carefully,we can observe only the package name is changing in the three tasks.so we can create a simple loop to perform these tasks.
To create a task with simple loop,we will create a playbook named withloopplay.yml file.

>vi withloopplay.yml

The structure will be

- - -
   -hosts:db
    user:ansadmin
    become:true
    become_methods:sudo
    tasks:
      -name:Installing package
        yum:
          name:{{item}}
          state:"installed"
          with _item:
             -httpd
             -postfix
             -vsftpd
...

One more example with simple loop and variable

- - -
   -hosts:db
    user:ansadmin
    become:true
    become_methods:sudo
    vars:
      packages:
         -httpd
         -postfix
         -vsftpd
    tasks:
      -name:Installing package
        yum:
          name:{{item}}
          state:"installed"
          with _item:"{{packages}}"
//we can even start the services
       -name:Starting services
         service: 
           name:{{item}} 
          


This post first appeared on Tech Travel Hub, please read the originial post: here

Share the post

How to Work With Ansible?

×

Subscribe to Tech Travel Hub

Get updates delivered right to your inbox!

Thank you for your subscription

×