I have the problem where my default values are normally stored in defaults/main.yml
for running ansible scripts but I have not found a way to override them. I am using molecule to test, and I want a method of passing in variables into my molecule/default/molecule.yml
or to molecule/default/playbook.yml
so that I can dynamically set phpVersion
.
# defaults/main.yml
phpVersion: 7.0
#tasks/main.yml
---
- name: Check if OS is Ubuntu LTS
fail: msg="Server must be Ubuntu LTS"
when: ansible_distribution != 'Ubuntu'
or (ansible_distribution_version != '14.04'
and ansible_distribution_version != '16.04'
and ansible_distribution_version != '18.04')
- name: Get default PHP version
shell: >
set -o pipefail && \
/usr/bin/php -v | grep 'PHP '
register: php_installed_default_version
failed_when: false
changed_when: false
- name: Add ondrej repo to allow multiple PHP versions
apt_repository:
repo: "ppa:ondrej/php"
update_cache: yes
- name: Include php version specific playbook
include_tasks: "php{{ item }}.yml"
with_items: "{{ php_versions }}"
when: php_versions is defined
- name: Set default PHP version to 7.0 (PHP CLI)
shell: update-alternatives --set php /usr/bin/php{{ phpVersion }}
register: command_result
when: phpVersion == 7.0
and php_installed_default_version is defined
and php_installed_default_version.stdout is defined
and (not php_installed_default_version.stdout | regex_search("PHP 7\.0"))
changed_when: command_result.stdout == "to provide"
- name: Set default PHP version to 7.1 (PHP CLI)
shell: update-alternatives --set php /usr/bin/php{{ phpVersion }}
register: command_result
when: phpVersion == 7.1
and php_installed_default_version is defined
and php_installed_default_version.stdout is defined
and (not php_installed_default_version.stdout | regex_search("PHP 7\.1"))
changed_when: command_result.stdout == "to provide"
- name: Set default PHP version to 7.2 (PHP CLI)
shell: update-alternatives --set php /usr/bin/php{{ phpVersion }}
register: command_result
when: phpVersion == 7.2
and php_installed_default_version is defined
and php_installed_default_version.stdout is defined
and (not php_installed_default_version.stdout | regex_search("PHP 7\.2"))
changed_when: command_result.stdout == "to provide"
# find out what update alternatives spits out and parse some of that through the registered variable: did this task change or not.
- name: Set default PHP version to 7.3 (PHP CLI)
shell: update-alternatives --set php /usr/bin/php{{ phpVersion }}
register: command_result
when: phpVersion == 7.3
and php_installed_default_version is defined
and php_installed_default_version.stdout is defined
and (not php_installed_default_version.stdout | regex_search("PHP 7\.3"))
changed_when: command_result.stdout == "to provide"
so to run my tests I enter this command:
$ MOLECULE_DISTRO=ubuntu1804-php70 molecule test --destroy=never
# molecule/default/molecule.yml
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
options:
config-data:
ignore: venv
platforms:
- name: instance
image: "superelectron/docker-ubuntu-ansible-php:${MOLECULE_DISTRO:-ubuntu1804-php70}"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
pre_build_image: true
instance_raw_config_args:
- "vm.network 'forwarded_port', guest: 80, host: 8088"
provisioner:
name: ansible
log: true
lint:
name: ansible-lint
verifier:
name: testinfra
lint:
name: flake8
# molecule/default/playbook.yml
---
- name: Converge
hosts: all
roles:
- role: ansible-role-php
vars:
phpVersion: 7.0
From molecule.yml
and playbook.yml
you can see how GREAT it would be to pass something like this to set the phpVersion:
phpVersion=7.0 MOLECULE_DISTRO=ubuntu1804-php70 molecule test --destroy=never
and to have playbook.yml set a variable like this:
vars:
phpVersion: ${phpVersion}
The question is, how can I dynamically set a variable used in tasks/main.yml with molecule so that my tests dynamically set phpVersion?
Edit: it might actually be possible to do better than below but I didn't get time to test it fully. Solution below is still valid. Choose the best one for you.
You can actually pass env vars to the molecule ansible provisionner from molecule.yml
(see doc which itself accepts env vars for templating with fallback to default values.
Here is the new idea. It is cleaner in the molecule playbook that solution below but needs two different env vars (one for the command line and the over one passed by molecule to the playbook).
In molecule.yml
provisioner:
name: ansible
log: true
lint:
name: ansible-lint
env:
MY_PHP: ${MOLECULE_PHP:-"7.0"}
In your molecule playbook:
vars:
phpVersion: "{{ lookup('env', 'MY_PHP') }}"
And your commands:
# Default
molecule converge
# Override
MOLECULE_PHP=7.4 molecule converge
This is one solution. It has two minor drawbacks:
env
lookup returns an empty string for inexistant env vars. You cannot use the default
filters so looking for fallback value is a little more verboseIn your molecule playbook:
vars:
phpOverride: "{{ lookup('env', 'MY_PHP') }}"
phpVersion: "{{ (phpOverride | length > 0) | ternary(phpOverride, '7.0') }}"
And on your command line:
# For default value
molecule converge
# With override
MY_PHP=7.4 molecule converge