skip to content

You add a host to an Ansible inventory under a friendly alias that does not resolve in DNS; it answers SSH on port 2222 as the user `deploy`. Which inventory variables make that work?

level: middleimportance: should knowfreq 58%

answer

  1. the inventory name is only a label
  2. something else says where to dial
  3. port and login user are variables too
  4. one variable picks the transport plugin
  5. another points at the target's Python

basics

~20 s

Set ansible_host to the real address or DNS name, ansible_port to 2222 and ansible_user to deploy. The inventory name stays a label used in patterns and for the host_vars filename; ansible_host is what Ansible actually connects to.

solid answer

~40 s

The inventory name is just a label — it is what patterns match, what `host_vars/<name>.yml` keys off, and what shows up in output. What Ansible dials is `ansible_host`, so I write `web01 ansible_host=10.2.0.7` and add `ansible_port: 2222` and `ansible_user: deploy`. Those are ordinary variables, so they can live inline in the inventory, in `host_vars/web01.yml`, or in a `group_vars` file when a whole group shares them — which is the usual case for a bastion-fronted or non-standard-port fleet. The same family covers the rest of the connection: `ansible_connection` selects the transport (`ssh` by default, `local`, `winrm` for Windows), `ansible_ssh_private_key_file` picks the key, and `ansible_python_interpreter` points at the interpreter when the target's default is missing or wrong.

code

yaml · 8 lines
yaml
webservers:
  hosts:
    web01:
      ansible_host: 10.2.0.7
      ansible_port: 2222
      ansible_user: deploy
      ansible_ssh_private_key_file: ~/.ssh/deploy_ed25519
      ansible_python_interpreter: /usr/bin/python3

go deeper

for a junior

Be able to say that ansible_host holds the real address while the inventory name is just a label, and that ansible_user and ansible_port set the login user and SSH port.

for a middle

Explain that these are ordinary variables, so shared ones belong in a group file, and name the wider family including ansible_connection and ansible_python_interpreter.

for a senior

Demonstrate that connection detail belongs in the reviewed inventory rather than a laptop's SSH config, and that you debug it with -m ping -vvv or ansible-inventory --host.

for a principal

Own the convention for how hosts are addressed across the estate — stable aliases versus raw addresses, where transport defaults live, and how credentials reach a pipeline without personal local state.

## The inventory name is a label, not an address Every inventory entry has a name. That name is what host patterns match, what `host_vars/<name>.yml` is keyed on, what appears in play output, and what `--limit` accepts. It is *not* necessarily how Ansible reaches the machine. If the name happens to resolve in DNS, Ansible will connect to it; otherwise you must say where the host actually is: ```ini [webservers] web01 ansible_host=10.2.0.7 ansible_port=2222 ansible_user=deploy ``` or in YAML: ```yaml webservers: hosts: web01: ansible_host: 10.2.0.7 ansible_port: 2222 ansible_user: deploy ``` Using stable aliases with `ansible_host` carrying the volatile address is good practice: the address can change without invalidating every `host_vars` file, playbook pattern and CI `--limit` that names the host. ## The connection variable family These are ordinary variables that the connection plugin reads, which is why they can be set anywhere variables can be set: - `ansible_host` — the address or name to connect to. - `ansible_port` — the port; SSH defaults to 22. - `ansible_user` — the remote user to log in as. - `ansible_ssh_private_key_file` — the key to authenticate with. - `ansible_connection` — the transport plugin: `ssh` (default), `local` (run on the control node without SSH), `winrm` or `psrp` for Windows, and container transports such as `community.docker.docker`. - `ansible_python_interpreter` — which Python the modules run under on the target. - `ansible_become` / `ansible_become_user` — privilege escalation defaults for the host. Because they are variables, the natural home for shared ones is a group file. A whole Windows group becomes: ```yaml # group_vars/windows.yml ansible_connection: winrm ansible_port: 5986 ansible_user: svc_ansible ``` and a single odd host keeps its exception in `host_vars/web01.yml` instead of polluting the group. ## `ansible_python_interpreter` and why it appears Ansible modules are Python programs shipped to the target and executed there, so the target needs an interpreter. Modern ansible-core defaults this to `auto`, meaning it discovers a suitable Python for the detected distribution rather than hard-coding `/usr/bin/python`. Discovery still fails on minimal images, appliances and unusual distributions, and the fix is to state it: `ansible_python_interpreter: /usr/bin/python3.11`. Setting it per group is normal for a fleet of one distro; setting it per host is normal for the one oddity. ## Inventory variables versus `~/.ssh/config` You can achieve some of this with an SSH client config — a `Host web01` block with `HostName`, `Port` and `User`. The difference is who can reproduce it. An SSH config lives on one laptop; the inventory is in the repository, reviewed, and identical on the CI runner. For anything a teammate or a pipeline must reproduce, put it in the inventory. SSH config is still the right home for purely personal preferences and for jump-host plumbing you do not want to encode per project. ## Traps worth knowing `ansible_host` is easy to confuse with `ansible_hostname`, which is a *fact* gathered from the target (its configured hostname) and has nothing to do with connecting. Setting connection variables in a role's `vars/` rather than in the inventory hides them from anyone reading the inventory to answer "where does this actually connect?". And a `host_vars` file named after the address instead of the inventory alias is silently ignored — the lookup uses the alias. ## Verifying `ansible -i inventory web01 -m ping -vvv` prints the resolved connection — the address, port and user actually used — which resolves connection arguments faster than reading the files. `ansible-inventory --host web01` dumps the variables the host resolved to.

  • What is the difference between `ansible_host` and `ansible_hostname`?
    `ansible_host` is an inventory variable you set, telling Ansible which address to connect to. `ansible_hostname` is a fact gathered from the target after connecting — the machine's own configured hostname. Setting `ansible_hostname` in an inventory changes nothing about the connection, which is a classic source of confusion.
  • Where would you put `ansible_connection: winrm` for a fleet of Windows hosts?
    In `group_vars/windows.yml`, so every host in that group inherits the transport, port and user together. Per-host duplication of connection variables is a maintenance trap; the inventory should express the exception per host and the rule per group.
  • Why prefer inventory connection variables over an entry in `~/.ssh/config`?
    Because the inventory is in the repository: reviewed, versioned, and identical on a teammate's machine and the CI runner. An SSH config is per-user local state, so a playbook that only works because of it will fail in the pipeline with no visible cause.

saying these in an interview costs you the question

  • Believing the inventory name must be resolvable in DNS
  • Confusing ansible_host with the gathered fact ansible_hostname
  • Thinking a non-standard SSH port needs a custom connection plugin
  • Naming host_vars files after the IP rather than the alias
  • Relying on personal ~/.ssh/config so CI cannot reproduce the run

context