Ansible Role CI for Ceph using Molecule, OpenStack, Ceph-Ansible and GitHub Actions — Part 1
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:
- Create 1 mon server and 3 osd servers in OpenStack
- Install Ceph on the servers using ceph-ansible
- Test the role on the newly created Ceph cluster
- 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