Inventory
Initialization
Create inventory file with IP addresses. Check computers in inventory by doing a ping:
ansible all -i inventory -u vagrant -m ping -k
# -i - <inventory file>
# -u - <username>
# -m - <select module>
# -k - <interactive password prompt>
ansible all -i inventory -u admin -m ping -k -vvv # debug mode with verbosity 3
Inventory examples:
[db]
vm ansible_host=192.168.1.98 ansible_user=aagern
[app]
vm ansible_host=192.168.1.98 ansible_user=aagern
[front]
vm ansible_host=192.168.1.98 ansible_user=aagern
[all:vars]
ansible_ssh_extra_args="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
ansible_python_interpreter=/usr/bin/python3
web1 ansible_ssh_host=192.168.33.20
db1 ansible_ssh_host=192.168.33.30
[webservers]
web1
[dbservers]
db1
[datacenter:children]
webservers
dbservers
[datacenter:vars]
ansible_ssh_user=vagrant
ansible_ssh_pass=vagrant
Configuration
Order of precedence for the config file:
- $ANSIBLE_CONFIG env variable (first place to be searched)
- ./ansible.cfg - local file in the working directory
- ~/.ansible.cfg - user home directory
- /etc/ansible/ansible.cfg - global config (last place to be searched)
First config file found wins, Ansible stops looking for other config files.
Environment override
Specify: $ANSIBLE_
Override settings on the fly:
$ export ANSIBLE_FORKS=10
[defaults]
forks - how many parallel processes does Ansible handle. Default=5, production recommended=20
host_key_checking - check host key before sending commands. Default=True (for production), for dev/test systems =False (easy control)
log_path - Ansible logging. Default=Null, produstion recommended - set path all Ansible users can write to.
Target patterns
Patterns to choose hosts/groups:
- OR pattern: group1:group2
Example:
ansible webservers:dbservers -i inventory -m service -a "name=iptables state=stopped" --sudo
- NOT pattern: :!group2
- Wildcard pattern: web.lab.local*
- REGEX pattern: ~web[0-9]+
- AND pattern: group1:&group2 - apply to hosts BOTH in group1 and group2 (intersection)
- Complex patterns
Complex pattern example: webservers:&production:!python3 # apply to web servers in production but not in the Python3 group
Modules
Help on modules
ansible-doc -l # all installed modules list
ansible-doc <module-name> # module man
ansible-doc -s <module-name> # playbook snippets code examples on module
Module examples
Copy module
- Copies a file from the local box to a remote system - useful for copying config files to remote system
- can do backups
- can do remote validation
Fetch module
- Copy a file from remote system to local box
- validate file using md5 checksum
Setup module
- Gather info and facts on remote system
- Inventory analysis of the system
ansible -i inventory web1 -m setup # gather all available system info
ansible -i inventory web1 -m setup -a "filter=ansible_eth*" # gather info on NICs
ansible -i inventory all -m setup --tree ./setup # form an inventory of files in /setup/ folder with info on targeted systems
Apt module (for Debian systems) / Yum module (RedHat systems)
- Install, update, delete packages
- Can update entire system
Example for Yum:
ansible webservers -i inventory -m yum -a "name=httpd state=present" -u vagrant --sudo
# name - name of package (Apache)
# present - if package is not there, install. If it is there - do nothing and report "changed: false" (idempotence test)
Service module
- Start/stop/restart services
- Set autostart option for services
ansible webservers -i inventory -m service -a "name=httpd state=started enabled=yes" -u vagrant --sudo
# name - name of service (Apache)
# state = started/stopped - make idempotence test and change if necessary
# enabled = yes/no - autostart on system boot
Playbooks
General tasks usage
# Tasks in a playbook are executed top down. Tasks use modules.
tasks:
- name: Name the task for readability
module: parameters=go_here
# Example:
- name: Deploy Apache Configuration File
copy: src=../../ansible/files/configuration/httpd.conf
dest=/etc/httpd/conf/
Playbook execution: ansible-playbook my_playbook.yml
Playbook example:
---
# -------- Global play declaration
- hosts: webservers
## ----- Variables per play
vars:
git_repo: https://github.com/repo.git
http_port: 8081
db_name: wordpress
## ------------------------
### ---- Declare user to run tasks
sudo: yes
sudo_user: wordpress_user
### ------------------------------
gather_facts: no # dont't gather facts with SETUP module (default gathers facts - expensive in time)
remote_user: root
tasks:
# --------------------------------
- name: Install Apache
yum: name=httpd state=present
- name: Start Apache
service: name=httpd state=started
Including files
Use “- include” and “- include_vars” directives to include playbook files:
tasks:
- include: wordpress.yaml
vars:
sitename: My Awesome Site
- include: reverse_proxy.yaml
- include_vars: variables.yaml
Register task output
Use the output of one task for another task:
tasks:
- shell: /usr/bin/whoami
register: username
- file: path=/home/myfile.txt
owner: {{ username }}
Debugging tasks with Debug module
Add screen output and print content of variables:
tasks:
- debug: msg="This host is {{ inventory_hostname }} during execution"
- shell: /usr/bin/whoami
register: username
- debug: var=username
Promt user during execution:
- hosts: web1
vars_prompt:
- name: "sitename"
prompt: "What is the new site name?"
tasks:
- debug: var=username
Playbook handlers
A handler can be informed to execute a task (restart service) only if state=changed.
- Run after all tasks
- Run only once no matter how many times they are called
Handlers syntax is the same as tasks syntax:
tasks:
- name: Copy Apache Config files
- copy: src=../../files/httpd.conf
dest=/etc/httpd/config/
notify:
- Apache Restart
handlers:
- name: Apache Restart
service: name=httpd state=restarted
“When” condition
Commence a task if condition is True:
tasks:
- name: Install Httpd Package
apt: name=httpd state=present
when: ansible_os_family == "RedHat"
- name: Install Apache2 Package
yum: name=apache2 state=present
when: ansible_os_family == "Debian"
Check output of previous task as condition to run next task:
tasks:
- name: Stop iptables now
service: name=iptables state=stopped
register: result
ignore_errors: yes # supress default stop on error
- debug: msg="Failure!"
when: result|failed # Debug message will only be shown if task has failed
# other conditions are "result|success", "result|skipped"
Checking variables with WHEN condition
Bring variable check to BOOL check:
- name: "test"
hosts: local
vars_prompt:
- name: "os_type"
prompt: "What OS? (centos or ubuntu)"
default: "centos"
private: no
vars:
- is_ubuntu: "{{os_type == 'ubuntu'}}"
- is_debian: "{{os_type == 'debian'}}"
tasks:
- debug: msg="this shows the conditional if variable equals ubuntu"
when: is_ubuntu|bool
- debug: msg="this shows the conditional if variable equals centos"
when: is_centos|bool