The ansible config file #
Ansible.cfg #
The ansible.cfg file is the configuration file for Ansible. It can be used to set various options and settings that control the behavior of Ansible and how it operates.
Some common options that can be set in the ansible.cfg file include:
- inventory: This specifies the path to the inventory file that lists the hosts that Ansible will operate on.
- library: This specifies the path to the directory containing Ansible modules.
- module_utils: This specifies the path to the directory containing utility modules used by Ansible.
- log_path: This specifies the path to the file where Ansible will log its output.
- roles_path: This specifies the path to the directory containing Ansible roles.
There are many other options that can be set in the ansible.cfg file, and you can find more information about them in the Ansible documentation.
The ansible.cfg file contains settings for tweaking the ansible service on the control node.
- First, we will be generating a ansible.cfg default configuration file. The following command will generate a file with all settings disabled:
ansible-config init --disabled > ansible.cfg- The following modification to the ansible file is for testing purposes only. We will set the host_key_checking variable to False to allow us to connect to target hosts without verifying the SSH key. In a production environment, it is strongly recommended to import the keys. When you are in the /etc/ansible directory, edit the ansible.cfg file.
sudo nano ansible.cfg- Next, find the host_key_checking entry (you can search in nano by pressing CTRL + W and entering the search term) Remove the ‘;’ in front of the entry and enter the following:
host_key_checking=FalseThe inventory file #
Ansible Inventory is a file that contains a list of hosts, which are the servers or devices that Ansible will manage. In its most basic form, the inventory file is just a flat list of hosts (or also called “Targets”). However, in more advanced , enterprise deployments, the inventory file is frequently hosted on a Git repository (Github or Gitlab for example). The added value of extra source control helps teams collaborate and track changes made to the inventory file.
The inventory file defines groups of hosts, which allow you to apply actions to multiple servers at once. In this chapter, we will start with some simple examples of how to define hosts with usernames and passwords in the inventory file, and then show how to use groups and variables.
When you installed ansible, a default inventory file can be found in the directory /etc/ansible/hosts.
Inventory breakdown #
the following structure is used within a basic inventory file.
[<group name>]
<optional alias name> <IP address> <parameters>
[<group name>:vars]
<specific variable>=<value>[linux_hosts]
webserver1 ansible_host=192.168.5.2 ansible_user=davy ansible_password=SuperVeiligWachtwoordVanDavySpecial characters in passwords #
When the password you are using to connect to a target hosts contains special characters (like ‘#’, ‘!’, ‘ç’,… ), Ansible will attempt to parse it as a special character. If you want to negate this (so it can be used like a normal character), you have to add a backslash ‘\’. An example: you have a target hosts with the following password:
ThisIsADifficult#password
The following would cause an error:
webserver1 ansible_host=10.10.10.10 ansible_user=davy ansible_password=ThisIsADifficult#passwordTo negate the special # character, it has to be defined as follows:
webserver1 ansible_host=10.10.10.10 ansible_user=davy ansible_password=ThisIsADifficult\#passwordParameter overview #
The inventory file can be used to define variables for hosts, groups, and even all hosts in the inventory. These variables can be used to customize the behavior of Ansible playbooks, such as setting connection parameters, defining host-specific variables, and more.
Here are some of the commonly used parameters that can be used in an inventory file:
- ansible_host: the IP address or hostname of the host. This is used by Ansible to connect to the host via SSH or other connection plugins.
- ansible_user: the username to use when connecting to the host.
- ansible_port: the SSH port number to use when connecting to the host. The default value is 22.
- ansible_ssh_private_key_file: the path to the private key file to use for SSH authentication.
- ansible_password: the password to use when connecting to the host. This is not recommended for security reasons and should be used only as a last resort.
- ansible_ssh_pass: an alternative to ansible_password that specifies the password to use when connecting to the host via SSH. This is also not recommended for security reasons and should be used only as a last resort.
- ansible_connection: the connection plugin to use when connecting to the host. The default value is ssh, but other plugins such as winrm, local or docker can be used for connecting to different types of hosts.
- ansible_become: a boolean value that determines whether to use privilege escalation when running commands on the host. The default value is false.
- ansible_become_user: the username to use for privilege escalation when running commands on the host.
- ansible_become_password: the password to use for privilege escalation when running commands on the host. This is not recommended for security reasons and should be used only as a last resort.
- ansible_shell_type: the shell type to use when running commands on the host. The default value is sh, but other shells such as bash or zsh can be used.
Variables in the inventory file #
Say you have a group of 10 servers who have a simular naming convention and can be queried by using the same username and password. Say they are named as follows:
- Webserver01
- Webserver02
- …
- Webserver10
Instead of adding 10 lines into the inventory file, you could add them as one single line using the following pattern:
webserver[01-10].lab.local ansible_user=webadmin ansible_password=WebadminsecretpassBasic Examples #
Linux Server #
Suppose we have a Linux server with IP address 192.168.1.10, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:
[linux_servers]
linux1 ansible_host=192.168.1.10 ansible_user=ansibleuser ansible_password=password123In this example, we have created a group called
\[linux-servers\]and added our Linux server to that group. We have also specified the ansible_user and ansible_password variables to tell Ansible how to connect to the server.
Windows Server #
Similarly, suppose we have a Windows server with IP address 192.168.1.20, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:
[windows_servers]
win1 ansible_host=192.168.1.20 ansible_user=ansibleuser ansible_password=password123 ansible_connection=winrm ansible_winrm_transport=ntlmIn this example, we have created a group called
\[windows-servers\]and added our Windows server to that group. We have also specified the ansible_user, ansible_password, ansible_connection, and ansible_winrm_transport variables to tell Ansible how to connect to the server using WinRM.
Cisco Switch #
Suppose we have a Cisco switch with IP address 192.168.1.30, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:
[cisco_switches]
access_SWBlockD ansible_host=192.168.1.30 ansible_user=ansibleuser ansible_password=password123 ansible_connection=network_cliIn this example, we have created a group called
\[cisco-switches\]and added our Cisco switch to that group. We have also specified the ansible_user, ansible_password, and ansible_connection variables to tell Ansible how to connect to the switch using the network_cli connection plugin.
Using Groups and Variables #
Group Vars #
In the previous examples, we specified the username and password for each host individually. If we have many hosts, it can be tedious to specify these variables for each one. Instead, we can use group variables to specify the variables for a group of hosts.
For example, suppose we have a group of Linux servers and we want to use the same username and password for all of them. We can define a group variable in our inventory file like this:
[linux_servers]
server1 ansible_host=192.168.1.10
server2 ansible_host=192.168.1.11
[linux_servers:vars]
ansible_user=ansibleuser
ansible_password=password123In this example, we have defined a group of Linux servers, and then defined a group variable for that group using the
\[groupname:vars\]syntax. The ansible_user and ansible_password variables will apply to all hosts in the linux-servers group.
Child groups #
Child groups are defined using the \[child-group:children\] syntax in the inventory file, where child-group is the name of the child group, and children is the keyword that specifies the parent group. Any settings defined in the parent group will be inherited by the child group, including any host or variable definitions.
Child groups are useful for organizing your inventory file and simplifying the definition of properties and variables for related hosts. You can use them to group hosts by function, environment, or any other category that makes sense for your infrastructure.
Example 1: Child Groups in the Linux Server Group #
Suppose we have a group of Linux servers that we want to divide into two child groups, web-servers and db-servers, and we want to define different variables for each child group.
We can define our inventory file like this:
[linux_servers]
server1 ansible_host=192.168.1.10
server2 ansible_host=192.168.1.11
server3 ansible_host=192.168.1.12
[web_servers:children]
linux_servers
[db_servers:children]
linux_servers
[web-servers:vars]
http_port=8080
[db-servers:vars]
db_port=3306In this example, we have created a group called linux-servers with three hosts. We have then defined two child groups, web-servers and db-servers, that both inherit from linux-servers. We have also defined different variables for each child group.
When we run an Ansible playbook that targets web-servers, Ansible will run the playbook against all hosts in the web-servers group, which includes all hosts in the parent group linux-servers. Ansible will also use the http_port variable for all hosts in the web-servers group.
Similarly, when we run an Ansible playbook that targets db-servers, Ansible will run the playbook against all hosts in the db-servers group, which includes all hosts in the parent group linux-servers. Ansible will also use the db_port variable for all hosts in the db-servers group.
Example 2: Child Groups in the Windows Server Group #
Suppose we have a group of Windows servers that we want to divide into two child groups, dev-servers and prod-servers, and we want to define different connection variables for each child group.
[windows_servers]
server1 ansible_host=192.168.1.20
server2 ansible_host=192.168.1.21
server3 ansible_host=192.168.1.22
[dev_servers:children]
windows_servers
[prod_servers:children]
windows_servers
[dev_servers:vars]
ansible_user=devuser
ansible_password=devpass
[prod_servers:vars]
ansible_user=produser
ansible_password=prodpassIn this example, we have created a group called windows-servers with three hosts. We have then defined two child groups, dev-servers and prod-servers, that both inherit from windows-servers. We have also defined different connection variables for each child group.
When we run an Ansible playbook that targets dev-servers, Ansible will run the playbook against all hosts in the dev-servers group, which includes all hosts in the parent group windows-servers. Ansible will also use the ansible_user and ansible_password variables for all hosts in the dev-servers group.
Similarly, when we run an Ansible playbook that targets prod-servers, Ansible will run the playbook against all hosts in the prod-servers group, which includes all hosts in the parent group windows-servers. Ansible will also use the ansible_user and ansible_password variables for all hosts in the prod-servers group.
Configuring Ansible to use keypair authentication #
In the Ansible configuration file (ansible.cfg), specify the private key:
[defaults]
private_key_file = ~/.ssh/id_rsaOr alternatively, set it in the inventory file (this is the preferred way as it’s way more granular)
Add the following entry at the host or group you wish to authenticate to using a keypair:
ansible_ssh_private_key_file=~/.ssh/id_rsa
Full example rule:
kasm ansible_host=172.16.90.10 ansible_user=davy.cavens ansible_ssh_private_key_file=~/.ssh/id_rsa Modules and plugins #
As you can see in the example commands on the previous page, ansible uses ‘modules’. Ansible modules are small pieces of code that are responsible for carrying out specific tasks on remote hosts. Modules can be thought of as building blocks that are combined together to form playbooks or specify actions for ad-hoc commands, which are then used to automate tasks on one or more remote hosts. Modules can be written in any programming language and are responsible for defining the tasks that are carried out during an Ansible playbook run.
We’ll go through some of the most frequently used modules.
File #
The file module is used to manage files and directories on remote hosts. This module can be used to create, modify, and delete files and directories, as well as change file permissions and ownership.
The following example creates a specific file on a remote host:
- name: Create file
hosts: webservers
tasks:
- name: Create file with specific content
file:
path: /var/www/html/index.html
state: touch
owner: apache
group: apache
mode: '0644'
content: "<html><head><title>Hello World</title></head><body><h1>Hello World</h1></body></html>"Copy #
The copy module is used to copy files from the Ansible control machine to one or more remote hosts. This module can also be used to set file permissions and ownership.
The following example copies a file to a remote host:
- name: Copy file
hosts: webservers
tasks:
- name: Copy file to remote host
copy:
src: /path/to/local/file
dest: /path/to/remote/file
owner: apache
group: apache
mode: '0644'Yum & APT #
The yum and APT modules are used to manage packages on remote hosts. This includes installing, updating or removing packages. Yum is used for RHEL based distributions, APT is used for Debian based distributions.
An example using Yum:
- name: Install package
hosts: webservers
tasks:
- name: Install package using YUM
yum:
name: httpd
state: presentService #
The service module is used to manage services on remote hosts. This module can be used to start, stop, restart, and enable/disable services.
The following example starts a service on a remote host:
- name: Start service
hosts: webservers
tasks:
- name: Start service on remote host
service:
name: httpd
state: startedShell #
The shell module is used to execute arbitrary shell commands on remote hosts. This module can be used to run complex commands that cannot be handled by other Ansible modules.
The following example runs a shell command on a remote host:
- name: Run command
hosts: webservers
tasks:
- name: Run command on remote host
shell: ls -la /var/www/htmlTemplate #
The template module is used to generate files from templates on the Ansible control machine and copy them to one or more remote hosts. This module can be used to create configuration files that are customized for each remote host.
The following example generates a file from a template and copies it to the remote host:
- name: Generate file
hosts: webservers
tasks:
- name: Generate file from template and copy to remote host
template:
src: /path/to/template.conf.j2
dest: /etc/httpd/conf.d/custom.confLineinfile #
The lineinfile module can be used to add a line to a specific file on the target’s filesystem.
An example:
- name: Add a line to a file
lineinfile:
path: /etc/hosts
line: 192.168.1.99 foo.lab.net fooOther modules? #
The ansible Galaxy contains more than 700 different modules. Not all modules are installed on an ansible controller by default.
You can install non-default modules using the ansible-galaxy command:
ansible-galaxy collection install cisco.iosYou can find an overview of all modules in the Ansible Galaxy