Verify Ansible Configuration¶
- In this lab we will create the Ansible configuration and verify that it is configured correctly.
- This lab is based upon the previous lab and its
docker-compose. - In this lab we will learn how to use:
ansible.cfginventoryssh.config
What will we learn?¶
- How to create and configure
ansible.cfg - How to set up an Ansible
inventoryfile - How to configure
ssh.configfor Ansible - How to verify Ansible configuration and connectivity
Prerequisites¶
- Complete the previous lab in order to have the
Ansiblecontroller and theLinuxservers up and running.
01. Create configuration files¶
IMPORTANT!
- In this lab we will be placing the files under the
/labs-scriptsdirectory. - The directory is mounted to our docker container(s) under the
<PROJECT_ROOT>/runtimedirectory. - You are encouraged to review the
docker-compose.yamlfile throughout the lab session.
02. About ansible.cfg file¶
- What is
ansible.cfg? - The
ansible.cfgfile is an INI-like configuration file used to define various settings and parameters that influence how Ansible operates. - It allows users to customize Ansible’s behavior, such as specifying inventory locations, default module settings, connection options, and more.
- The
ansible.cfgfile can be placed in several locations, and Ansible will search for it in a specific order. - The configuration file is divided into sections, each containing various customizable parameters that control different aspects of Ansible’s functionality.
- Below we will create the
ansible.cfgfile, thessh.configfile and theinventoryfile.
03. ansible.cfg locations:¶
- Reference: Official Ansible documentation: - Ansible Configuration Settings
- Ansible searches
ansible.cfgin a specific order. - The first file it finds will be used while ignoring the rest.
- Ansible will search for the configuration file in the following order:
| Search resource | Description |
|---|---|
ANSIBLE_CONFIG | environment variable if set |
ansible.cfg | In the current directory |
~/.ansible.cfg | Under the home directory |
/etc/ansible/ansible.cfg | OS common path |
- In this exercise the environment variable
ANSIBLE_CONFIGis set in the docker container path/labs-scripts/.ansible.cfg
04. ansible.cfg structure:¶
-
The
ansible.cfgfile is divided into sections, each containing various customizable parameters. -
Main
ansible.cfgsettings:
| Setting | Description | Ansible Docs |
|---|---|---|
| [callback_plugins] | Specifies directories for callback plugins that customize output or trigger actions. | Docs |
| [connection] | Defines general connection settings that apply to all connection types. | Docs |
| [defaults] | Contains general settings for Ansible such as inventory location, verbosity, and log settings. | Docs |
| [diff] | Controls whether Ansible shows differences when applying configurations. | Docs |
| [galaxy] | Configures settings for Ansible Galaxy, a hub for sharing roles and collections. | Docs |
| [inventory] | Defines options related to inventory parsing and caching. | Docs |
| [logging] | Logging configuration, typically under [defaults] section using log_path. | Docs |
| [paramiko_connection] | Configures settings specific to the Paramiko SSH library. | Docs |
| [privilege_escalation] | Defines settings related to privilege escalation, such as sudo or become. | Docs |
| [ssh_connection] | Settings for SSH connections, (timeout, control settings etc). | Docs |
| [winrm] | Configures settings for Windows Remote Management (WinRM) connections. | Docs |
[callback_plugins]¶
- The
[callback_plugins]section specifies directories where Ansible looks for callback plugins, which can customize output or trigger actions based on playbook events.
[connection]¶
- The
[connection]section defines general connection settings that apply to all connection types.
[defaults]¶
- The
[defaults]section contains the general settings for Ansible (such as inventory location, verbosity and log settings). - It is the most commonly used section and is often the first place users look to customize their Ansible environment.
- Here are some commonly used settings in the
[defaults]section: ask_pass- If set to true, Ansible will prompt for the SSH password.host_key_checking- If set to false, Ansible will not check SSH host keys.inventory- Specifies the path to the inventory file.log_path- Specifies the path to the log file.remote_user- Specifies the default remote user for SSH connections.timeout- Specifies the timeout for SSH connections in seconds.private_key_file- Specifies the path to the private key file for SSH authentication.become- If set to true, privilege escalation (e.g., sudo) will be used.become_method- Specifies the method to use for privilege escalation (e.g., sudo, su).become_user- Specifies the user to become when using privilege escalation.retry_files_enabled- If set to false, Ansible will not create retry files.gathering- Specifies how facts are gathered (e.g., smart, explicit, none).
[defaults]
ask_pass = false
host_key_checking = false
inventory = /etc/ansible/hosts
log_path = /var/log/ansible.log
remote_user = ansible
timeout = 30
[diff]¶
- Controls whether Ansible shows differences when applying configurations.
- This can be useful for debugging and understanding changes.
always- Show differences even when the playbook is not run in check mode.context- The number of lines of context to show around changes.ignore- Do not show differences.diff- Show a unified diff of changes.unified- Show a unified diff of changes with context lines.
[galaxy]¶
- The
[galaxy]section configures settings for Ansible Galaxy, which is a hub for sharing and downloading Ansible roles and collections. - This section can be used to specify custom Galaxy servers, caching options, and other related settings.
- Here is an example configuration for the
[galaxy]section: server_list- Specifies the list of Galaxy servers to use.cache_dir- Specifies the directory to cache downloaded roles and collections.role_file- Specifies the path to the file containing role definitions.collection_file- Specifies the path to the file containing collection definitions.requirements_file- Specifies the path to the file containing Galaxy requirements.role_file- Specifies the path to the file containing role definitions.
[inventory]¶
- Defines options related to inventory parsing and caching.
- Inventory is a critical component of Ansible, as it defines the hosts and groups of hosts that Ansible will manage.
- The inventory can be specified in various formats, including
INIfiles,YAMLfiles, and dynamic inventory scripts. - The inventory can also be cached to improve performance.
- Here are some commonly used settings in the
[inventory]section: enable_plugins- Specifies the inventory plugins to use.cache- If set to true, inventory caching will be enabled.cache_plugin- Specifies the inventory cache plugin to use.cache_timeout- Specifies the timeout for inventory caching in seconds.inventory_ignore_extensions- Specifies file extensions to ignore when loading inventory files.inventory_loader- Specifies the inventory loader to use.strict- If set to true, Ansible will enforce strict inventory parsing.host_key_checking- If set to true, Ansible will check SSH host keys for inventory hosts.enable_inventory_cache- If set to true, inventory caching will be enabled.inventory_cache_timeout- Specifies the timeout for inventory caching in seconds.inventory_cache_connection- Specifies the connection string for the inventory cache plugin.
[inventory]
enable_plugins = host_list, ini, auto
cache = True
cache_plugin = memory
cache_timeout = 3600
[logging]¶
- Ansible does not have a dedicated
[logging]section inansible.cfg. - Instead, logging is typically configured under the
[defaults]section using thelog_pathdirective. log_pathcontrols where Ansible logs its output.- If
log_pathis set, Ansible will write logs to the specified file, where as if it is not set, or left empty, logging will be disabled. - Here is an example of how to configure logging in the
[defaults]section:
[paramiko_connection]¶
- The
[paramiko_connection]section configures settings specific to the Paramiko SSH library, an alternative to OpenSSH for SSH connections. - Here are some commonly used settings in the
[paramiko_connection]section: pty- If set to true, a pseudo-terminal will be allocated for the connection.look_for_keys- If set to true, Paramiko will look for SSH keysbanner_timeout- Specifies the timeout for receiving the SSH banner.keepalive- If set to true, keepalive messages will be sent to
[privilege_escalation]¶
- The
[privilege_escalation]section defines settings related to privilege escalation (such assudoorbecome). -
The
becomedirective is used to enable privilege escalation. -
Here are some commonly used settings in the
[privilege_escalation]section: become- If set to true, privilege escalation will be used.become_method- Specifies the method to use for privilege escalation (e.g., sudo, su).become_user- Specifies the user to become when using privilege escalation.become_ask_pass- If set to true, Ansible will prompt for the privilege escalation password.become_flags- Specifies any additional flags to pass to the privilege escalation command.become_exe- Specifies the path to the privilege escalation executable.become_pass- Specifies the password to use for privilege escalation.
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
[ssh_connection]¶
- Settings for SSH connections, (timeout, control settings etc).
- ControlMaster and ControlPersist options are used for SSH multiplexing, allowing multiple SSH sessions to share a single connection.
ssh_argscan be used to pass additional options to the SSH command.pipeliningcan be enabled to reduce the number of SSH connections.scp_if_sshspecifies whether to useSCPfor file transfers when using SSH.
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = True
scp_if_ssh = True
[winrm]¶
- The
[winrm]section configures settings for Windows Remote Management (WinRM) connections, used for managing Windows hosts. - Here are some commonly used settings in the
[winrm]section: transport- Specifies the transport method to use (e.g., basic, ntlm).cert_validation- Controls certificate validation (e.g., ignore, validate).read_timeout_sec- Specifies the read timeout for WinRM connections in seconds.operation_timeout_sec- Specifies the operation timeout for WinRM connections in seconds.max_retries- Specifies the maximum number of retries for WinRM connections.retry_delay- Specifies the delay between retries for WinRM connections.
05. Auto Generate ansible.cfg¶
- You can choose to execute
ansible-config init, which will generate a sample Ansible configuration file. - As this is the main configuration file for our demo application, it is the content of
ansible.cfgwhich we will use in this lab.
# File location: $RUNTIME_FOLDER/labs-scripts/ansible.cfg.
# This is the default location of the inventory file, script, or directory that
Ansible will use to determine what hosts it has available to talk to.
# Defines that the inventory info is in a file named “inventory”.
[defaults]
inventory = inventory
# Specifies remote hosts, so we do not need to config them in main SSH config.
[ssh_connection]
transport = ssh
transfer_method = scp
# The location of the SSH config file.
# We will create this file in our next step.
ssh_args = -F ssh.config \
-o ControlMaster=auto \
-o ControlPersist=60s \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/root/.ssh/known_hosts
06. Create the ssh.config file¶
- Ansible operates in Linux environments using
SSHprotocol, in order to run Ansible playbooks. - By default, Ansible uses the default SSH keys, unless provided with an SSH configuration file.
- Ansible ssh.config file allows you to define custom SSH settings for connecting to remote hosts.
- In this demo we will use our own
ssh.configconfiguration file.
# File location: $RUNTIME_FOLDER/labs-scripts/ssh.config
# Set up the desired hosts
# keep in mind that we have set up the hosts in the docker-compose
Host *
# Disable host key checking
# Avoid asking for the key-print authenticity
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
# Enable hashing known_host file
HashKnownHosts yes
# IdentityFile allows to specify private keys we wish to use for authentication
# Authentication = the process of authentication
# We will use the auto-generated SSH keys from our Docker container
# List the desired servers
# The hosts are defined in the docker-compose which we created in the setup lab
Host linux-server-1
HostName linux-server-1
IdentityFile /root/.ssh/linux-server-1
User root
Port 22
Host linux-server-2
HostName linux-server-2
IdentityFile /root/.ssh/linux-server-2
User root
Port 22
Host linux-server-3
HostName linux-server-3
IdentityFile /root/.ssh/linux-server-3
User root
Port 22
07. Create the inventory file¶
- See Ansible documentation: How to build your inventory.
- An Ansible inventory file is a
configuration filethat lists and categorizes the hosts Ansible will manage. - It provides a structured way to define
hostsandgroups, enabling efficient targeting and execution of tasks on specific hosts or groups of hosts. - The simplest inventory is a single file with a list of
hostsandgroups. - The inventory is written using the
INIformat. inventorycan be written in other formats as well, such asYAMLandDynamic Inventorywhich dynamically configure the inventory with scripts.- The default location for this file is
/etc/ansible/hosts. - If
/etc/ansible/hostsdoesn’t exists, ansible will look for user specific inventory file, to be placed at$HOME/.ansible/hosts - You can specify a different inventory file at the command line using the
-i <path>inventory option when executing Ansible commands or by exporting theANSIBLE_INVENTORYenvironment variable. - Using
-i <path>inventory option takes precedence over environment variable. - The inventory configuration we will use for the labs:
# File location: $RUNTIME_FOLDER/labs-scripts/inventory
# List of servers which we want ansible to connect to
# The names are defined in the docker-compose
[servers]
linux-server-1 ansible_ssh_common_args='-o UserKnownHostsFile=/root/.ssh/known_hosts'
linux-server-2 ansible_ssh_common_args='-o UserKnownHostsFile=/root/.ssh/known_hosts'
linux-server-3 ansible_ssh_common_args='-o UserKnownHostsFile=/root/.ssh/known_hosts'
[all:vars]
# Extra "global" variables for the inventory
This inventory file is written following these rules:
- Information is described by one node per line, such as
linux-server-xx. - A node line consists of an
identifier of the node (ex. linux-server-X)and ahost variable(s) (ex. ansible_host=xxxx), to be given to the node . - You can also specify an IP address or FQDN for the
linux-server-xxpart. - You can create a group of hosts with
[group_name]. In our inventory the group name is[servers]. -
You can use any group name except
[all]and[localhost](e.g.,[webservers]or[databases]can be used as group names for servers).[all]-allis a special group that points to all nodes described in the inventory. - The[all:vars]&group variablesare defined for the groupall. - When we use a group, we can use the whole group as “hosts” for ansible. - A magic variable, represented byansible_xxxx, contains special values that control Ansible’s behavior and environment information that Ansible will automatically retrieve. - Details are explained in the variables section.
08. Prepare for execution¶
- Place the files under the shared folder or simply execute the script /Labs/000-setup/02-init-ansible.sh
- Verify that the controller can execute ansible /Labs/000-setup/01-init-servers.sh
09. Test Ansible configuration¶
-
Now we are ready to start play with
Ansible! -
The first step is to test
Ansibleconfiguration
- Sample output
ansible [core 2.17.9]
config file = /labs-scripts/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.12.3 (main, Feb 4 2025, 14:48:35) [GCC 13.3.0] (/usr/bin/python3)
jinja version = 3.1.2
libyaml = True
- We are looking for the following line:
10. Basic ansible configuration¶
- Once all is ready, lets check if the controller can connect to the servers with the Ansible
pingcommand. pingis anAd-HocAnsible command that we will cover later on.
# Ping the servers and check that they are "alive"
docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m ping"
### Output
* Executing: ansible all -m ping
linux-server-2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
linux-server-1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
linux-server-3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
11. Summary¶
ansible --versionconfirms the installed version and active configuration file- The
ansible.cfgfile sets defaults: inventory path, remote user, private key, and SSH options - The
pingmodule tests SSH connectivity and Python availability on managed hosts - no packages needed on targets ansible-inventory --listvalidates the inventory and shows all host variables in JSON format- A successful
pongresponse confirms Ansible can authenticate, connect, and execute modules on the target host