-
Try to avoid the command module - always seek out a module first
-
Always use version control to keep track of your Ansible work
-
Use whitespaces, tag roles, name tasks and plays. Use readable directorly layouts
site.yml # master playbook, calling others
webservers.yml # playbook for webserver tier
deployonce.yml # separate playbook for single-shot tasks
inventories/
production/ # different stages via inventory
hosts # inventory file for production servers
group_vars/
host_vars/
london/ # additional, alternative grouping if useful
roles/
requirements.yml # includes roles from some other place
common/ # base line, company wide configuration
webtier/
-
Start with one Git repository - but when it grows, use multiple!
-
At the beginning: put everything in one Git repository
-
In the long term:
-
● One Git repository per role
-
● Dedicated repositories for completely separated teams / tasks
-
Give inventory nodes human-meaningful names rather than IPs or DNS hostnames
-
Group hosts for easier inventory selection and less conditional tasks -- the more the better.
-
Use dynamic sources where possible. Either as a single source of truth - or let Ansible unify multiple sources.
● Stay in sync automatically ● Reduce human error ● No lag when changes occur ● Let others manage the inventory
- Use Cloud Native yaml formatting for writing.
USE NATIVE YAML SYNTAX
NO!
USE NATIVE YAML SYNTAX
- name: install telegraf
yum: name=telegraf-{{ telegraf_version }} state=present update_cache=yes notify: restart telegraf
- name: start telegraf
service: name=telegraf state=started
Better, but no
- name: install telegraf
yum: >
name=telegraf-{{ telegraf_version }}
state=present
update_cache=yes
enablerepo=telegraf
notify: restart telegraf
- name: start telegraf
service: name=telegraf state=started
Yes!
- name: install telegraf
yum:
name: “telegraf-{{ telegraf_version }}”
state: present
update_cache: yes
enablerepo: telegraf
notify: restart telegraf
- name: start telegraf
service:
name: telegraf
state: started
-
Name tasks clearly
-
Blocks can help in organizing code, but also enable rollbacks or output data for critical changes
-
Use the Ansile provided multiple switches on the CLI for troubleshooting like -vv and --check etc.
-
Don’t just start services -- use smoke tests
-
Try to avoid the command module - always seek out a module first
NO!:
- name: add user
command: useradd appuser
- name: install apache
command: yum install httpd
- name: start apache
shell: |
service httpd start && chkconfig
httpd on
YES!:
- name: add user
user:
name: appuser
state: present
- name: install apache
yum:
name: httpd
state: latest
- name: start apache
service:
name: httpd
state: started
enabled: yes
- If managed files are not marked, they might be overwritten accidentally
● Label template output files as being generated by Ansible ● Use the ansible_managed** variable with the comment filter
{{ ansible_managed | comment }}
- Roles enable you to encapsulate your operations.
● Like playbooks -- keep roles purpose and function focused
● Store roles each in a dedicated Git repository
● Include roles via roles/requirements.yml file, import via
ansible-galaxy tool
● Limit role dependencies
- Get roles from Galaxy, but be careful and adopt them to your needs
● Galaxy provides thousands of roles
● Quality varies drastically
● Take them with a grain of salt
● Pick trusted or well known authors
- Root access is harder to track than sudo - use sudo wherever possible
Ansible can be run as root only
● But login and security reasons often request non-root access
● Use become method - so Ansible scripts are executed via sudo
(sudo is easy to track)
● Best: create an Ansible only user
● Don’t try to limit sudo rights to certain commands - Ansible does
not work that way!
- More Tower for live-applications. More research to be done here for Ansible Tower best practices.
True or False?
A module is a collection of tasks? FALSE
It’s better to use shell or command instead of a specific module? FALSE
Host facts override play variables?
A role might include the following: vars, meta, and handlers?
Dynamic inventory is generated by extracting information from external sources?
It’s a best practice to use indention of 2 spaces instead of 4?
‘notify’ used to trigger handlers?
This “hosts: all:!controllers” means ‘run only on controllers group hosts?