The default validator for Molecule istest infrastructure, but can also be usedbomAs mentioned on its GitHub page, Goss is a YAML-based server spec fallback tool for validating a server's configuration. Since I wanted to use this combination, I had a hard time finding proper documentation and examples. That's why I created this document.
This blog post isn't about Vagrant and Git, so I assume you can start the virtual machine. If you really want to get started right away, make sure Git and Vagrant are installed, then use the following commands to start the virtual machine and install Ansible, Molecule, Goss, and Docker:
Git-Klon https://github.com/rdbraber/ansible_molecule_goss.gitcd ansible_molecule_gossvagrant upvagrant ssh
The test role described in this document is available in the /home/vagrant/roles directory.
For reference, I'll write the steps to install Ansible, Molecule, Goss and Docker. All steps are done with Vagrant account.
Install Molecule and Ansible
We'll install Molecule using pip, a Python package installation tool. First we need to install the python-pip package, with some other requirements we'll need later to install Molecule. The python-pip package is only available onWARM(Extra Packages for Enterprise Linux), so we must first install this repository:
sudo yum install -y epel-releasesudo yum install -y gcc python-pip python-devel openssl-devel
Once the command is finished, we can install Molecule, which will also install Ansible:
sudo pip install --Upgrade des Pipsudo-Pip-Installationsmoleküls
The first command updates pip to the latest version. The second command installs Molecule with some additional packages required by Molecule.
You can try the Ansible version:
[vagrant@molecule ~]$ ansible --versionansible 220.127.116.11 Konfigurationsdatei = Keine konfigurierter Modulsuchpfad = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/module'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executável location = /usr/bin/ansible python version = 2.7.5 (padrão, 4 de agosto de 17 00:39: 18) [GCC 4.8 .5 20150623 (Red Hat 4.8.5-16)]
Try the molecule version:
[Vagabond@Molecule ~]$ Molecule --VersionMolecule, versão 2.5.0
Installation of Goss
Installing Goss is done by getting the install script from the Goss website and running this script:
curl -fsSL https://goss.rocks/install | GOSS_DST=/usr/local/sbinsh
Check out the Goss version:
[bum@molecule ~]$goss --versionGoss-Version v0.3.5
To install Docker, we first need to add the configuration file to the repository. Also, we need to add some additional packages:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.reposudo yum install -y docker -ce
Make sure the docker daemon is started and also after restart:
start sudo systemctl docker activate udo systemctl docker
Check the docker version:
[vagrant@molecule ~]$ sudo docker versionClient: Version: 17.09.1-ce API version: 1.32 Go version: go1.8.3 Git commit: 19e2cf6 Constructed: Thu Dec 7 22:23:40 2017 OS/Arch: linux/amd64Server : Version: 17.09.1-ce API Version: 1.32 (minimum version 1.12) Go Version: go1.8.3 Git Compromise: 19e2cf6 Created: Thu Dec 7 22:25:03 2017 OS/Arch: linux /amd64 Experimental: false
Test that Docker works by running the hello-world container:
sudo docker start hello world
If Docker is installed correctly, Hello from Docker! the message is displayed.
With all the previous steps completed, we can now create a new Ansible function that we can test with Molecule.
To make things a little easier, let's add the roaming user to the groups docker. That way the sudo command doesn't need to be used for the Docker command:
sudo usermod -G docker -a bum
Exit and come back to activate the change. Try running the hello-world container again, but without the sudo command.
Create a new Ansible function
We'll create an Ansible role that will install, configure, and start a web server. After installing the web server, let's test that the web server is installed, configured and working. The function is tested in a Docker container.
First create a roles directory in your home directory and change to this directory:
mkdir ~/functions && cd ~/functions
The new function must be initialized with
Molekül init role --role-name httpd_webserver --verifier-name goss
The directory for the role is created with the following content:
httpd_webserver├── defaults│ └── main.yml├── handlers│ └── main.yml├── meta│ └── main.yml├── Molekül│ └── default─ create ├─ Destroy─ .yml│ ├── Dockerfile.j2│ ├── INSTALL.rst│ ├── Molekül.yml│ ├── Playbook.yml│ ├── Prepare.yml│ ├── Tests│ _default .yml│ verificador.yml├── README.md├── Aufgaben│ └── main.yml├── vars│ └── main.yml└── .yamllint
What you see is a directory called Molecule inside the functions directory. This directory contains all Molecule configuration files. The first file we'll look at is the INSTALL.rst file. This file contains requirements that must be met before you can test the function with Docker:
*******Instalar******Requisitos===============* Docker Engine* docker-pyInstall=======.. code-block::bash $ sudo pip install docker-py
As shown in the file, we need to install the docker-py package:
sudo pip install docker-py
Create the game for the Ansible role
We'll create a role that installs an httpd web server on a CentOS 7 image or container. Next, we need to edit the ~/roles/httpd_webserver/tasks/main.yml file. Add the following content to this file:
---# Task file for httpd_webserver- name: Install httpd package yum: name: httpd status: installed- name: Start the web server and make sure it starts in the startup service: name: httpd status: started enabled: yes- name : configure the web server to run on port 8080 lineinfile: path: /etc/httpd/conf/httpd.conf regexp: '^Listen ' insertafter: '^#Listen ' line: 'Listen 8080 ' notification: start httpd-name : create a test page for the web server line file: path: /var/www/html/test.html owner: apache group: apache mode: 0640 create: yes line: 'page Test'
Also create the handlers file ~/roles/httpd_webserver/handlers/main.yml to ensure that the web server is restarted when a change is made to the configuration file:
---# Driver file for httpd_webserver- Name: restart httpd service: Name: httpd status: restarted
The main configuration file for Molecules is Molecules.yml. One is already stored in the molecular/pattern directory. We need to modify this file so that it can run our tests. Make sure it contains the following entries:
---abhängigkeit: name: galaxydriver: name: dockerlint: name: yamllintplatforms: -name: webserver-test hostname: webserver-test image: couchbase/centos7-systemd command: "/usr/sbin/init" Privileged: Trueprovisioner :name :ansible lint:name:ansible-lintscenario:name:defaultverifier:name:goss habilitado:true
Below is a brief explanation of the settings.
- Dependency – If a role ID depends on other roles, provide a place to get it. In this case, the functions are downloaded from galaxy.ansible.com.
- Rider: What platform did we test our reel on. There are different types of options such as Azure, Amazon EC2, Google Compute Engine (GCE), Vagrant and Docker. In this case, we will test our role in a Docker container.
- lint: which lint we will use for the yaml files.
- Platforms: Specifies the required parameters for the Docker container in this case.Since we want to start the web server in the container using systemd, we need a base container that supports systemd. Another thing to mention is the fact that to run systemd, the container must be running in privileged mode.
- Provisioner: Ansible is currently the only provisioner supported by Molecule. To lint the Ansible playbook we wrote, we'll use ansible-lint.
- Scenario: The molecule can work with different scenarios. The default must always be available.
- verifier: specifies the tool that verifies the result of our playbook. In our case we will use Goss.
All other yaml files in the molecular/standard directory are playbooks used to test the function:
- create.yml – Creates the Docker image used to create a container. The Dockerfile used for this is also in the same directory (Dockerfile.j2).
- Destroy.yml – If tested, this playbook takes care of stopping the container and deleting it.
- plabook.yml: This file contains a reference to the function we want to test.
- Prepare.yml – Can be used to add additional steps if needed before the test can proceed. If Docker is the test controller, this file will not contain any additional steps.
verifier.yml – This playbook takes care of the actual testing of the function. If we use Goss as validator:
- Download Goss and install it in the running container
- Copy the Goss test file from our local machine (molecule/default/test/test_default.yml) to the container
- Run Goss Tests
Create test file for Goss
To test our function, we need to specify which tests we want to run. These tests are located in the molecular/default/tests/test_default.yml file. An example of this type of file is:
---Package: httpd: installed: true versions:- 2.4.6 Service: httpd: enabled: true running: trueprocess: httpd: running: trueport: tcp:8080: listening: truehttp: http://localhost:8080 /test . html: status: 200 body: [testpage] file: /var/www/html/test.html: exists: true mode: "0640" owner: apache group: apache command: httpd -v |grep -i version: exit status :0 stdout: - "Server version: Apache/2.4.6 (CentOS)"
The tests in this file test the following items:
- Package – Check that the httpd package is installed and that it is version 2.4.6.
- service: Make sure the httpd service is running and enabled at startup.
- process: Check if an httpd process is currently running.
- port: Check if there is a service available on port 8080.
- http: Check that the test page's web server is reachable and that the test page contains the correct content.
- File – Verify that the /var/www/html/test.html file exists and has the correct owner, group, and file permissions.
- Command: Use a bash command to check the web server version, check the exit status and submit the command.
Take the Molecule Test
Run the command to test the function
molecular testfrom the function directory. The first output you'll see are all the steps performed during the test:
[vagrant@molecule httpd_webserver]$ molecular test--> test matrix └── pattern ├── fluff ├── destroy ├── dependency ├── syntax ├── create ├── prepare ├── converge ├─ ─ idempotency ─ secondary effect ├── verify └── destroy
- lint: check all yaml files with yamlint
- Destroy: if a container with the same name is already running, destroy that container
- Dependency: If the function depends on other functions, the functions are downloaded
- Syntax: verify function with ansible-lint
- create – Create the Docker image and use that image to launch our test container.
- Prepare – If additional steps are required, they are covered by this step.
- converge: Run the function inside the test container.
- Idempotency: Run the function again to check idempotency. In other words, you can play the role a second time with the same results.
- side_effect – Should test high availability or similar failover scenarios. To seeAnsible Commissions
- Check: Run the Goss tests inside the container.
- Destroy: Destroys the container.
When running the command for the first time, it might take a little longer as we need to download the base image for our own image. If the test runs successfully, you will see the following message at the end of the output:
Verification completed successfully
molecular testThe command tests all steps. It is also possible to test just a few steps. Use the
Molecule - HelpCommand to display the steps that can be tested:
[vagrant@molecule httpd_webserver]$ molecule --help Usage: molecule [OPTIONS] COMMAND [ARGUMENTS]... _____ _ _ | 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 🇧🇷 Molecule helps develop and test Ansible features. Enable autocomplete issue: eval "$(_MOLECULE_COMPLETE=source molecule)"Options: --debug / --no-debug Enables or disables debug mode. The default is disabled. --version Print the version and exit. --help Display this message and exit. Commands: check Use provisioner to test... convert Use provisioner to configure instances... create Use provisioner to launch instances. Dependency Manage role dependencies. Destroy Use the provisioner to destroy instances. idempotency Use the provisioner to configure: init Initialize a new role or scenario. lint Remove the paper. list Displays the status of instances. login Log in to an instance. Prepare Use the provisioner to prepare the instances... side effect Use the provisioner to perform side effects... syntax Use the provisioner to check the syntax of the role. Test Test (Lint, Destroy, Dependency, Syntax,... Verify Runs automated tests on instances.
For example, we could just test the lint function:
[vagrant@molecule httpd_webserver]$ molecule lint--> Test Matrix└── default └── lint--> Scenario: 'default'--> Action: 'lint'--> Running yamllint on files in /home/vagrant /roles/httpd_webserver/... /home/vagrant/roles/httpd_webserver/tasks/main.yml 13:14 Uncited truth warning (true) 29:13 Uncited truth warning (true) /home/ vagrant/roles /httpd_webserver /molecule /default/molecule.yml 13:17 Uncited truth warning (true) 22:12 Uncited truth warning (true)Lint completed successfully. Ignore, no evidence found.--> Run Ansible Lint on /home/vagrant/functions/httpd_webserver/molecule/default/playbook.yml...Lint completed successfully.
If you want to remove the warning messages, you can edit the .yamlint file located at the root of the functions directory. Change it to something like this:
extend: default rules: square brackets: inner maximum space: 1 level: error square brackets: inner maximum space: 1 level: line length error: disable # NOTE (retr0h): Templates no longer fail this fluff rule. # Uncomment when running old Molecules templates. Truth: Disable
For more information about yamllint, see:https://yamllint.readthedocs.io/en/latest/
problems I found
When installing Ansible, Molecule, Goss and Docker components, I had some issues after installing everything. I realized that the order in which things were installed mattered. This was especially true for components installed with pip. The installation order in this document should work.
I had some problems with urllib3 and chardet packages when running
/usr/lib/python2.7/site-packages/requests/__init__.py:80: RequestsDependencyWarning: urllib3 (1.22) or chardet (2.2.1) does not match a supported version! Request Dependency Notice)
I was able to solve it with the following commands:
sudo pip desinstalar -y chardet urllib3sudo pip install --upgrade chardet urllib3