An Ansible role tested with Molecule in Gitpod

I’m mainly a Java developer and still haven’t found a way to use Gitpod for Java development. Gitpod allows you to spin up fresh development environments from your GitHub projects so that you can code with Visual Studio on the web (that’s just a very reductive definition, so you may want to look at its website for the complete set of features). I honestly prefer to have my IDE (Eclipse) on my computer.

However, I probably found a use case for Gitpod that’s also good for me! I recently started playing and having fun with Ansible to automate all my Linux installations. I’m also test-addicted and want to test my Ansible playbooks and roles automatically. For testing Ansible playbooks and roles, I use the mainstream technology Molecule. Molecule allows you to thoroughly test Ansible tasks by running them against a Docker container. (I’ll blog about my Ansible playbooks, roles, and how I use Molecule shortly.)

Once you have Docker installed on your system, setting up Ansible and Molecule is not hard. However, due to the used technologies, running Molecule tests stresses your computer a bit due to disk usage (because of Docker images and containers; also because Molecule allows you to test Ansible tasks against different Docker images) and due to computational power. Indeed, it would be best if you had a powerful computer to use Molecule. I don’t always have one with such computation power with me; if I have, I might need that with some concurrent development tasks.

That gave me a chance to evaluate Gitpod for the task of testing an Ansible role with Molecule on Gitpod. In this blog post, I’ll detail, step by step, how I set up my Gitpod development environment for this job. The Ansible role used in this example is trivial and is not the post’s goal.

On my computer, I install Ansible and Molecule (with Docker support) with the following pip command:

Then I create an Ansible role ready to be tested with Molecule as follows:

I created a Git repository and pushed that to GitHub:

To access Gitpod easily from a GitHub repository, I installed the Gitpod browser extension.

Now, I can start Gitpod for this repository using the button (as I said, you need to use a browser extension; otherwise, you have to prefix the URL appropriately):

Let’s press the “Gitpod” button. The first time you use Gitpod, you’ll have to accept a few authorizations.

NOTE: in this blog post, I’m using the light theme of Visual Studio in Gitpod.

Once the Visual Studio code was open in the browser, I was welcomed by a “Get Started with Gitpod”:

First, let’s set up the main developer tools in the Gitpod workspace (a Linux OS): Ansible and Molecule. We’ll install them using Python Pip (as I’ve done on my local machine), which is already available in Gitpod.

In the Visual Studio terminal, I run:

The above command will take about a minute to terminate (we’ll get back to this later)

Then, we can verify that molecule (and ansible) are installed:

Now we can run Molecule from within the Gitpod workspace. We can try and run “molecule converge” (though our Ansible role doesn’t do anything at the moment). After that, we can enter the container with “molecule login” (from the generated molecule/default/molecule.yml file, we can see that it’s based on the Docker image ““):

Instead of running “converge”, we can let Molecule create the Docker image with “molecule create“. We would still be able to enter the Docker image as above.

Let’s stop the workspace:

(To close a workspace, we could close the workspace browser tabs: within three minutes, the workspaces will be stopped.)

If we get back to Gitpod and create a new workspace (that is, we don’t use the Gitpod dashboard to restart the workspace we have just stopped), we will lose the installed programs ansible and molecule. Let’s make the installation of these tools permanent, so we’ll find them each time we start a Gitpod workspace for this GitHub project.

To do that, let’s run “gp init“. This command will create a new .gitpod.yml file (with some example contents; see the documentation for more details about this file) where we can configure the workspace for our project. This configuration will be stored in the git repository of this project. Once this file is in place, Gitpod will pre-configure our workspace each time we enter Gitpod for the current project.

I’m changing the file as follows:

As written in the documentation:

To test your .gitpod.yml file, you need to commit and push the file to your repository and open a new workspace either by using the Gitpod extension or prefixing your repo URL with

If you don’t want to have multiple commits as you’re testing and making changes to your .gitpod.yml, you can make changes from a new branch.

For the moment, let’s commit and push directly to the master or main branch (of course, by using Visual Studio):

Let’s stop the workspace and get back to Gitpod. We will see the output of our “init” command, and Ansible and Molecule will be available.

However, from what I understand, for installing programs that are indispensable during development, instead of using an “init” task, it’s better to provide a custom Docker image with the programs already installed.

To do that, we add this section to the .gitpod.yml file:

Then, we create the file .gitpod.Dockerfile. As soon as the file is created and opened, Visual Studio suggests we install the Docker extension in Visual Studio:

Let’s choose “Install Do not Sync”. Once the extension has been installed, we can use the gear icon and specify to add the extension to the .gitpod.yml file:

The file will be automatically modified with the following new section:

This way, each time we open the workspace of the project or someone else does (e.g., for contributing), the Docker extension will be automatically available.

Let’s implement the Dockerfile by starting from the full Gitpod workspace image (the one we have used so far because it’s the default image) and by installing Ansible and Molecule in the Docker image:

Note: Gitpod suggests using a specific tag instead of “latest” to help the reproducibility of the workspace. For this simple example, we’ll simply use “latest”.

Now that we have a custom Dockerfile for the image of our Gitpod workspace, instead of stopping the workspace and opening a new one, it might be better first to verify whether we can build such an image (remember, in Gitpod, you have docker available after all):

Then, we can enter that image and verify that our desired programs are installed:

Doing such a check before starting a new workspace lets us immediately spot possible problems with our custom image.

You notice that building the Docker image takes a lot of time. That’s because we started from the full Gitpod base Docker image (a big image), which contains support for several languages. We’ll optimize this later.

We remove the “init” task from the .gitpod.yml file. However, we can use a “before” task specific to this project (the pip packages are typical of Ansible and Molecule projects). We have Molecule create the Docker instance (see the molecule.yml file shown above in the screenshot). This will make the Docker image used in our Molecule tests already pulled when we open the workspace:

To summarize, this is the .gitpod.yml file (note that I also added the Gitlens extension, which is very useful for Git repositories):

We can start a new workspace. Now Gitpod knows about our custom Dockerfile and builds that image for us. In particular, whenever we start Gitpod for this repository, Gitpod checks whether the Dockerfile has been updated and rebuilds the image if needed. Thus, building our custom Docker image will take some time only the first time, and if we change the Dockerfile.

When the workspace start, we’ll see Gitpod building our image:

Similarly to when we built our custom Docker image in the workspace, this will take some time because we start from the vast “workspace-full” image.

Maybe we can do better and start from the Gitpod workspace image that provides only Python support. After all, for this project, that’s all we need (we don’t need Java, C++, etc.):

I also took the chance to update Pip itself. In the previous runs, I had seen such a message:

As done before, let’s first check that the image builds fine locally and that, in the end, it contains our required software.

We can start a new workspace. Gitpod realizes that our Dockerfile has changed and rebuilds it. This time, this should be faster.

It took some time, but now we have an IDE for our project on the web. The files we have created can be reused for similar projects. For projects using different languages, the customization will be different.

We can start implementing the tasks for our role. For example, let’s edit the file tasks/main.yml. In this example, we want to install ZSH:

Let’s save, and run “molecule converge” (remember, the Docker image for our molecule test has already been downloaded during the workspace opening). We’ll get an error:

That’s because “sudo”, which is required by our task (“become: true”), is not installed in the Docker image we use for testing (““). We can prepare our instance with a molecule/default/prepare.yml playbook or use another RedHat-based Docker image, which already comes with “sudo”, e.g., “fedora:36”. For this simple example, I’ll go with the latter solution. We change molecule/default/molecule.yml accordingly:

Since we have now changed the Docker image for Molecule tests, we must first “destroy” the current Molecule image (“molecule destroy“) and then try to “molecule converge” (this time, a new Docker image will be downloaded). Now “converge” should succeed. We can also run a complete Molecule scenario with the command “molecule test” (this will also check idempotency and verify possible assertions; currently, we don’t have any assertions).

We can also add a badge to the README of the GitHub repository to quickly jump to Gitpod. That’s useful for contributors who don’t have the Gitpod extension. The markdown code for the badges can be found at For this project, I add this markdown code to the README file:

You may want to experiment with other Visual Studio extensions like the “Ansible” extension. If you install that, you’ll get a warning of the shape:

That’s because we haven’t installed the command “ansible-lint”. We can do that with Pip. We should also update our custom Docker image accordingly. I will not do that for this simple example, though.

That’s all for now. I hope you found this post useful to get started with Gitpod 🙂

2 thoughts on “An Ansible role tested with Molecule in Gitpod

  1. Pingback: My Ansible Role for “Oh My Zsh” and other CLI programs | Lorenzo Bettini

  2. Pingback: Java, Maven and Gitpod: Getting Started | Lorenzo Bettini

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.