[web]
node2
[db]
db1 ansible_host=10.0.0.21 ansible_user=deploy
[local]
localhost ansible_connection=local
[web:vars]
ansible_user=student
| What |
Where |
Means |
| machine name |
node2 |
how the machine is named in the output; Ansible also connects by it if there is no ansible_host |
ansible_host |
the machine's line |
the address or name for SSH |
ansible_user |
the machine's line or [group:vars] |
who to log in as; without it — your own name |
ansible_connection=local |
the machine's line |
work on this machine without SSH |
[web] |
a header |
a group; all is every machine in the inventory |
student@node1:~/inv$ ansible-inventory -i hosts.ini --graph
@all:
|--@ungrouped:
|--@web:
| |--node2
|--@local:
| |--localhost
student@node1:~/inv$ ansible -i hosts.ini all --list-hosts
hosts (2):
node2
localhost
Without -i Ansible looks for /etc/ansible/hosts; the lab machine has
none, and the command sees only localhost. Inventory errors in a
playbook — ansible-playbook.
ansible <machines> -m <module> -a '<arguments>' runs one module on all
machines of a group. The answer comes per machine:
student@node1:~/inv$ ansible -i hosts.ini web -m copy \
> -a 'content="hello\n" dest=/tmp/hello.txt'
node2 | CHANGED => {
"changed": true,
"dest": "/tmp/hello.txt",
...
}
The same command again gives node2 | SUCCESS and "changed": false:
the file is already like that. The command module (also the default
without -m) does not know what the command does and always reports
CHANGED:
student@node1:~/inv$ ansible -i hosts.ini web -m command -a 'id -un'
node2 | CHANGED | rc=0 >>
student
| In the output |
Means |
SUCCESS |
the module ran, there was nothing to change |
CHANGED |
the module changed the machine (command always does) |
FAILED! |
the module ran with an error — the cause is in msg |
UNREACHABLE! |
cannot connect to the machine — ansible |
-o prints each machine's answer on one line. service returns
hundreds of unit fields — -o or a playbook is easier to read.
Modules run as the user Ansible logged in as. Writing to /etc without
the rights:
node2 | FAILED! => {
...
"msg": "Destination /etc not writable"
}
-b (--become) runs the module through sudo:
student@node1:~/inv$ ansible -i hosts.ini web -b -m command -a 'id -un'
node2 | CHANGED | rc=0 >>
root
On the lab machines student's sudo needs no password. Where sudo
asks for one, add -K (--ask-become-pass). In a playbook it is the
same — become: true.
- hosts: web
become: true
vars:
pkg: nginx
tasks:
- name: Install {{ pkg }}
apt: { name: "{{ pkg }}", state: present, update_cache: true }
- name: Config from a template
template: { src: nginx.conf.j2, dest: /etc/nginx/nginx.conf }
notify: reload nginx
- name: Start and enable
service: { name: "{{ pkg }}", state: started, enabled: true }
handlers:
- name: reload nginx
service: { name: nginx, state: reloaded }
ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.yml --check --diff
ansible-playbook -i inventory.ini site.yml --limit web1 --tags config
ansible-galaxy init roles/myrole
Variables go in group_vars/, host_vars/; secrets in ansible-vault
(ansible-vault encrypt secrets.yml, run with --ask-vault-pass). The
lab machine has no network to the outside: update_cache and packages
from the network will not work.
How to read a run, changed=0 on the second run, handlers,
--check --diff and playbook errors — ansible-playbook.