The inventory file

The collection of hosts that Ansible knows about is called the inventory.

The simplest inventory file just contain a list of hostnames or IP addresses.

There is one host that Ansible automatically adds to the inventory by default: localhost. Ansible understands that localhost refers to your local machine, so it will interact with it directly rather than connecting by SSH.

Apart from host name, you can also specify other parameters, for example, if you changed the default ssh port from 22 to 2000 on the target machine, you needs to specify this in the inventory file:

testserver ansible_ssh_host=192.168.10.73 ansible_ssh_port=2000

The parameters are shown following:


Name Default Description
ansible_host name of host Hostname or IP address to SSH to
ansible_port 22 Port to SSH to
ansible_user root User to SSH as
ansible_ssh_pass none Password to use for SSH authentication
ansible_connection smart How Ansible will connect to host (see below)
ansible_ssh_private_key_fle none SSH private key to use for SSH authentication
ansible_shell_type sh Shell to use for commands (see below)
ansible_python_interpreter /usr/bin/python Python interpreter on host (see below)
ansible_*_interpreter none Like ansible_python_interpreter for other languages

 

Note: Ansible 2.0 has deprecated the “ssh” from ansible_ssh_user, ansible_ssh_host, and ansible_ssh_port to become ansible_user, ansible_host, and ansible_port. If you are using a version of Ansible prior to 2.0, you should continue using the older style variables (ansible_ssh_*). These shorter variables are ignored, without warning, in older versions of Ansible.

ansible_connection: The default transport, smart, will check to see if the locally installed SSH client supports a feature called ControlPersist. If the SSH client supports Controlpersist, Ansible will use the local SSH client.

If the SSH client doesn’t support  ControlPersist, then the smart transport will fall back to using a Python-based SSHclient library called paramiko

ansible_shell_type
Ansible works by making SSH connections to remote machines and then invoking scripts. By default, Ansible assumes that the remote shell is the Bourne shell located at /bin/sh.

ansible_python_interpreter

Ansible modules are not (yet) compatible with Python 3, only python2.

ansible_*_interpreter
If you are using a custom module that is not written in Python, you can use this parameter to specify the location of the interpreter (e.g., /usr/bin/ruby) .

Defaults that can be overridden in ansible.cfg

Behavioral inventory parameter  ansible.cfg option
ansible_port remote_port
ansible_user remote_user
ansible_ssh_private_key_fle private_key_fle
ansible_shell_type executable

Ansible supports doing <hostname>:<port> syntax when specifying hosts.

So the testserver ansible_ssh_host=192.168.10.73 ansible_ssh_port=2000 equals 192.168.10.73:22

If you want to control AWS webservers, you can add the servers in following format:

[webservers]
13.64.28.32 ansible_ssh_private_key_file="/home/administrator/web.pem" ansible_user=ec2-user
13.64.28.34 ansible_ssh_private_key_file="/home/administrator/web.pem" ansible_user=ec2-user

To test the connectivity:

sudo ansible webservers -i hosts -m ping

ec2-xxx-xxx-xxxx-xxx.ap-southeast-2.compute.amazonaws.com | SUCCESS => {

    "ansible_facts": {

        "discovered_interpreter_python": "/usr/bin/python"

    },

    "changed": false,

    "ping": "pong"

Try with command free to see the memory usage:

sudo ansible MCI_web -i hosts -m command -a free

Password:

ec2-xxx-xxx-xxxx-xxx.ap-southeast-2.compute.amazonaws.com  | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache   available

Mem:        1013900      467244      186028       57792      360628      310552

Swap:             0           0           0
Groups Groups of Groups

Ansible automatically defines a group called all (or *), which includes all of the hosts in the inventory.
The Group is usually in this format:

[group_name]
host_name parameters

Groups of Groups

Ansible also allows you to define groups that are made up of other groups by using the name_of_parent_group:children suffix in INI or the children: entry in YAML. . The format is:

[name_of_parent_group:children]
group_name_1
group_name_2

If you have multiple servers, like web01.example.com, web02.example.com…..web20.example.com, you can use format:

[webservers]
web[01:20].example.com

This also apply to letters:

[web]
web-[a-t].example.com

You can apply variables using :vars or vars:

If we want to do the following:

• Configure the web servers with the hostname, port, username, password of the
primary postgres server, and name of the database.
• Configure the task queues with the hostname, port, username, password of the
primary postgres server, and the name of the database.
• Configure the web servers with the hostname and port of the RabbitMQ server.
• Configure the task queues with the hostname and port of the RabbitMQ server.
• Configure the primary postgres server with the hostname, port, and username
and password of the replica postgres server (production only)

[all:vars]
ntp_server=ntp.ubuntu.com
[production:vars]
db_primary_host=rhodeisland.example.com
db_primary_port=5432
db_replica_host=virginia.example.com
db_name=widget_production
db_user=widgetuser
db_password=pFmMxcyD;Fc6)6
rabbitmq_host=pennsylvania.example.com
rabbitmq_port=5672
[staging:vars]
db_primary_host=quebec.example.com
db_name=widget_staging
db_user=widgetuser
db_password=L@4Ryz8cRUXedj
rabbitmq_host=quebec.example.com
rabbitmq_port=5672

There is a more scalable way:

Ansible looks for host variable files in a directory called host_vars and group variable files in a directory called group_vars. Ansible expects these directories to be either in the directory that contains your playbooks or in the directory adjacent to your inventory file.

 

Dynamic inventory

If you have a system external to Ansible that keeps track of your hosts, and you don’t want to manually duplicate the information in your hosts file, you can use the feature dynamic inventory to avoid the duplication.

If the inventory file is marked executable, Ansible will assume it is a dynamic inventory script and will execute the file instead of reading it.

An Ansible dynamic inventory script must support two command-line flags:

–host=<hostname> for showing host details
–list for listing groups

Adding Entries at Runtime with add_host and group_by

Because the dynamic inventory script is executed at the beginning of the playbook, so if any new hosts are added while the playbook is executing, Ansible won’t see them.

Ansible will let you add hosts and groups to the inventory during the execution of a playbook.
add_host

The add_host module adds a host to the inventory. This module is useful if you’re using Ansible to provision new virtual machine instances inside of an infrastructureas-a-service cloud.

Issue

sshpass issue:

| FAILED | rc=-1 >>

to use the 'ssh' connection type with passwords, you must install the sshpass program

Solution: brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb

 

run command:

 

no matching cipher found. Their offer: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc

On the host side:

  1. Launch a terminal.
  2. Paste the line into the terminal: sudo nano /etc/ssh/ssh_config
  3. Enter your password. Press Enter. SSH config file will be displayed.
  4. Un-comment the line: Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc