К основному контенту

Testing your Ansible roles with Vagrant








Travis.ci offers a simple and free way to test your Ansible roles but that’s after you’ve pushed and published your code. What if you want to verify how a change looks on a machine or easily see that build error without using an existing machine? This led me down the path of locally provisioning a virtual machine and outside of a normal virtual machine that I have running, I just wanted a standalone build just for a role.
I first went down the Docker route since that’d give me a good starting point but I still enjoy the simplicity of a Vagrant controlled virtual machine. The CLI is incredibly simple and you can easily swap out the base box to test on different distros if you’d like. Also, Vagrant has an ansible_local provisioner that makes it as simple as pointing it at your test playbook to run which I already have in place for Travis.ci.
The setup for this is based off of my Ansible Galaxy logrotate role which I recently added this test virtual machine to verify setup changes as well as to keep backwards compatibility with newer features. Right now when testing it’s a combination of ensuring the role stays as green as possible so that it’s idempodent and verifying template changes on the virtual machine.
In order to get setup locally you’ll need Vagrant and Virtualbox installed as well as Ansible. First, create a new tests directory and then within there a test.yml file which will contain a simple test playbook that’ll run on the virtual machine. We’ll utilize the logrotate role in our playbook but you can use whatever role your testing for, it just needs to be included in the roles list.

---
- hosts: all
  become: True
  vars:
    logrotate_scripts:
      - name: nginx-options
        path: /var/log/nginx/options.log
        options:
          - daily

  roles:
    - ansible-logrotate
The test file isn’t doing much at this point but it’ll end up doing a full role run on the virtual machine with some simple options, next we can setup the Vagrantfile to boot the virtual machine.

# -*- mode: ruby -*-
# vi: set ft=ruby :
@ansible_home = "/home/vagrant/.ansible"

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"

  # Copy the Ansible playbook over to the guest machine, run rsync-auto to automatically
  # pull in the latest changes while a VM is running.
  config.vm.synced_folder "../", "#{@ansible_home}/roles/ansible-logrotate", type: 'rsync'

  # The working ansible directory created by ansible_local is owned by root
  config.vm.provision "shell", inline: "chown vagrant:vagrant #{@ansible_home}"

  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "test.yml"
  end
end
Within our Vagrantfile we’re doing a few things:
  1. Sycing over the Ansible role that we’re working on into a default Ansible role directory, I’ve found that rsync-auto synced folders are much faster than mounted folders
  2. Ensure that the vagrant user owns the working directory with the shell provisioner
  3. From there we use the ansible_local provisioner provided by Vagrant to run our test playbook with Ansible on the virtual machine
Now that this is in place you can run vagrant up --provision to run the test playbook on the virtual machine. The first run of course will take some time as it downloads the box and adds the guest additions, subsequent runs are fairly fast.
Next we can add an actual test to the playbook and since we’re making changes to the role on our local OS make sure you have rsync-auto running for your virtual machine. This will ensure that your changes are copied over to the machine upon save, this is configured via the Vagrantfile as mentioned above.
Go ahead and add a task that’ll verify that something is in place or checking the state of something. For this example I’m ensuring that doing a config check on the logrotate file that was just put in place doesn’t trigger any errors from the logrotate command. Update your test.yml file so the full version looks like this:

---
- hosts: all
  become: True
  vars:
    logrotate_scripts:
      - name: nginx-options
        path: /var/log/nginx/options.log
        options:
          - daily

  roles:
    - ansible-logrotate

  tasks:
    - name: Verify logrotate config check passes
      shell: logrotate -d "{{ logrotate_conf_dir }}{{ item.name }}"
      with_items: "{{ logrotate_scripts }}"
      register: logrotate_tests
      failed_when: "'error' in logrotate_tests.stderr"
Go ahead and run vagrant up --provision and it’ll run through and you should see green for the initial logrotate steps since those already ran and then yellow for the one task verifying the logrotate file, red would of course be a failure that you’d want to fix.
From here you can continue to make changes to your role, break things, fix things, ssh into the VM to verify, etc. Here’s my workflow as I was building this out for the galaxy role:


source:

Комментарии

Популярные сообщения из этого блога

How to do Arithmetic Operations in Ansible

You can use arithmetic calculations in Ansible using the Jinja syntax. This is helpful in many situations where you have stored the output of an operation, and you need to manipulate that value. All usual operation like addition, subtraction, multiplication, division, and modulo are possible. Let us start with an example. We will be using the  debug module  to print the out the result. The following tasks show all the basic arithmetic operations. The output is given in comments. Ansible arithmetic operation example - hosts: loc tasks: - debug: msg: "addition{{ 4 +3 }}" #Ansible addition 7 - debug: msg: "substraction {{ 4 - 3 }}" #Ansible arithmetic substraction 1 - debug: msg: "multiplication {{ 4 * 3 }}" #multiplication 12 - debug: msg: "Modulo operation {{ 7 % 4}}" #ansible Modulo operation - find remainder 3 - debug: msg: "floating division {{ 4 / 3}}" #ansible floating divisio...

ubuntu/debian ipmi

#install ipmitool (this is for debian) apt-get install ipmitool #insert the kernel modules needed for ipmi modprobe ipmi_devintf modprobe ipmi_si modprobe ipmi_msghandler #get the current mode (01 00 is dedicated mode) ipmitool raw 0x30 0x70 0x0c 0 #send the raw command to enable dedicated lan ipmitool raw 0x30 0x70 0xc 1 1 0
Ansible - Appending to lists and dictionaries  n this blog post I'll show how to add items to lists and dictionaries, when using loops, and across tasks. Normally when trying to add a new item to the variable, while in the loop, or between tasks, Ansible will ovewrite the values, keeping the result of the last iteration. For example, let's see what will be the result of running the following playbook: --- - name: Append to list hosts: localhost vars: cisco: - CiscoRouter01 - CiscoRouter02 - CiscoRouter03 - CiscoSwitch01 arista: - AristaSwitch01 - AristaSwitch02 - AristaSwitch03 tasks: - name: Add Cisco and Airsta devices to the list set_fact: devices: "{{ item }}" with_items: - "{{ cisco }}" - "{{ arista }}" - name: Debug list debug: var: devices verbosity: 0 [przemek@quasar blog]$ ansible-playbook append_list.yml PLAY [Append to list] ****************...