Migrate Molecule for Ansible pipeline from Travis.ci to Github Actions
Tags: ansible, molecule, github, actions
Published: 2021-02-07 13:09:58

I decided to migrate from Travis.ci to GitHub actions because I had spent all credits and couldn't renew them. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8332pfj9k82j9r07c2rm.png)
Before migration my ci/cd configuration look like:
```yaml
---
language: python
python: '3.6'

env:
  global:
    - MOLECULEW_USE_SYSTEM=true
  matrix:
    # Spin off separate builds for each of the following versions of Ansible
    - MOLECULEW_ANSIBLE=2.8.18
    - MOLECULEW_ANSIBLE=2.9.16
    - MOLECULEW_ANSIBLE=2.10.4

# Require Ubuntu 20.04
dist: focal

# Require Docker
services:
  - docker

install:
  # Install dependencies
  - ./moleculew wrapper-install

  # Display versions
  - ./moleculew wrapper-versions

script:
  - ./moleculew test

branches:
  only:
    - master
    - /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)([\.\-].*)?$/

notifications:
  webhooks: https://galaxy.ansible.com/api/v1/notifications/
```

And the molecule configuration:
```yaml
---
dependency:
  name: galaxy

driver:
  name: docker

lint: |
  set -e
  yamllint .
  ansible-lint
  flake8
platforms:
  - name: ansible-role-oh-my-zsh-debian-9
    image: debian:9
  - name: ansible-role-oh-my-zsh-debian-10
    image: debian:10
  - name: ansible-role-oh-my-zsh-ubuntu-16.04
    image: ubuntu:16.04
  - name: ansible-role-oh-my-zsh-ubuntu-18.04
    image: ubuntu:18.04
  - name: ansible-role-oh-my-zsh-ubuntu-20.04
    image: ubuntu:20.04
  - name: ansible-role-oh-my-zsh-centos-7
    image: centos:7
  - name: ansible-role-oh-my-zsh-centos-8
    image: centos:8
  - name: ansible-role-oh-my-zsh-fedora-32
    image: fedora:32
  - name: ansible-role-oh-my-zsh-fedora-33
    image: fedora:33
  - name: ansible-role-oh-my-zsh-opensuse-15.1
    image: opensuse/leap:15.1
  - name: ansible-role-oh-my-zsh-opensuse-15.2
    image: opensuse/leap:15.2

provisioner:
  name: ansible

verifier:
  name: testinfra
```
These files available in my repository and actual for release version [2.4.1](https://github.com/tutunak/ansible-role-oh-my-zsh/releases/tag/2.4.1)

Following GitHub Actions setup guide, I've created a file structure for my future pipeline
```
  .github/
    workflows/
      ci.yml
```
And take like the example one's of [geerlingguy](https://github.com/geerlingguy) repository I've made a action ci file:
```yaml
---
name: CI
'on':
  pull_request:
  push:
    branches:
      - master
jobs:
  test:
    name: Molecule
    runs-on: ubuntu-latest
    strategy:
      matrix:
        ansible:
          - 2.8.18
          - 2.9.16
          - 2.10.4
    steps:
      - name: Check out the codebase.
        uses: actions/checkout@v2
      - name: Set up Python 3.
        uses: actions/setup-python@v2
        with:
          python-version: '3.x'
      - name: Install test dependencies.
        run: pip3 install ansible==${{ matrix.ansible }}  molecule[docker] docker testinfra yamllint ansible-lint flake8
      - name: Run Molecule tests.
        run: molecule test
        env:
          PY_COLORS: '1'
          ANSIBLE_FORCE_COLOR: '1'

```
Let's look closer at each part of this file. 

First is the configuration that describes when we will be run our pipeline. It'll be run on all pull requests or push to master branch
```yaml
---
name: CI
'on':
  pull_request:
  push:
    branches:
      - master
```

Next, is the jobs description. In my case, there is only one `test`. I gave the name for this job and setup os version `ubuntu-latest`. And the matrix part for the strategy is similar to the Travis.ci syntax. 

```yaml
jobs:
  test:
    name: Molecule
    runs-on: ubuntu-latest
    strategy:
      matrix:
        ansible:
          - 2.8.18
          - 2.9.16
          - 2.10.4
```
Steps:
```yaml
    steps:
      - name: Check out the codebase.
        uses: actions/checkout@v2
      - name: Set up Python 3.
        uses: actions/setup-python@v2
        with:
          python-version: '3.x'
      - name: Install test dependencies.
        run: pip3 install ansible==${{ matrix.ansible }}  molecule[docker] docker testinfra yamllint ansible-lint flake8
      - name: Run Molecule tests.
        run: molecule test
        env:
          PY_COLORS: '1'
          ANSIBLE_FORCE_COLOR: '1'
```
This step executes the Github action that checkout repository. 
```yaml
      - name: Check out the codebase.
        uses: actions/checkout@v2
```
The next one installs ansible.
```yaml
      - name: Set up Python 3.
        uses: actions/setup-python@v2
```
And step that installs dependencies.
```yaml
      - name: Install test dependencies.
        run: pip3 install ansible==${{ matrix.ansible }}  molecule[docker] docker testinfra yamllint ansible-lint flake8
```
`ansible==${{ matrix.ansible }}`  - installs different ansible version for each environment.

The final step runs molecule
```yaml
      - name: Run Molecule tests.
        run: molecule test
        env:
          PY_COLORS: '1'
          ANSIBLE_FORCE_COLOR: '1'

```
`PY_COLORS: '1'`: This forces Molecule to use the colorized output in the CI environment. Without it, all the output would be white text on a black background.
`ANSIBLE_FORCE_COLOR: '1'`: This does the same thing as PY_COLORS, but for Ansible’s playbook output.