Introduction
Ansible can be installed correctly yet use the wrong inventory, interpreter or privileges. A reliable project makes those choices explicit and confirms their effect on real targets.
In this lab, you will create a project configuration, inspect its loaded values, set target Python through inventory, and compare ordinary execution with explicit privilege escalation on two prepared SSH nodes. This independent environment supplies Ansible and connections; no package installation or SSH-server changes are needed.
Create and Load Project Configuration
In this step, you will create a project configuration and confirm that Ansible actually loads it.
You already installed Ansible in the preceding lab. This independent environment supplies the shared course installation so you can focus on configuration. Open the Terminal and select the workspace:
cd /home/labex/project
Ansible uses one configuration file, choosing the first available from ANSIBLE_CONFIG, the current directory's ansible.cfg, the user's home configuration, and the system configuration. Changing directories can therefore change which project configuration is loaded. An environment variable can select a different file even when a project file exists.
The prepared connection-reference.cfg contains the original training connection settings. cat displays it:
cat connection-reference.cfg
It selects the project inventory and a trusted host-key file. The lab has already created the keys and nodes; do not change your platform login or SSH server.
Create ansible.cfg below. cat > writes standard input to a file, replacing existing content. <<'EOF' starts a here-document: paste all lines through the final EOF. Quoting the marker keeps the text literal. INI section names in brackets group settings, and each name = value line sets an option.
cat > ansible.cfg <<'EOF'
[defaults]
inventory = /home/labex/project/inventory.ini
host_key_checking = True
interpreter_python = /usr/bin/python3
[privilege_escalation]
become = False
[ssh_connection]
ssh_args = -o UserKnownHostsFile=/home/labex/.local/share/ansible-course/known_hosts -o StrictHostKeyChecking=yes -o ControlMaster=auto -o ControlPersist=30s
EOF
inventory selects the host list. host_key_checking keeps server identity checks enabled. interpreter_python sets the default target Python, not the controller interpreter. become = False keeps ordinary tasks unprivileged. The prepared ssh_args use the training known_hosts file, require trusted keys and reuse short-lived SSH connections.
Display version and configuration information:
ansible --version
Find config file = /home/labex/project/ansible.cfg. The module path belongs to the shared course installation in this lab; your preceding installation exercise used a separate learner environment.
ansible-config dump shows effective configuration. --only-changed limits it to non-default settings and identifies where each came from:
ansible-config dump --only-changed
Look for CONFIG_FILE() = /home/labex/project/ansible.cfg, a project DEFAULT_HOST_LIST, and INTERPRETER_PYTHON set to /usr/bin/python3. The output uses internal option names that can differ from INI spelling. Reading a file alone does not prove Ansible loaded it.
Test the project configuration with the Python ping module you already know:
ansible all -m ansible.builtin.ping
Both web1 and web2 should return pong. Keep commands in this workspace so the intended configuration remains active.
Set the Target Interpreter in Inventory
In this step, you will set a connection variable for both hosts and understand how it relates to the project default.
Read the prepared inventory:
cat inventory.ini
It has two distinct ansible_host destinations followed by [all:vars]. Settings after that section apply to both hosts, including ansible_user=automation and the training private-key path. These describe the SSH account and authentication on the managed nodes.
A connection variable named ansible_python_interpreter overrides the interpreter_python configuration default for its hosts. Use it when an inventory needs a specific target interpreter. A correct default cannot rescue an inventory variable pointing to a missing executable.
printf prints text; \n means a newline. >> appends without replacing the existing inventory. Append the interpreter variable under the existing [all:vars] section:
printf '\nansible_python_interpreter=/usr/bin/python3\n' >> inventory.ini
Display the inventory again and find the new setting beneath [all:vars]:
cat inventory.ini
The controller's Python installation remains unchanged. This path will be executed separately inside each managed node. Test both targets:
ansible all -m ansible.builtin.ping
Each should still return pong and changed: false. You now have a working per-inventory interpreter setting as well as a project default. Configuration output describes defaults; connection variables may override them during execution.
Compare Ordinary and Elevated Execution
In this step, you will observe the actual remote user before and after explicit privilege escalation.
The command module runs a program on the target. -a supplies module arguments; quote id -un so the shell passes the program and its option as one argument string. id -un prints the effective user's name:
ansible all -m ansible.builtin.command -a 'id -un'
Both hosts should report automation. This is the managed-node account selected by the inventory, not the controller's labex user.
--become requests privilege escalation for this invocation. The training nodes allow the automation account to use sudo without a password; your project default still keeps escalation off for ordinary runs:
ansible all -m ansible.builtin.command -a 'id -un' --become
Both hosts should report root. Ansible's command module normally reports CHANGED when it runs a command, even for this read-only identity query. That label alone does not prove a system configuration changed; interpret the actual stdout and return status.
Repeat without --become:
ansible all -m ansible.builtin.command -a 'id -un'
The output returns to automation. Escalation was explicit for one invocation, rather than a permanent change to the login account. Leave global escalation disabled and keep the platform account configuration unchanged.
Summary
You created and loaded a project configuration, inspected effective defaults, and supplied a higher-priority target interpreter through inventory. Real SSH module execution confirmed both targets, and identity queries demonstrated the difference between ordinary automation access and explicit become. These checks provide a foundation for diagnosing connection settings without changing platform access.



