Ansible Role CI for Ceph using Molecule, OpenStack, Ceph-Ansible and GitHub Actions — Part 1

Kevin Coakley
4 min readApr 27, 2020

--

Part 1: Configuring Molecule OpenStack Driver

Part 2: Install Ceph on the servers using ceph-ansible
Part 3: Automatically run the Molecule test using GitHub Actions and OpenStack

Molecule is a powerful testing tool for Ansible. The default Docker driver for testing Ansible roles works well for the majority of Ansible roles that I have created. However, there are some roles that cannot be tested using Docker, like Ansible roles that require hardware or complex server/networking configurations that Docker cannot emulate. For these Ansible roles, it may be necessary to create your own environment on a cloud computing provider in order to test and integrate into your CI workflows.

For this example, I will be testing an Ansible role that will mange Pools for the Ceph distributed object store. I will need to have a healthy Ceph cluster with 1 monitor/manger server and 3 storages servers, each with one volume (virtual hard drive) attached. I will be using OpenStack to create the testing infrastructure but AWS, GCE and Azure could also be used. Molecule has a community supported driver for OpenStack that is still the in early stages of development, but works with a little bit of tweaking. There are Molecule drivers for all of the big cloud computing providers. Once the Molecule tests have been created, they will be executed on the GitHub Actions CI infrastructure every time there is a new commit to the git repository.

The CI Workflow steps that Molecule needs to execute in order to test the Ansible role are as follows:

  1. Create 1 mon server and 3 osd servers in OpenStack
  2. Install Ceph on the servers using ceph-ansible
  3. Test the role on the newly created Ceph cluster
  4. Clean up all resources created in OpenStack from step #1

This first part will cover steps #1 and #4. Part two will cover step #2 and the final part will cover how to integrate the 4 steps with GitHub Actions.

First, I will install Molecule and the Molecule OpenStack driver then I will initialize a new Ansible role using the Molecule OpenStack driver:

pip install molecule molecule-openstackmolecule init role -d openstack role-name

Note: The latest version of the molecule-openstack is 0.1 at the time of publishing this story.

The molecule init command creates the basic Ansible role files. In this first part, I will only be concerned with the create.yml, destroy.yml, and molecule.yml files in the molecule directory.

└── molecule
└── default
├── INSTALL.rst
├── converge.yml
├── create.yml
├── destroy.yml
├── molecule.yml
├── prepare.yml
└── verify.yml

First, I will update the platforms section of molecule.yml in order to specify the 1 mon server and 3 osd servers. The image and flavor variables need to be updated with the values from your OpenStack provider.

platforms:
- name: "mon-1"
image: CentOS 7.6 x86_64
flavor: m1.medium
- name: "osd-1"
image: CentOS 7.6 x86_64
flavor: m1.medium
- name: "osd-2"
image: CentOS 7.6 x86_64
flavor: m1.medium
- name: "osd-3"
image: CentOS 7.6 x86_64
flavor: m1.medium

Next, I will update the create.yml in order to fix some issues with the template that is provided by the Molecule OpenStack driver and to add 1 data volume to each of the osd servers.

Update the ssh_user variable with the correct username for the image specified in molecule.yml:

     ssh_user: centos

I renamed the neutron_network_name variable to network_name, entered the proper value for my OpenStack provider and updated the os_server statement for nics to use the network_name variable:

network_name: private_network- name: Create molecule instance(s)
os_server:
name: "{{ item.name }}"
image: "{{ item.image }}"
flavor: "{{ item.flavor }}"
security_groups: "{{ security_group_name }}"
key_name: "{{ keypair_name }}"
nics:
- net-name: "{{ network_name }}"
register: server
with_items: "{{ molecule_yml.platforms }}"
async: 7200
poll: 0

I removed the nova_image and nova_flavor variables and the os_network_facts statment since they didn’t seem to be doing anything:

   
< nova_image: Ubuntu-16.04
< nova_flavor: NO-Nano
< - name: Gather facts about network for use with instance crea
< os_networks_facts:
< name: "{{ neutron_network_name }}"

I added the os_volume statement to create 10GB volumes for the servers defined in the platforms section of molecule.yml that have the string osd in the name:

- name: Create OSD volumes
os_volume:
state: present
size: 10
display_name: "{{ item.name }}"
when: '"osd" in item.name'
with_items: "{{ molecule_yml.platforms }}"

Finally, I updated destroy.yml in order to remove the osd volumes created in create.yml when Molecule is done running:

- name: Delete OSD volumes
os_volume:
state: absent
size: 10
display_name: "{{ item.name }}"
when: '"osd" in item.name'
with_items: "{{ molecule_yml.platforms }}"

With those changes, when I run molecule test from the command line, Molecule should create 1 mon server and 3 osd servers in OpenStack with volumes attached to the 3 osd servers and remove all of the resources before completing.

In the next part I will describe how to install Ceph on the servers created from create.yml using ceph-ansible via prepare.yml file.

The full repository of all of the code is at https://github.com/kevincoakley/ansible-role-ceph-pools

--

--