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

Testing Ansible Roles using Molecule and Vagrant

Ansible

Ansible is a radically simple IT automation engine that automates cloud provisioning,configuration management, application deployment, intra-service orchestration, and many other IT needs.

TestInfra

With Testinfra you can write unit tests in Python to test actual state of your servers
AND/OR

ServerSpec

With Serverspec, you can write RSpec tests for checking your servers are configured correctly.
And

Molecule

Molecule is designed to aid in the development and testing of Ansible roles including support for multiple instances, operating system distributions, virtualization providers and test frameworks.


Getting started with molecule

  • Installing molecule
$ pip install molecule
molecule --version
  • Create an Ansible Role
$ molecule init test-role-vagrant
Successfully initialized new role in ./test-role-vagrant
This will create an ansible role with the following directory structure
test-role-vagrant
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── molecule.yml
├── playbook.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   ├── test.yml
│   └── test_default.py
└── vars
    └── main.yml
The directory structure looks familiar? that is molecule internally uses ansible-galaxy init command to create a role structure. It then puts following extra files in it.
  • molecule.yml | test framework configuration
  • playbook.yml | playbook for executing the role in the vagrant
  • tests/test_default.py | tset infra unit test cases
molecule.yml describes so many details but the default uncommented lines are given below
---
vagrant:
  # vagrant arguments that are global to all instances
  raw_config_args:
    — “ssh.insert_key = false”
  # molecule’s — platform option will look for these names
  platforms:
    — name: trusty64
  box: trusty64
  box_url: https://vagrantcloud.com/ubuntu/boxes/trusty64/versions/14.04/providers/virtualbox.box
  # Optional: box_version — support for vagrant versioning
  # box_version: 0.1.0
  # Optional: very basic support for vagrant-triggers plugin
  # triggers:
  # — trigger: before
  # action: destroy
  # cmd: run_remote ‘subscription-manager unregister’
  providers:
    — name: virtualbox
  type: virtualbox
  options:
  memory: 512
  cpus: 2
  instances:
    — name: test-role-vagrant-01
  ansible_groups:
    — group_1
    — group_2
  interfaces:
    — network_name: private_network
  type: dhcp
  auto_config: true
  options:
  # prevents vagrant-01 from becoming vagrant-01-rhel-7 (platform is appended by default)
    append_platform_to_hostname: no
  # vagrant arguments specific to this instance
This default configuration can be used to test the role against trusty64 vagrant box
Let’s create put one task in tasks/main.yml
---
# tasks file for test-role-vagrant
- name: install wget package
  apt: name=wget state=present
Write the test case to check if the package is installed properly
def test_hosts_file(Package):
  p = Package(‘wget’)
  assert p.is_installed
now to test the role execute the below command
$ molecule test
Bringing machine ‘test-role-vagrant-01’ up with ‘virtualbox’ provider…
==> test-role-vagrant-01: Box ‘trusty64’ could not be found. Attempting to find and install…
 test-role-vagrant-01: Box Provider: virtualbox
 test-role-vagrant-01: Box Version: >= 0
==> test-role-vagrant-01: Box file was not detected as metadata. Adding it directly…
==> test-role-vagrant-01: Adding box ‘trusty64’ (v0) for provider: virtualbox
 test-role-vagrant-01: Downloading: https://vagrantcloud.com/ubuntu/boxes/trusty64/versions/14.04/providers/virtualbox.box
==> test-role-vagrant-01: Successfully added box ‘trusty64’ (v0) for ‘virtualbox’!
==> test-role-vagrant-01: Preparing master VM for linked clones…
 test-role-vagrant-01: This is a one time operation. Once the master VM is prepared,
 test-role-vagrant-01: it will be used as a base for linked clones, making the creation
 test-role-vagrant-01: of new VMs take milliseconds on a modern system.
==> test-role-vagrant-01: Importing base box ‘trusty64’…
==> test-role-vagrant-01: Cloning VM…
==> test-role-vagrant-01: Matching MAC address for NAT networking…
==> test-role-vagrant-01: Setting the name of the VM: test-role-vagrant_test-role-vagrant-01_1466261467727_9266
==> test-role-vagrant-01: Clearing any previously set forwarded ports…
==> test-role-vagrant-01: Fixed port collision for 22 => 2222. Now on port 2201.
==> test-role-vagrant-01: Clearing any previously set network interfaces…
==> test-role-vagrant-01: Preparing network interfaces based on configuration…
 test-role-vagrant-01: Adapter 1: nat
 test-role-vagrant-01: Adapter 2: hostonly
==> test-role-vagrant-01: Forwarding ports…
 test-role-vagrant-01: 22 (guest) => 2201 (host) (adapter 1)
==> test-role-vagrant-01: Running ‘pre-boot’ VM customizations…
==> test-role-vagrant-01: Booting VM…
==> test-role-vagrant-01: Waiting for machine to boot. This may take a few minutes…
 test-role-vagrant-01: SSH address: 127.0.0.1:2201
 test-role-vagrant-01: SSH username: vagrant
 test-role-vagrant-01: SSH auth method: private key
 test-role-vagrant-01: Warning: Remote connection disconnect. Retrying…
 test-role-vagrant-01: Warning: Remote connection disconnect. Retrying…
==> test-role-vagrant-01: Machine booted and ready!
==> test-role-vagrant-01: Checking for guest additions in VM…
 test-role-vagrant-01: The guest additions on this VM do not match the installed version of
 test-role-vagrant-01: VirtualBox! In most cases this is fine, but in rare cases it can
 test-role-vagrant-01: prevent things such as shared folders from working properly. If you see
 test-role-vagrant-01: shared folder errors, please make sure the guest additions within the
 test-role-vagrant-01: virtual machine match the version of VirtualBox you have installed on
 test-role-vagrant-01: your host and reload your VM.
 test-role-vagrant-01:
 test-role-vagrant-01: Guest Additions Version: 4.3.36
 test-role-vagrant-01: VirtualBox Version: 5.0
==> test-role-vagrant-01: Setting hostname…
==> test-role-vagrant-01: Configuring and enabling network interfaces…
==> test-role-vagrant-01: Mounting shared folders…
 test-role-vagrant-01: /vagrant => /Users/sebin/dev/molecule_roles/test-role-vagrant
==> test-role-vagrant-01: Machine not provisioned because ` — no-provision` is specified.
 ____________
< PLAY [all] >
 — — — — — — 
 \ ^__^
 \ (oo)\_______
 (__)\ )\/\
 || — — w |
 || ||
______________
< TASK [setup] >
 — — — — — — — 
 \ ^__^
 \ (oo)\_______
 (__)\ )\/\
 || — — w |
 || ||
ok: [test-role-vagrant-01]
 _________________________________________________
< TASK [test-role-vagrant : install wget package] >
 — — — — — — — — — — — — — — — — — — — — — — — — -
 \ ^__^
 \ (oo)\_______
 (__)\ )\/\
 || — — w |
 || ||
ok: [test-role-vagrant-01]
 ____________
< PLAY RECAP >
 — — — — — — 
 \ ^__^
 \ (oo)\_______
 (__)\ )\/\
 || — — w |
 || ||
test-role-vagrant-01 : ok=2 changed=0 unreachable=0 failed=0
Idempotence test in progress (can take a few minutes)…
Idempotence test passed.
Executing testinfra tests found in tests/.
============================= test session starts ==============================
platform darwin — Python 2.7.11, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /Users/sebin/dev/molecule_roles/test-role-vagrant, inifile:
plugins: xdist-1.14, testinfra-1.3.0
gw0 [1] / gw1 [1] / gw2 [1]
scheduling tests via LoadScheduling
.
=========================== 1 passed in 2.41 seconds ===========================
No serverspec tests found in spec/.
==> test-role-vagrant-01: Forcing shutdown of VM…
==> test-role-vagrant-01: Destroying VM and associated drives…
the different steps in a molecule test are
  • molecule create |> creates the vagrant instance
  • molecule converge |> run ansible-playbook playbook.yml …
  • molecule idempotence |> do the idempotence test
  • molecule verify |> run the tests using testinfra
  • molecule destroy |> delete the vagrant instance
The tests can be done using docker also, which will improve the initiation time and put lower overhead on the host machine. Check out this post

Комментарии

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

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] ****************...