BackgroundBefore adopting this strategy I found myself testing ansible roles on the actual machine they were being deployed to. This is bad because:
- It's error prone (previous failed attempts can leave the machine your testing on in a state that is invalid).
- You have to write more code to rollback what ansible has done so you can test again.
- Not being able to run locally increases you edit, compile, debug cycle.
- In order to automate this for CI you need to set aside a machine/VM.
How to test an ansible roleJeff Geerling has a great blog post on testing ansible roles with travis ci which was adapted from his book Ansible for DevOps. His post shows you how to test that:
- role syntax is ok.
- role can be applied to localhost.
- role is idempotent (i.e. can be applied again to localhost resulting in zero changes).
This is a great approach. However it doesn't quite work for me since:
- I'm using a different distribution of linux on my dev machine to my production machines that my roles are designed for.
- Even if I could run them locally, I don't want to as I'll have to undo the actions in order to run the tests again.
- I'm not using travic ci.
Testing ansible role with dockerSee my sample project on github. In short, this involves the exact same steps as above but just replacing localhost with a docker container.
|Diagram showing flow of bash script calling ansible which applies the role to a docker container|
- Test role syntax locally.
- Test role can be applied to docker container via ssh.
- Re-apply the role to the docker container and check it results in zero changes.
- Check that the docker container is in the correct state.
All I really needed was to write the bash script and find a docker image that was "red hat like" that came with ssh. I found the tutum centos docker image which was perfect.
This testing approach has a number of benefits:
- Can apply role to a different linux distribution than your localhost. For example if you use a Debian Linux distribution locally but want to test your role against a CentOs distribution, this is possible by using a docker image that mimics the distribution of your choice. This can have the affect of simplifying your role as you only have to worry about one platform (e.g. not having to use the ansible apt and yum module with when conditions as per this article)
- Since the docker container is destroyed on the next run of the test, it can be run multiple times without prior runs affecting future runs.
- Testing via ssh and not localhost. Ansible should behave the same way when applying a role to localhost as for ssh, but testing via ssh is more likely a closer test to your real world setup.
- Test can be extended to run against different docker containers. Perhaps you have different machines in different states which your role will need to handle, this can be tested by applying your role to different docker containers.
- You need docker installed.
- Finding a docker image that is in the correct state can be hard, might require you to create one yourself.
- My bash script is a little complicated and might be hard to maintain!