How to test install and uninstall scenario with Molecule for Ansible?
Recommended Solution
The recommended way to address this is using multiple Molecule Scenarios. You could use your install
scenario as the default, and then add a second uninstall
scenario that just runs and tests the uninstall steps.
When setting this up, simply create a second scenario directory in your role's molecule
folder (copy the default
one), and then make some changes:
(Edit: this step was necessary for molecule < 3.0.
scenario.name
was removed in later versions)In the.molecule.yml
file change thescenario.name
attribute touninstall
In the same file, use the
default
scenario'splaybook.yml
file as the playbook for theprepare
step:provisioner:
name: ansible
playbooks:
prepare: ../default/playbook.yml
converge: playbook.ymlAdjust the tests for the
uninstall
scenario to verify the uninstall steps.
This will ensure that the same steps are used for installing the software as in the install/default scenario, and you can focus on the uninstall steps.
To run the scenarios you can either run all of them or a single one:
# Run all scenarios
molecule test --all
# Run only the uninstall scenario
molecule test --scenario-name uninstall
This should get you pretty close to what you want to do, without replicating any code.
If you want to try some other things, here are a couple of other thoughts:
Alternatives
I would keep a scenario for the install only that would play all the needed tests (lint, idempotency, check, verify....) and create an install_uninstall
specific scenario.
Playing install_uninstall
will never be idempotent. So this scenario should disable the idempotency tests that will never pass. You might as well want to disable the check test that is played in your other scenario, lint... This can be done in molecule.yml
by adjusting the parameters for scenario.test_sequence
:
scenario:
name: install_uninstall
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
Of course you can adjust to your real needs (like droping verify also if you have no testinfra tests for this case).
Once this is done you only have to add two plays in your scenario playbook:
---
- name: install
hosts: all
roles:
- role: my_role
install: true
- name: uninstall
hosts: all
roles:
- role: my_role
install: false
And you should be ready to test with:
molecule test -s install_uninstall
Edit:
An other option would be to keep only your current install scenario but launch the individual molecule commands rather than a full test. Assuming your current working scenario is in default
# Check and lint my files
molecule lint
# Make sure no box/container is on the way
molecule destroy
# Create my box/container for tests
molecule create
# Play my default playbook
molecule converge
# Idempotency check
molecule idempotence
# Verify we can correctly use check mode
molecule check
# Play testinfra tests
molecule verify
# Now play the uninstall
molecule converge -- -e install=false
## add more tests you can think off ##
# and finally cleanup
molecule destroy.
Unfortunately, unless this feature was very recently added to molecule, it is not possible to call idempotency
and check
with extra variables
Ansible yum module to install a list of packages AND remove any other packages
Building up on @gary lopez answer to add security and performance.
First you will need to get an actual list of all packages you want to see installed on your final machine, including the default ones that come with the system. I assume that list will be in var yum_rpm
Once you have that, the next step is to get the list of currently installed packages on the machine. To create an actual list we can reuse:
- name: Get installed packages
yum:
list: installed
register: __yum_packages
- name: Make installed packages a list of names
set_fact:
installed_packages: "{{ __yum_packages.results | map(attribute='name') | list }}"
From there, adding and removing is just a matter of making a difference on lists. The goal here is to avoid looping on the yum module package by package (because it is damn slow and listed as a bad practice on the module documentation page) and to make the install and remove operations in one go.
- name: align packages on system to expected
yum:
name: "{{ item.packages }}"
state: "{{ item.state }}"
loop:
- packages: "{{ yum_rpm | difference(installed_packages) }}"
state: present
- packages: "{{ installed_packages | difference(yum_rpm) }}"
state: absent
when: item.packages | length > 0
Related Topics
Saving Numpy Array to Txt File Row Wise
How to Stop Execution of All Cells in Jupyter Notebook
Clearing All Labels from a Tkinter Window
How to Iterate Over a Timespan After Days, Hours, Weeks and Months
Search and Replace a Line in a File in Python
How to Remove Additional Commas in a List in Python
Merging Two Dataframes With Different Lengths
How to Get Current Cpu and Ram Usage in Python
Create a New Dataframe Based on Rows With a Certain Value
High Pass Filter for Image Processing in Python by Using Scipy/Numpy
Getting the Id of the Last Record Inserted for Postgresql Serial Key With Python
Pandas - Replace Outliers With Groupby Mean
Adding Columns to Dataframe Based on File Name in Python
Loop Over List of Elements for Find_Element_By_Xpath() by Selenium and Webdriver
Python Key Error=0 - Can't Find Dict Error in Code
How to Disable the Security Certificate Check in Python Requests