Bootstrap FreeKB - Ansible - Getting Started with Molecule
Ansible - Getting Started with Molecule

Updated:   |  Ansible articles

Let's create a Python virtual environment named poc.

python3 -m venv poc

 

Let's activate the Python virtual environment.

source poc/bin/activate

 

Let's upgrade pip in the Python virtual environment and install molecule.

pip install --upgrade pip
pip install molecule

 

The pip list command should now show that the molecule CLI is installed in the Python virtual environment.

~]$ pip list
Package                   Version
------------------------- ---------
ansible-compat            25.1.5
ansible-core              2.18.4
attrs                     25.3.0
bracex                    2.5.post1
cffi                      1.17.1
click                     8.1.8
click-help-colors         0.9.4
cryptography              44.0.2
enrich                    1.2.7
Jinja2                    3.1.6
jsonschema                4.23.0
jsonschema-specifications 2024.10.1
markdown-it-py            3.0.0
MarkupSafe                3.0.2
mdurl                     0.1.2
molecule                  25.4.0
packaging                 24.2
pip                       25.0.1
pluggy                    1.5.0
pycparser                 2.22
Pygments                  2.19.1
PyYAML                    6.0.2
referencing               0.36.2
resolvelib                1.0.1
rich                      14.0.0
rpds-py                   0.24.0
subprocess-tee            0.4.2
typing_extensions         4.13.1
wcmatch                   10.0

 

Let's ensure the molecule CLI is working.

~]$ molecule --version
molecule 25.4.0 using python 3.12
    ansible:2.18.4
    default:25.4.0 from molecule

 

Let's create a new collection called foo.bar.

cd poc/
ansible-galaxy collection init foo.bar

 

The foo/bar directory should contain some files and directories.

]$ ls -l foo/bar/
total 8
drwxr-xr-x. 2 john.doe users    6 Apr  3 23:20 docs
-rw-r--r--. 1 john.doe users 3089 Apr  3 23:20 galaxy.yml
drwxr-xr-x. 2 john.doe users   25 Apr  3 23:20 meta
drwxr-xr-x. 2 john.doe users   23 Apr  3 23:20 plugins
-rw-r--r--. 1 john.doe users   66 Apr  3 23:20 README.md
drwxr-xr-x. 2 john.doe users    6 Apr  3 23:20 roles

 

Let's create a role named my_role.

~]$ cd foo/bar/roles/
~]$ ansible-galaxy role init my_role
- Role my_role was created successfully

 

Let's update main.yml in my_role to contain something simple.

]$ cat my_role/tasks/main.yml
---
- ansible.builtin.debug:
    msg: "Hello World"

 

Let's create a playbook that will include my_role in the foo/bar directory.

]$ cat my_playbook.yml
---
- hosts: localhost
  gather_facts: false
  tasks:
  - name: include_role my_role main.yml
    ansible.builtin.include_role:
      name: my_role
      tasks_from: main.yml
...

 

The foo/bar directory should now include my_playbook.yml.

]$ ls -l foo/bar/
drwxr-xr-x. 2 john.doe users    6 Apr  3 23:20 docs
-rw-r--r--. 1 john.doe  users 3089 Apr  3 23:20 galaxy.yml
drwxr-xr-x. 2 john.doe users   25 Apr  3 23:20 meta
-rw-r--r--. 1 john.doe users  187 Apr  3 23:26 my_playbook.yml
drwxr-xr-x. 2 john.doe users   23 Apr  3 23:20 plugins
-rw-r--r--. 1 john.doe users   66 Apr  3 23:20 README.md
drwxr-xr-x. 3 john.doe users   21 Apr  3 23:22 roles

 

Running the playbook should return something like this.

]$ ansible-playbook my_playbook.yml
PLAY [localhost] 

TASK [include_role my_role main.yml] 
included: my_role for localhost

TASK [my_role : ansible.builtin.debug] 
ok: [localhost] => {
    "msg": "Hello World"
}

PLAY RECAP 
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Let's create a directory named extensions in the foo/bar directory.

mkdir extensions

 

The foo/bar directory should now include the extensions directory.

]$ ll foo/bar/
total 12
drwxr-xr-x. 2 john.doe users    6 Apr  3 23:20 docs
drwxr-xr-x. 3 john.doe users   22 Apr  3 23:28 extensions
-rw-r--r--. 1 john.doe  users 3089 Apr  3 23:20 galaxy.yml
drwxr-xr-x. 2 john.doe users   25 Apr  3 23:20 meta
-rw-r--r--. 1 john.doe users  187 Apr  3 23:26 my_playbook.yml
drwxr-xr-x. 2 john.doe users   23 Apr  3 23:20 plugins
-rw-r--r--. 1 john.doe users   66 Apr  3 23:20 README.md
drwxr-xr-x. 3 john.doe users   21 Apr  3 23:22 roles

 

Let's move into the extensions directory and run the molecule init scenario command. Something like this should be returned.

]$ cd extensions
]$ molecule init scenario
INFO     Initializing new scenario default...

PLAY [Create a new molecule scenario] ******************************************

TASK [Check if destination folder exists] **************************************
changed: [localhost]

TASK [Check if destination folder is empty] ************************************
ok: [localhost]

TASK [Fail if destination folder is not empty] *********************************
skipping: [localhost]

TASK [Expand templates] ********************************************************
changed: [localhost] => (item=molecule/default/converge.yml)
changed: [localhost] => (item=molecule/default/create.yml)
changed: [localhost] => (item=molecule/default/destroy.yml)
changed: [localhost] => (item=molecule/default/molecule.yml)

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

 

The extensions/molecule directory should now contain a few YAML files.

]$ ls -l foo/bar/extensions/molecule/default/

-rw-r--r--. 1 john.doe users  203 Apr  3 23:28 converge.yml
-rw-r--r--. 1 john.doe users 1182 Apr  3 23:28 create.yml
-rw-r--r--. 1 john.doe users  622 Apr  3 23:28 destroy.yml
-rw-r--r--. 1 john.doe users  206 Apr  3 23:28 molecule.yml

 

Let's update the converge.yml file to test the main.yml file in my_role.

---
- name: converge
  hosts: localhost
  gather_facts: false
  tasks:
    - name: converge my_role main.yml
      ansible.builtin.include_role:
        name: my_role
        tasks_from: main.yml

 

Let's create the ANSIBLE_ROLES_PATH environment variable to point the the roles directory that contains my_role.

export ANSIBLE_ROLES_PATH=/home/john.doe/poc/foo/bar/roles/

 

From the extensions directory, you can now run molecule commands. Let's run the molecule converge command which will invoke the converge.yml playbook. In this example, since there are no issues in main.yml in my_role, converge did not raise any issues. Cool.

]$ molecule converge

INFO     Running default > converge

PLAY [converge] ****************************************************************

TASK [converge my_role main.yml] ***********************************************
included: my_role for localhost

TASK [my_role : ansible.builtin.debug] *****************************************
ok: [localhost] => {
    "msg": "Hello World"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 9d8c4e in the box below so that we can be sure you are a human.