docs: add ansible howto collection
Four reference files covering: - ansible.md — core commands, ansible.cfg, key settings - ansible-inventory.md — static/dynamic inventory, directory layout - ansible-variables.md — 22-level precedence, scoping, merge behavior - ansible-roles.md — structure, defaults vs vars, dependencies
This commit is contained in:
214
topics/ansible-inventory.md
Normal file
214
topics/ansible-inventory.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# Ansible Inventory
|
||||
|
||||
> Define which hosts to manage, how to group them, and where to find them.
|
||||
|
||||
## Inventory Formats
|
||||
|
||||
### INI Format
|
||||
|
||||
```ini
|
||||
# inventory/hosts.ini
|
||||
|
||||
[webservers]
|
||||
web1.example.com
|
||||
web2.example.com ansible_port=2222
|
||||
|
||||
[dbservers]
|
||||
db1.example.com ansible_user=postgres
|
||||
db[1:3].example.com # db1, db2, db3
|
||||
|
||||
[loadbalancers]
|
||||
lb1.example.com
|
||||
|
||||
# Group of groups
|
||||
[production:children]
|
||||
webservers
|
||||
dbservers
|
||||
loadbalancers
|
||||
|
||||
# Group variables
|
||||
[webservers:vars]
|
||||
http_port=8080
|
||||
app_env=production
|
||||
|
||||
[all:vars]
|
||||
ansible_python_interpreter=/usr/bin/python3
|
||||
```
|
||||
|
||||
### YAML Format (preferred)
|
||||
|
||||
```yaml
|
||||
# inventory/hosts.yml
|
||||
all:
|
||||
vars:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
children:
|
||||
production:
|
||||
children:
|
||||
webservers:
|
||||
hosts:
|
||||
web1.example.com:
|
||||
web2.example.com:
|
||||
ansible_port: 2222
|
||||
vars:
|
||||
http_port: 8080
|
||||
dbservers:
|
||||
hosts:
|
||||
db1.example.com:
|
||||
ansible_user: postgres
|
||||
loadbalancers:
|
||||
hosts:
|
||||
lb1.example.com:
|
||||
```
|
||||
|
||||
## Directory Layout
|
||||
|
||||
```
|
||||
inventory/
|
||||
├── hosts.yml # Host definitions
|
||||
├── group_vars/
|
||||
│ ├── all.yml # Vars for every host
|
||||
│ ├── all/ # Dir form (merged, alphabetical)
|
||||
│ │ ├── common.yml
|
||||
│ │ └── vault.yml # Encrypted secrets
|
||||
│ ├── webservers.yml # Vars for webservers group
|
||||
│ └── production.yml # Vars for production parent group
|
||||
└── host_vars/
|
||||
├── web1.example.com.yml
|
||||
└── db1.example.com/ # Dir form
|
||||
├── main.yml
|
||||
└── vault.yml
|
||||
```
|
||||
|
||||
### Multiple Environments
|
||||
|
||||
```
|
||||
inventories/
|
||||
├── staging/
|
||||
│ ├── hosts.yml
|
||||
│ ├── group_vars/
|
||||
│ └── host_vars/
|
||||
└── production/
|
||||
├── hosts.yml
|
||||
├── group_vars/
|
||||
└── host_vars/
|
||||
```
|
||||
|
||||
```bash
|
||||
ansible-playbook site.yml -i inventories/staging/
|
||||
ansible-playbook site.yml -i inventories/production/
|
||||
```
|
||||
|
||||
## Dynamic Inventories
|
||||
|
||||
### Script-Based (legacy)
|
||||
|
||||
A script that outputs JSON when called with `--list` or `--host <name>`.
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env python3
|
||||
# inventory/dynamic.py — must be executable (chmod +x)
|
||||
import json, sys
|
||||
|
||||
def get_inventory():
|
||||
return {
|
||||
"webservers": {
|
||||
"hosts": ["web1.example.com", "web2.example.com"],
|
||||
"vars": {"http_port": 8080}
|
||||
},
|
||||
"dbservers": {
|
||||
"hosts": ["db1.example.com"]
|
||||
},
|
||||
"_meta": {
|
||||
"hostvars": {
|
||||
"web1.example.com": {"ansible_port": 22},
|
||||
"db1.example.com": {"ansible_user": "postgres"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if "--list" in sys.argv:
|
||||
print(json.dumps(get_inventory(), indent=2))
|
||||
elif "--host" in sys.argv:
|
||||
host = sys.argv[sys.argv.index("--host") + 1]
|
||||
hostvars = get_inventory().get("_meta", {}).get("hostvars", {})
|
||||
print(json.dumps(hostvars.get(host, {})))
|
||||
```
|
||||
|
||||
The `_meta.hostvars` key avoids per-host `--host` calls (efficiency).
|
||||
|
||||
### Plugin-Based (modern, preferred)
|
||||
|
||||
```yaml
|
||||
# inventory/aws_ec2.yml — filename must end with the plugin suffix
|
||||
plugin: amazon.aws.aws_ec2
|
||||
regions:
|
||||
- eu-west-1
|
||||
keyed_groups:
|
||||
- key: tags.Environment
|
||||
prefix: env
|
||||
- key: instance_type
|
||||
prefix: type
|
||||
filters:
|
||||
tag:Managed: ansible
|
||||
compose:
|
||||
ansible_host: private_ip_address
|
||||
```
|
||||
|
||||
Common inventory plugins:
|
||||
|
||||
| Plugin | Source | Suffix |
|
||||
|-------------------------------|------------|-----------------|
|
||||
| `amazon.aws.aws_ec2` | AWS EC2 | `aws_ec2.yml` |
|
||||
| `azure.azcollection.azure_rm`| Azure | `azure_rm.yml` |
|
||||
| `google.cloud.gcp_compute` | GCP | `gcp.yml` |
|
||||
| `community.general.proxmox` | Proxmox | `proxmox.yml` |
|
||||
| `community.docker.docker_containers` | Docker | `docker.yml` |
|
||||
| `ansible.builtin.constructed` | Derived | `constructed.yml`|
|
||||
|
||||
```bash
|
||||
# Verify dynamic inventory output
|
||||
ansible-inventory -i inventory/aws_ec2.yml --graph
|
||||
ansible-inventory -i inventory/aws_ec2.yml --list
|
||||
```
|
||||
|
||||
### Constructed Inventory (compose groups from existing data)
|
||||
|
||||
```yaml
|
||||
# inventory/constructed.yml
|
||||
plugin: ansible.builtin.constructed
|
||||
strict: false
|
||||
groups:
|
||||
is_debian: ansible_os_family == "Debian"
|
||||
is_large: ansible_memtotal_mb > 8192
|
||||
keyed_groups:
|
||||
- key: ansible_distribution | lower
|
||||
prefix: os
|
||||
```
|
||||
|
||||
## Special Variables
|
||||
|
||||
| Variable | Purpose |
|
||||
|-----------------------|------------------------------------|
|
||||
| `ansible_host` | IP/hostname to connect to |
|
||||
| `ansible_port` | SSH port (default: 22) |
|
||||
| `ansible_user` | SSH user |
|
||||
| `ansible_ssh_private_key_file` | SSH key path |
|
||||
| `ansible_become` | Enable privilege escalation |
|
||||
| `ansible_connection` | Connection type (`ssh`, `local`) |
|
||||
| `ansible_python_interpreter` | Python path on target |
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Script inventories must be executable (`chmod +x`) and have a shebang
|
||||
- Plugin inventory files must end with the correct suffix or be listed in `enable_plugins`
|
||||
- `group_vars/` directory must sit next to the inventory file, or at playbook level
|
||||
- YAML inventory: hosts need trailing colon even with no vars (`web1.example.com:`)
|
||||
- Groups named `all` and `ungrouped` are implicit — don't redefine them
|
||||
- Directory form `group_vars/all/` merges files alphabetically — name carefully
|
||||
|
||||
## See Also
|
||||
|
||||
- `ansible` — core commands and ansible.cfg
|
||||
- `ansible-variables` — variable precedence across inventory layers
|
||||
- `ansible-roles` — role structure and organization
|
||||
Reference in New Issue
Block a user