Executing Ansible Tests
We can just believe the acres of green lines that are reported back from our Ansible playbooks of executing them. Sure the tasks have succeeded but if there anything that we may have overlooked, like permissions, SELinux or firewalls all throwing stones at our deployments. Testing that the service is actually working is crucial to the success. Executing tests in Ansible is crucial to the success. Ansible Molecule has a verify Playbook to run this for you but we can also think about building tests directly into our own Playbooks. We run our tests in AWS and Molecule could use the delegated driver to connect into external clod providers. As I say we will be executing these test in Ansible from our own Playbooks.
Deploying Apache to Rocky Linux
The Playbook that we are Using to deploy Apache is kept very simple:
--- - name: Http deployment hosts: webservers become: true gather_facts: true tasks: - name: deploy http package: name: httpd state: present - name: start service service: name: httpd state: started enabled: true - name: deliver content copy: content: This is the web content dest: /var/www/html/index.html
Whist this is ok, we do not test that the service stays running, we do not test that the web server is serving pages and the page that we expect.
Working with Hostvars
The hostvars variable are facts that are cached during the execution of the Playbook. We can access the variables from the same Playbook, so long as the hosts we need have been contacted in the Playbook. The best testing of services such as Aapche is to connect from remote machies. We can use the Controller to test connections to the wen servers by collecting their IP Addresses from hostvars.
- name: Run tests hosts: localhost connection: local become: false tasks: - name: Collects web server IPs template: src: test.j2 dest: text.txt
This Play is added to the existing Playbook as the 2nd Play Ansible will be executing, this will eventually have the tests needing executing by Ansible to prove the deployment. The Jinja template is shown next:
{% for host in groups['redhat'] %} {{ hostvars[host]['ansible_default_ipv4']['address'] }} {% endfor %}
The list will be created in the test.txt file and will have the IP addresses of the hosts in the group webservers. This will also be in the inventory but of course we would need to process the file with some utility outside of Ansible to do this. This shows a dynamic was to create the list.
Now: Executing Test in Ansible
The final Playbook
--- - name: Http deployment hosts: webservers become: true gather_facts: true tasks: - name: deploy http package: name: httpd state: present - name: start service service: name: httpd state: started enabled: true - name: deliver content copy: content: This is the web content dest: /var/www/html/index.html - name: Run tests hosts: localhost connection: local become: false tasks: - name: Collects web server IPs template: src: test.j2 dest: text.txt - name: p4 uri: url: http://{{ item }} status_code: 200 with_lines: cat text.txt
The with_lines metaparameter allows us to read the list of IPs and use it in a loop were we check for a status code of 200 being returned.