I

What is Ansible?

Ansible is an open-source automation tool for configuration management, enabling easy configuration of multiple networked servers simultaneously. It is commonly used for automating deployment, configuration management, and orchestration tasks in IT environments.

Ansible uses SSH to communicate with remote machines and does not require any agents to be installed on them, making it lightweight and easy to set up.

Ansible is suitable for heterogeneous environments. It can query servers to determine their operating systems and then use the appropriate commands to automate the tasks across different os, which helps in eliminating the need for manual command creation.

Puppet, Chef, and SaltStack are other popular configuration management and automation tools similar to Ansible.

Ansible Control and Managed Nodes

Control Node:In Ansible, the control node is the machine where Ansible is installed and from which Ansible playbooks and commands are executed.

Managed Node:Managed nodes, on the other hand, are the machines that are being managed by Ansible. Ansible does not require any agent software to be installed on managed nodes.

ansible-architecture

Ansible key components

In Ansible, there are several key components and concepts that are important to understand:

  1. Playbooks: Playbooks are YAML files that define a set of tasks to be executed on remote hosts. They can also include variables, handlers, and other Ansible components.
  2. Tasks: Tasks are the individual units of work in Ansible playbooks. They are actions that Ansible performs, such as installing a package, copying a file, or restarting a service.
  3. Roles: Roles are a way of organizing and reusing Ansible code. They encapsulate a set of tasks, variables, and files related to a specific function or application.
  4. Inventory: The inventory is a list of managed nodes (servers or devices) that Ansible can interact with. It can be static (defined in a file) or dynamic (generated by a script).
  5. Modules: Ansible modules are standalone scripts that Ansible uses to perform tasks on remote hosts. They can manage packages, files, services, and more.
  6. Handlers: Handlers are tasks that are only executed if they are notified by other tasks. They are typically used to restart services or perform other actions that should only occur when a change has been made.
  7. Facts: Facts are pieces of information about remote hosts that Ansible gathers and can use in playbooks. They include things like the operating system, IP address, and hardware details.
  8. Variables: Variables are used to customize playbooks and make them more flexible. They can be defined at various levels (e.g., playbook, role, inventory) and are used to parameterize tasks and templates.

Ansible Installation- Control Node

To install Ansible, you can follow these steps:

  1. On Linux: Ansible can be installed using the package manager of your distribution. For example, on Ubuntu, you can use:
  2. sudo apt update
      sudo apt install ansible
  3. On macOS: Ansible can be installed using Homebrew:
  4. brew install ansible
  5. On Windows: Ansible can be installed using the Windows Subsystem for Linux (WSL) or other methods compatible with Windows.

Once installed, you can test your Ansible installation by running the following command:

ansible --version

Click here to visit the official Ansible documentation page.

Managed Nodes setup

With the previous step completed, the Control node is now ready. Next, we will set up the managed nodes. For this lab, I will be using two nodes with the following IP addresses.

Control Node : 172.31.20.208
Managed Node1 : 172.31.44.212
Managed Node2 : 172.31.34.5

The control node uses SSH to connect with the managed nodes. Therefore, we need to ensure that SSH is running on both the control and managed nodes.
To check the running status of the SSH daemon (sshd), you can use the following command:

sudo systemctl status sshd
Control Node:
ansible-architecture
Managed Node1:
ansible-architecture
Managed Node2:
ansible-architecture

Ansible Adhoc commands


To showcase Ansible's capabilities, we will begin with Ansible ad hoc commands. Ansible ad hoc commands utilize the /usr/bin/ansible command-line tool to automate a single task on one or more managed nodes. While these commands are quick and easy, they are not reusable.

Ping test from Control node to Managed node using ad hoc command:

Using managed node username & password:

ansible -i 172.31.44.212, all -m ping -e ansible_user=datechknow -e ansible_password=password123
ansible -i 172.31.34.5, all -m ping -e ansible_user=datechknow -e ansible_password=password123
Using .pem file:
ansible -i 172.31.44.212, all -m ansible.builtin.service -a "name=sshd state=started" --user ec2-user --key-file=/home/ec2-user/myproject.pem
ansible -i 172.31.34.5, all -m ansible.builtin.service -a "name=sshd state=started" --user ec2-user --key-file=/home/ec2-user/myproject.pem
Sample output:
ansible-architecture
Checking if SSHD is running on managed hosts using Ansible ad hoc commands:

To execute a task in Ansible, you must specify the corresponding Ansible module and provide the necessary arguments as parameters. Ansible will then use this information as input to perform the task on the specified managed nodes.

For Example: "ansible.builtin.service" in this service is the module from Ansible collection "ansible.builtin". One collection can have many modules. You need to choose the correct module as per the task you want to perform.

To learn about different Ansible collections and associated modules you can follow the given resource links: Ansible Collections and Ansible modules


The following demo shows how to use ansible module "ansible.builtin.service" to verify whether a specific process running or not in the managed hosts using Ad hoc command.

ansible -i 172.31.44.212, all -m ansible.builtin.service -a "name=sshd state=started" --user ec2-user --key-file=/home/ec2-user/myproject.pem
ansible -i 172.31.34.5, all -m ansible.builtin.service -a "name=sshd state=started" --user ec2-user --key-file=/home/ec2-user/myproject.pem
Sample output:
ansible-architecture

Adhoc command with Inventory File

Inventory file:the inventory file is where you define the list of managed hosts and organize them into groups. This allows you to target specific groups of hosts for automation tasks

 Below is the inventory file format:
          
          [web_servers]  ---> this is a group name
          web1.example.com  -> managed server1
          web2.example.com
          
          [db_servers] ---> This is a group name
          db1.example.com  -> managed db server1
          db2.example.com

          Below is my inventory file (myserverlist) with the managed IP addresses:

          [server_group1]
          172.31.44.212
          172.31.34.5
        
inventory-create

          Sample command using inventory file:

          ansible -i myserverlist server_grp1 -m ansible.builtin.service -a "name=sshd state=started" --user ec2-user --key-file=/home/ec2-user/myproject.pem
           
          myserverlist - is the inventory file name that I created
          server_grp1 - is the group name I used for the list of managed hosts.

        

Below is another example of checking httpd service status on all the managed hosts listed in the inventory file. However httpd service is installe in 172.31.44.212 but not started. And in the other node httpd is not installed. Now refer to the error generated for the ansible command execution.


[ec2-user@ip-172-31-20-208 ansible]$ ansible -i myserverlist server_grp1 -m ansible.builtin.service -a "name=httpd state=started" --user ec2-user 
--key-file=/home/ec2-user/myproject.pem
[WARNING]: Platform linux on host 172.31.34.5 is using the discovered Python interpreter at /usr/bin/python3.9, but future installation of another Python
interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.15/reference_appendices/interpreter_discovery.html for more
information.
172.31.34.5 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.9"
    },
    "changed": false,
    "msg": "Could not find the requested service httpd: host"
}
[WARNING]: Platform linux on host 172.31.44.212 is using the discovered Python interpreter at /usr/bin/python3.9, but future installation of another Python
interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.15/reference_appendices/interpreter_discovery.html for more
information.
172.31.44.212 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.9"
    },
    "changed": false,
    "msg": "Unable to start service httpd: Failed to start httpd.service: Access denied\nSee system logs and 'systemctl status httpd.service' for details.\n"
}
[ec2-user@ip-172-31-20-208 ansible]$