I’m trying to create a molecule scenario where through Vagrant a VM would be created, then the tests would be ran against that. I tried to ask LLMs but they get very confused with the pre-ansible-native vs ansible-native configuration and they are giving me non-sense, so I’m trying my luck here. I understand the ansible-native config of molecule that far that it’s my responsibility to create a create.yml playbook which would spin up a VM through Vagrant.
I can’t find any collection which would be like:
rather I ended up with the solution to execute vagrant like this:
tasks:
- name: Create virtual machine
command:
cmd: vagrant up
# Vagrantfile is in the scenario's directory
chdir: "{{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}"
I think the downside of this approach is that I can’t really register the state “natively” whether the virtual machine is running and ready. Is there a more “native” method to do “molecule test start → ensure virtual machine created via vagrant → ensure virtual machine is running through vagrant” → run tests?
enable_plugins enables the custom vagrant inventory plugin
inventory_plugins tells ansible to look for plugins in the plugins/inventory directory
The create.yml playbook for the molecule scenario should look like the following:
---
- name: Create virtual machine
hosts: localhost
gather_facts: false
tasks:
- name: Start test VM through vagrant
ansible.builtin.command:
cmd: vagrant up
chdir: "{{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}"
register: vagrant_up
changed_when: "'already running' not in vagrant_up.stderr"
- name: Add vm to inventory
ansible.builtin.meta: refresh_inventory
- name: Validate inventory
assert:
that:
- groups['my_machine'] | length > 0
- name: Wait for vm to be ready
hosts: "{{ groups['my_machines'] | map('extract', hostvars, 'inventory_hostname') | list }}"
gather_facts: false
vars:
acceptable_systemd_states:
- running
- degraded
tasks:
- name: Wait for systemd to settle
ansible.builtin.shell: /bin/sh -c 'systemctl is-system-running --wait || systemctl is-system-running'
register: systemd_status
until: systemd_status.rc == 0 or (systemd_status.stdout_lines | last | trim) in acceptable_systemd_states
failed_when: false
changed_when: false
retries: 10
delay: 3
- name: Wait for container PID1 to be ready
ansible.builtin.shell: /bin/bash -lc 'true'
register: _ready
retries: 10
delay: 3
until: _ready is succeeded
This way molecule would start with an empty inventory, during the create phase it would execute vagrant up and with an inventory refresh it will get the hosts from the custom vagrant inventory plugin.