Skip to content

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.cfg
  • inventory
  • ssh.config

What will we learn?

  • How to create and configure ansible.cfg
  • How to set up an Ansible inventory file
  • How to configure ssh.config for Ansible
  • How to verify Ansible configuration and connectivity

Prerequisites

  • Complete the previous lab in order to have the Ansible controller and the Linux servers up and running.

01. Create configuration files

IMPORTANT!

  • In this lab we will be placing the files under the /labs-scripts directory.
  • The directory is mounted to our docker container(s) under the <PROJECT_ROOT>/runtime directory.
  • You are encouraged to review the docker-compose.yaml file throughout the lab session.

02. About ansible.cfg file

  • What is ansible.cfg ?
  • The ansible.cfg file 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.cfg file 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.cfg file, the ssh.config file and the inventory file.

03. ansible.cfg locations:

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_CONFIG is set in the docker container path /labs-scripts/.ansible.cfg

04. ansible.cfg structure:

  • The ansible.cfg file is divided into sections, each containing various customizable parameters.

  • Main ansible.cfg settings:

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.
    [callback_plugins]
        stdout_callback     =    yaml
        callback_whitelist  =    timer, profile_tasks
    

[connection]

  • The [connection] section defines general connection settings that apply to all connection types.
    [connection]
        pipelining          =    True
        control_path_dir    =    ~/.ansible/cp
    

[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.
[diff]
    always              =    True
    context             =    5

[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.
[galaxy]
    server_list         =    release_galaxy
    cache_dir           =    ~/.ansible/galaxy_cache

[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 INI files, YAML files, 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 in ansible.cfg.
  • Instead, logging is typically configured under the [defaults] section using the log_path directive.
  • log_path controls where Ansible logs its output.
  • If log_path is 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:
    [defaults]
        log_path            =     /var/log/ansible.log
        log_level           =     info
        log_format          =     default
        log_date_format     =     iso8601
        log_ansi            =     True
        log_color           =     auto
        log_file            =     /var/log/ansible.log
        log_rotate          =     True
        log_max_size        =     10485760
        log_compress        =     True
        log_backup_count    =     5
        log_http            =     False
        log_json            =     True
    

[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 keys
  • banner_timeout - Specifies the timeout for receiving the SSH banner.
  • keepalive - If set to true, keepalive messages will be sent to
[paramiko_connection]
    pty                 =    False
    look_for_keys       =    True

[privilege_escalation]

  • The [privilege_escalation] section defines settings related to privilege escalation (such as sudo or become).
  • The become directive 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_args can be used to pass additional options to the SSH command.
  • pipelining can be enabled to reduce the number of SSH connections.
  • scp_if_ssh specifies whether to use SCP for 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.
[winrm]
    transport           =    basic
    cert_validation     =    ignore

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.cfg which 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 SSH protocol, 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.config configuration 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 file that lists and categorizes the hosts Ansible will manage.
  • It provides a structured way to define hosts and groups, 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 hosts and groups.
  • The inventory is written using the INI format.
  • inventory can be written in other formats as well, such as YAML and Dynamic Inventory which dynamically configure the inventory with scripts.
  • The default location for this file is /etc/ansible/hosts.
  • If /etc/ansible/hosts doesn’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 the ANSIBLE_INVENTORY environment 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 a host 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-xx part.
  • 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] - all is a special group that points to all nodes described in the inventory. - The [all:vars] & group variables are defined for the group all. - When we use a group, we can use the whole group as “hosts” for ansible. - A magic variable, represented by ansible_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


09. Test Ansible configuration

  • Now we are ready to start play with Ansible!

  • The first step is to test Ansible configuration

# Verify that Ansible is installed correctly
docker exec ansible-controller ansible --version
  • 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:
    config file = /labs-scripts/ansible.cfg
    

10. Basic ansible configuration

  • Once all is ready, lets check if the controller can connect to the servers with the Ansible ping command.
  • ping is an Ad-Hoc Ansible 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 --version confirms the installed version and active configuration file
  • The ansible.cfg file sets defaults: inventory path, remote user, private key, and SSH options
  • The ping module tests SSH connectivity and Python availability on managed hosts - no packages needed on targets
  • ansible-inventory --list validates the inventory and shows all host variables in JSON format
  • A successful pong response confirms Ansible can authenticate, connect, and execute modules on the target host