I use Ansible on a daily basis and it brings me so much joy when I finally write up a new Role or update a Playbook and everything works.
But that’s usually after a while of failures - a lot of failures. But that’s okay, if Ansible is used in the right way then you’ll always make progress.
So here’s some tips that help!
1. Use ‘ansible-lint’
Such a simple but useful tool will help keep your Playbooks and Roles clean of errors and provide useful hints to improve them e.g. ensuring Tasks are named.
Best run when creating or editing Roles and Playbooks.
ansible-lint playbook.yaml
2. Be Verbose
With certain Modules there is Default values set and whilst it may be fine to not mention them when writing up Tasks, there can be consequences for your future self or others when they come to update the Task. For instance apt install packages by default but doesn't update the cache. So you can end up with a Task like this:
- name: Install Nginx
apt:
name: nginx
But future self or others might hit an issue with this if the cache hasn't been updated prior, so by making it more verbose the state and Task provide more clarity of what's actually being run:
- name: Install Nginx
apt:
name: nginx
state: present
update_cache: yes
3. Don’t be afraid to use ‘shell’ or ‘command’
There is lot of Modules out there but sometimes it's easier to write a simple one liner to do what you want done - although not recommended by Ansible. ACME Certificate Module is very complex to use, and it has to be run twice to work. When I can tried to implement Let's Encrypt/Certbot with a Wildcard, I found it easier to use shell instead:
- name: Get TLS Certificates
shell: "certbot certonly --dns-route53 -d {{ server_name }} -n --agree-tos --email {{ email }}"
It's clearer what's being run and it can easily be changed in the future by others.
4. Enable Timer
Add this to your ansible.cfg
:
callback_whitelist = timer, profile_tasks
And this will allow you to see how long each Task and the Playbook took to run. This gives both estimates for when others run them but also allows insight into what tasks are slow and could be improved.
PLAY RECAP
**************************************************************
rpi2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
rpi3 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tinker : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Tuesday 14 July 2020 19:20:11 +0100 (0:00:00.603) 0:01:19.673 **********
==============================================================
Gathering Facts - 13.72s
/Users/tomwatt/DEV/Ansible-Local/playbooks/test.yaml:2
--------------------------------------------------------------
test-connection : Ensure the right sudo password - 6.13s
/Users/tomwatt/DEV/Ansible-Local/roles/test-connection/tasks/main.yaml:2
--------------------------------------------------------------
debug-host-info : Print Host Information - 0.60s
/Users/tomwatt/DEV/Ansible-Local/roles/debug-host-info/tasks/main.yaml:2
--------------------------------------------------------------
Playbook run took 0 days, 0 hours, 1 minutes, 19 seconds
5. Keep Ansible up to date
Newer versions have more functionality and fixes. One caveat, though, is being aware of changes between versions e.g. modules renamed, deprecations, etc. So check the Porting Guides when prior to updating.
Running your Playbooks with Verbose - -vvvvv
- on will give hints of what’s being changed/removed in later versions.
6. Many and Small Roles
I've done it and it's easily done, creating a Playbook that does everything that needs doing. It will work but will it work in the future? What happens when it needs a minor change to work on a different server? This is where having more, smaller Roles helps.
Keeping a Role to a simple grouping of Tasks, with any needed variables, handlers or templates improves the reusability of it. It's also organises the code, for easier testing and maintenance.
7. Use ‘ansible-galaxy role init’ to create Roles
Following on, be lazy and use it to create the basic structure for your new Roles, then remove what you don’t need.
Hope some of these are helpful for those who use Ansible or looking to use it. But let me know and share any tips you all have as well!
Top comments (3)
"3. Don’t be afraid to use ‘shell’ or ‘command’"
Ansible actually advises against resorting to utilizing shell commands because they don't maintain state. Ansible has no visibility with shell commands. It's best to:
the command line makes it rather convenient, but you lose a lot of the core functionalities of Ansible.
Thanks for the comment, I am aware that Ansible is against use of ‘shell’ & ‘command’ and updated the post. The point is more at the fact that some modules are complex and who ever maintains the code and uses them in a Task in the future might not be as knowledgeable and understand it if it needs changing.
It is impossible to cover everything with Ansible. In many cases I have to use shell commands for deployments. One example is IBM WebSphere deployment.