Describe where Ansible configuration files are located, how Ansible selects them, and edit them to apply changes to default settings.
You can create and edit two files in each of your Ansible project directories that configure the behavior of Ansible and the ansible-navigator command:
ansible.cfg, which configures the behavior of several Ansible tools.
ansible-navigator.yml, which changes default options for the ansible-navigator command.
You can create an ansible.cfg file in your Ansible project's directory to apply settings that apply to multiple Ansible tools.
The Ansible configuration file consists of several sections, with each section containing settings defined as key-value pairs. Section titles are enclosed in square brackets. For basic operation, use the following two sections:
[defaults], which sets defaults for Ansible operation
[privilege_escalation], which configures how Ansible performs privilege escalation on managed hosts
For example, the following is a typical ansible.cfg file:
[defaults] inventory = ./inventory remote_user = user ask_pass = false [privilege_escalation] become = true become_method = sudo become_user = root become_ask_pass = false
The following table explains these parameters:
| Directive | Description |
|---|---|
inventory
| Specifies the path to the inventory file. |
remote_user
| Specifies the username that Ansible uses to connect to the managed hosts.
If not specified, the current user's name is used.
(In a container-based automation execution environment run by ansible-navigator, this is always root.) |
ask_pass
| Specifies whether to prompt for an SSH password.
(Can be false, which is the default, if using SSH public key authentication.) |
become
| Specifies whether to automatically switch users on the managed host (typically to root) after connecting.
This can also be specified by a play. |
become_method
| Specifies how to switch users (typically sudo, which is the default, but su is an option). |
become_user
| Specifies which user to switch to on the managed host (typically root, which is the default). |
become_ask_pass
| Specifies whether to prompt for a password for the become_method parameter.
Defaults to false. |
The ansible-navigator config command displays the current Ansible configuration.
The command displays the actual value that Ansible uses for each parameter and from which source it retrieves that value, configuration file, or environment variable.
The following output is from the ansible-navigator config command run from a /home/student/project/ directory that contains an ansible.cfg file:
Name Default Source Current ...output omitted... 44│Default ask pass True default False 45│Default ask vault pass True default False 46│Default become False /home/student/project/ansible.cfg True 47│Default become ask pass False /home/student/project/ansible.cfg True ...output omitted... 50│Default become method False /home/student/project/ansible.cfg sudo 51│Default become user False /home/student/project/ansible.cfg root ...output omitted...
In the preceding example, each line describes an Ansible configuration parameter.
The Default ask pass and Default ask vault pass parameters use their default values, indicated by the True value in the Default column.
The Default become and Default become ask pass parameters have been manually configured to True in the /home/student/project/ansible.cfg configuration file.
The Default column is False for these two parameters.
The Source column provides the path to the configuration file which defines these parameters, and the Current column shows that the value for these two parameters is True.
The Default become method parameter has the current value of sudo, and the Default become user parameter has the current value of root.
To exit the interactive mode of the ansible-navigator config command, press Esc or type :q.
If the project does not include an ansible.cfg file, then Ansible tries to use a ~/.ansible.cfg file in the home directory of the user running Ansible, and if that does not exist, it tries to use an /etc/ansible/ansible.cfg file.
However, if you are using ansible-navigator, the ansible-navigator command looks for these files inside the automation execution environment.
On the current Red Hat-supported execution environments, these files do not exist or are empty.
If you are using the earlier ansible-playbook command or other Ansible commands that do not use automation execution environments, then Ansible looks for these files on your workstation.
You can create a configuration file (or settings file) for ansible-navigator to override the default values of its configuration settings.
The settings file can be in JSON (.json) or YAML (.yml or .yaml) format.
This discussion focuses on the YAML format.
Automation content navigator looks for a settings file in the following order and uses the first file that it finds:
If the ANSIBLE_NAVIGATOR_CONFIG environment variable is set, then use the configuration file at the location it specifies.
An ansible-navigator.yml file in your current Ansible project directory.
A ~/.ansible-navigator.yml file (in your home directory).
Notice that it has a "dot" at the start of its file name.
Just like the Ansible configuration file, each project can have its own automation content navigator settings file.
The following ansible-navigator.yml file configures some common settings:
ansible-navigator: execution-environment:image: utility.lab.example.com/ee-supported-rhel8:latest
pull: policy: missing
playbook-artifact: enable: false
The | |
The | |
The | |
The |
More complex configurations for automation content navigator are covered in the course Developing Advanced Automation with Red Hat Ansible Automation Platform (DO374). See https://ansible-navigator.readthedocs.io/en/latest/settings/ for more documentation on the settings that you can use in this file.
Ansible needs to know how to communicate with its managed hosts. One of the most common reasons to change the configuration file is to control which methods and users Ansible uses to administer managed hosts. The following are some examples of required information:
The location of the inventory that lists the managed hosts and host groups
The connection protocol to use to communicate with the managed hosts (by default, SSH), and whether a nonstandard network port is needed to connect to the server
The remote user to use on the managed hosts; this could be root or it could be an unprivileged user
If the remote user is unprivileged, Ansible needs to know if it should try to escalate privileges to root and how to do it (for example, by using sudo)
Whether to prompt for an SSH password or sudo password to log in or gain privileges
In the [defaults] section of the ansible.cfg file, the inventory parameter can point directly to a static inventory file, or to a directory containing multiple static inventory files and dynamic inventory scripts.
[defaults] inventory = ./inventory
By default, Ansible connects to managed hosts using the SSH protocol.
The most important parameters that control how Ansible connects to the managed hosts are set in the [defaults] section.
If not configured otherwise, Ansible attempts to connect to the managed host using the same username as the local user running the Ansible commands.
To specify a different remote user, set the remote_user parameter to that username.
If the local user running Ansible has private SSH keys configured that allow them to authenticate as the remote user on the managed hosts, Ansible automatically logs in.
If you do not have SSH key-based authentication configured for your remote user, it is possible to use password-based authentication.
However, to use password-based SSH authentication with ansible-navigator, you need to configure ansible-navigator so that it does not generate playbook artifacts (log files that record information about playbook runs).
The following example is a minimal ansible-navigator.yml file that disables the generation of playbook artifacts:
ansible-navigator:
playbook-artifact:
enable: falseWith this configuration, you can run ansible-navigator run with the -m stdout and --ask-pass options in addition to the playbook that you want to run, so that the ansible-navigator command prompts you for the remote user's SSH password.
You can set the ask_pass = true parameter in the defaults section of the ansible.cfg file so that you are always prompted by Ansible tools for the SSH password.
If you do not disable playbook artifact generation for ansible-navigator, or if you do not use -m stdout when running ansible-navigator, the ansible-navigator command might hang or otherwise fail to run.
If you have password-based SSH authentication set up, you can configure key-based SSH authentication.
The first step is to make sure that the user on the control node has an SSH key pair configured in ~/.ssh.
You can run the ssh-keygen command to generate a key pair.
For a single existing managed host, you can install your public key on the managed host and use the ssh-copy-id command to populate your local ~/.ssh/known_hosts file with its host key, as follows:
[user@controlnode ~]$ssh-copy-id root@web1.example.comThe authenticity of host 'web1.example.com (192.168.122.181)' can't be established. ECDSA key fingerprint is 70:9c:03:cd:de:ba:2f:11:98:fa:a0:b3:7c:40:86:4b. Are you sure you want to continue connecting (yes/no)?yes/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@web1.example.com's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'root@web1.example.com'" and check to make sure that only the key(s) you wanted were added.
You can also use an Ansible Playbook to deploy your public key to the remote_user account on all managed hosts using the authorized_key module.
This course has not covered Ansible Playbooks in detail yet.
A play that ensures that your public key is deployed to the managed hosts' root accounts might read as follows:
- name: Public key is deployed to managed hosts for Ansible
hosts: all
tasks:
- name: Ensure key is in root's ~/.ssh/authorized_hosts
ansible.posix.authorized_key:
user: root
state: present
key: '{{ item }}'
with_file:
- ~/.ssh/id_rsa.pubBecause the managed host would not have SSH key-based authentication configured yet, you would have to run the playbook using the ansible-navigator run command with the --ask-pass option for the command to authenticate as the remote user.
For security and auditing reasons, Ansible might need to connect to remote hosts as an unprivileged user before escalating privileges to get administrative access as the root user.
This can be set up in the [privilege_escalation] section of the Ansible configuration file.
To enable privilege escalation by default, set the become = true parameter in the configuration file.
Even if this is set by default, various methods exist to override it when running ad hoc commands or Ansible Playbooks.
(For example, there might be times when you want to run a task or play that does not escalate privileges.)
The become_method parameter specifies how to escalate privileges.
Several options are available, but the default is to use sudo.
Likewise, the become_user parameter specifies which user to escalate to, but the default is root.
If the become_method mechanism chosen requires the user to enter a password to escalate privileges, you can set the become_ask_pass = true parameter in the configuration file.
If you have become_ask_pass = true set when you use ansible-navigator, you also need to disable playbook artifact generation and use -m stdout as previously discussed in this section.
On Red Hat Enterprise Linux 8 and 9, the default configuration of /etc/sudoers grants all users in the wheel group the ability to use sudo to become root after entering their password.
One way to enable a user (someuser in the following example) to use sudo to become root without a password is to install a file with the appropriate parameters into the /etc/sudoers.d directory (owned by root, with octal permissions 0400):
## password-less sudo for Ansible user someuser ALL=(ALL) NOPASSWD:ALL
Think through the security implications of whatever approach you choose for privilege escalation. Different organizations and deployments might have different tradeoffs to consider.
The following example ansible.cfg file assumes that you can connect to the managed hosts as someuser using SSH key-based authentication, and that someuser can use sudo to run commands as root without entering a password:
[defaults] inventory = ./inventory remote_user = someuser ask_pass = false [privilege_escalation] become = true become_method = sudo become_user = root become_ask_pass = false
Setting become = true means that all tasks in the plays in playbooks that you run are run as the user specified by the become_user parameter, usually the root user.
From a security perspective, rather than setting become = true in the ansible.cfg file, it might be a better practice to configure privilege escalation for specific plays in your playbooks, or on a task-by-task basis as needed.
Both the ansible.cfg file and ansible-navigator.yml support the number sign (#) at the start of a line as a comment character.
The number sign at the start of a line comments out the entire line.
In addition, the ansible.cfg file supports the semicolon (;) as a comment character.
The semicolon character comments out everything to the right of it on the line.