<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>molecule | ..:: BOFH ::..</title><link>https://bofh.im/tag/molecule/</link><atom:link href="https://bofh.im/tag/molecule/index.xml" rel="self" type="application/rss+xml"/><description>molecule</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><copyright>© 1996-2025</copyright><lastBuildDate>Mon, 30 Mar 2020 02:53:32 +0600</lastBuildDate><image><url>https://bofh.im/media/icon_hu5405a232fba0802caf7558beb944b483_62948_512x512_fill_lanczos_center_2.png</url><title>molecule</title><link>https://bofh.im/tag/molecule/</link></image><item><title>Multiplatform Testing With Molecule and Travis</title><link>https://bofh.im/post/multiplatform-testing-with-molecule-travis/</link><pubDate>Mon, 30 Mar 2020 02:53:32 +0600</pubDate><guid>https://bofh.im/post/multiplatform-testing-with-molecule-travis/</guid><description>&lt;p>Recently I had been trying to convert all my Bourne shell scripts into possible &lt;a href="https://galaxy.ansible.com" target="_blank" rel="noopener">Ansible Galaxy&lt;/a> Roles so that I can use it every now and then in my playbooks. Normally my regular job requires concentration on &lt;a href="https://freebsd.org" target="_blank" rel="noopener">FreeBSD&lt;/a> based systems only but one of my new gigs actually has a multi platform scenario running &lt;a href="https://centos.org" target="_blank" rel="noopener">CentOS&lt;/a>, &lt;a href="https://ubuntu.com" target="_blank" rel="noopener">Ubuntu&lt;/a>, &lt;a href="https://debian.org" target="_blank" rel="noopener">Debian&lt;/a>, &lt;a href="https://freebsd.org" target="_blank" rel="noopener">FreeBSD&lt;/a>, &lt;a href="https://www.archlinux.org" target="_blank" rel="noopener">Arch Linux&lt;/a> and what not. So thought about rewriting the shell scripts into reusable multi platform Ansible Roles.&lt;/p>
&lt;p>The first place I thought about heading into was &lt;a href="https://galaxy.ansible.com" target="_blank" rel="noopener">Ansible Galaxy&lt;/a> which is a platform for sharing Ansible Roles with others. Ths site is nice and clean; has a good option for searching including name, tags and platform. For a network infrastructure the first crucial part is time synching. So I started searching for ntp which supports &lt;a href="https://freebsd.org" target="_blank" rel="noopener">FreeBSD&lt;/a>. There are lots of roles supporting that search. But some are broken, some do not work on that platform, some requires earlier version of Ansible. So rather than finding the needle in the haystack it was better to write my own version. Writing a dirty oneliner or hack for an internal project is one thing and writing and sharing something on the web which will be reused by others is another thing. It requires standardized code writing and build testing. In DevOPS philosophy what we call Continuous Integration/Continuous Deployment. Whenever we are changing a line of code the code is pushed into a testing system for a successfull build; once the build is successful it is deployed into production.&lt;/p>
&lt;p>Testing Ansible Roles on multi platforms is not an easy task. For local projects we can create &lt;a href="https://docker.com" target="_blank" rel="noopener">Docker&lt;/a> containers to test specially on Linux systems or we can test with &lt;a href="https://vagrantup.com" target="_blank" rel="noopener">Vagrant&lt;/a> using &lt;a href="https://https://virtualbox.org" target="_blank" rel="noopener">Virtualbox&lt;/a>. For normal syntax check we can use &lt;code>ansible-playbook&lt;/code> with &lt;code>--syntax-check&lt;/code> or &lt;a href="https://github.com/ansible/ansible-lint" target="_blank" rel="noopener">&lt;code>ansible-lint&lt;/code>&lt;/a>. But for real world scenario we need a good Testing Framework. &lt;a href="https://github.com/ansible-community/molecule" target="_blank" rel="noopener">molecule&lt;/a> is one good framework for the purpose. It has support for multi cloud platforms to deploy our testing. We can use &lt;a href="https://github.com/ansible-community/molecule" target="_blank" rel="noopener">molecule&lt;/a> to test locally or on remote cloud platforms or integrate it with additional CI/CD platforms like &lt;a href="https://travis-ci.org/" target="_blank" rel="noopener">Travis&lt;/a> or &lt;a href="https://cirrus-ci.org" target="_blank" rel="noopener">Cirrus&lt;/a> by creating a pipline from &lt;a href="https://github.com" target="_blank" rel="noopener">Github&lt;/a> or &lt;a href="https://gitlab.com" target="_blank" rel="noopener">Gitlab&lt;/a>. Both of them have commercial versions but for Open Source applications both of them are free. &lt;a href="https://galaxy.ansible.com" target="_blank" rel="noopener">Ansible Galaxy&lt;/a> has support for &lt;a href="https://travis-ci.org" target="_blank" rel="noopener">Travis&lt;/a> and &lt;a href="https://github.com" target="_blank" rel="noopener">Github&lt;/a>. So if my role is hosted at &lt;a href="https://github.com" target="_blank" rel="noopener">Github&lt;/a> and I have a proper definition of testing in a file called &lt;code>.travis.yml&lt;/code> in my root directory; whenever I have code change pushed into the &lt;a href="https://git-scm.com/" target="_blank" rel="noopener">git&lt;/a> repository my Ansible role will be tested and the result will be notified in my &lt;a href="https://galaxy.ansible.com" target="_blank" rel="noopener">Ansible Galaxy&lt;/a> project. Now the big problem for me is that &lt;a href="https://travis-ci.org" target="_blank" rel="noopener">Travis&lt;/a> do not have support for &lt;a href="https://freebsd.org" target="_blank" rel="noopener">FreeBSD&lt;/a> like &lt;a href="https://cirus-ci.org" target="_blank" rel="noopener">Cirrus&lt;/a>.&lt;/p>
&lt;p>So testing for my roles in a multi platform is facing a Road Block. We have to be a bit innovative. &lt;a href="https://github.com/ansible-community/molecule" target="_blank" rel="noopener">molecule&lt;/a> supports &lt;a href="https://vagrantup.com" target="_blank" rel="noopener">Vagrant&lt;/a> and &lt;a href="https://vagrantup.com" target="_blank" rel="noopener">Vagrant&lt;/a> has support for multiple Providers like &lt;a href="https://https://virtualbox.org" target="_blank" rel="noopener">Virtualbox&lt;/a>, &lt;a href="https://docker.com" target="_blank" rel="noopener">Docker&lt;/a>, &lt;a href="https://vmware.com" target="_blank" rel="noopener">Vmware&lt;/a>, &lt;a href="https://libvirt.org" target="_blank" rel="noopener">libvirt&lt;/a>. For a commandline based interface &lt;a href="https://libvirt.org" target="_blank" rel="noopener">libvirt&lt;/a> looks like a good choice. So we are going to create a &lt;a href="https://vagrantup.com" target="_blank" rel="noopener">Vagrant&lt;/a> and &lt;a href="https://libvirt.org" target="_blank" rel="noopener">libvirt&lt;/a> interface within our limited access &lt;a href="https://travis-ci.org" target="_blank" rel="noopener">Travis&lt;/a> platform; and push our code into that &lt;a href="https://libvirt.org" target="_blank" rel="noopener">libvirt&lt;/a> environment. Let&amp;rsquo;s jump into the code and see how we can accomplish this with &lt;a href="https://github.com/ansible-community/molecule" target="_blank" rel="noopener">molecule&lt;/a> and &lt;a href="https://travis-ci.org" target="_blank" rel="noopener">Travis&lt;/a>.&lt;/p>
&lt;p>My &lt;code>.travis.yml&lt;/code> looks like this.&lt;/p>
&lt;pre>&lt;code class="language-yaml">---
dist: bionic
language: python
python:
- 3.6
env:
global:
- VAGRANT_VER: 2.2.7
matrix:
- MOLECULE_DISTRO_BOX: generic/ubuntu1604
- MOLECULE_DISTRO_BOX: generic/ubuntu1804
- MOLECULE_DISTRO_BOX: debian/stretch64
- MOLECULE_DISTRO_BOX: debian/buster64
- MOLECULE_DISTRO_BOX: centos/7
- MOLECULE_DISTRO_BOX: centos/8
- MOLECULE_DISTRO_BOX: generic/freebsd11
- MOLECULE_DISTRO_BOX: generic/freebsd12
install:
- sudo add-apt-repository universe &amp;amp;&amp;amp; sudo apt update
- wget https://releases.hashicorp.com/vagrant/$VAGRANT_VER/vagrant_&amp;quot;$VAGRANT_VER&amp;quot;_x86_64.deb
- sudo dpkg -i vagrant_&amp;quot;$VAGRANT_VER&amp;quot;_x86_64.deb
- sudo apt install qemu-kvm qemu-utils libvirt-bin libvirt0 libvirt-dev
- vagrant plugin install vagrant-libvirt
- pip install molecule molecule-vagrant docker python-vagrant paramiko
- sudo chmod o+rwx /var/run/libvirt/libvirt-sock
script:
# Check ansible version
- ansible --version
# Check molecule version
- molecule --version
# Basic role syntax check
- ansible-playbook tests/test.yml -i tests/inventory --syntax-check
- molecule test
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/
&lt;/code>&lt;/pre>
&lt;p>My corresponding &lt;code>molecule/default/molecule.yml&lt;/code> looks like the following:&lt;/p>
&lt;pre>&lt;code class="language-yaml">---
dependency:
name: galaxy
driver:
name: vagrant
provider:
name: libvirt
type: libvirt
driver: kvm
options:
memory: 2048
cpus: 2
platforms:
- name: instance
box: ${MOLECULE_DISTRO_BOX:-&amp;quot;&amp;quot;}
interfaces:
- network_name: public_network
dev: &amp;quot;virbr0&amp;quot;
type: &amp;quot;bridge&amp;quot;
mode: &amp;quot;bridge&amp;quot;
provisioner:
name: ansible
log: true
verifier:
name: ansible
&lt;/code>&lt;/pre>
&lt;p>In the future I will try to create a &lt;a href="https://github.com/cookiecutter/cookiecutter" target="_blank" rel="noopener">CookieCutter&lt;/a> template for my roles for easier creation of directory and files layout. Please bear in mind that &lt;a href="https://travis-ci.org" target="_blank" rel="noopener">Travis&lt;/a> is supporting the OSS culture with free access to resources and do not abuse this service.&lt;/p></description></item></channel></rss>