We're using Ansible for a lot of our deployments. This agent-less configuration management tool requires almost no overhead, and this low barrier to entry enables people from our community to contribute deployment code. So far so good.
The Ansible code has seen a few major changes over the last years, which unfortunately cause some features to change, disappear, or even break.
It is impractical to refactor large projects to work with the latest Ansible version, so there is a need to use specific Ansible versions for specific deployments.
On MacOS I use the HomeBrew package manager to provide me with Ansible, and this works OK. Switching between different Ansible versions is possible, but in practise this is only works if you have cached the old version, i.e. you have been installing and updating versions continuously. Picking a random older version is very tedious at best.
Enter Python's virtualenv.
This allows you to isolate a complete python environment, and install a specific version of Ansible. With the help of some bash aliases you can conveniently switch between all versions.
Assuming you have the required basic tools available, run this bash script:
#!/usr/bin/env bash # Maintains a directory of Ansible virtual environments, and # an accompanying snippet of bash aliases to activate them. # Put the following into your .bash_rc to be able to use the aliases: # source ~/.bash_ansible BASH_SNIPPET="$HOME/.bash_ansible" ANSIBLES="$HOME/.ansible_virtualenvs" # Update this to keep regularly to have the latest of each minor version VERSIONS="2.1.6 2.2.3 2.3.3 2.4.6 2.5.10 2.6.6 2.7.0" # Needed for the projects we work on MODULES="python-keyczar jmespath netaddr dnspython boto botocore boto3 natsort" # Switch between different python versions. Remember to wipe the old virtualenvs if you do this. PYTHON="python" if [ ! -d "$ANSIBLES" ]; then echo "Ansible collection directory $ANSIBLES does not exist yet, creating it." mkdir -v $ANSIBLES fi echo "# Generated at `date` from $0" > $BASH_SNIPPET for v in $VERSIONS; do virtualenv -p "$PYTHON" "$ANSIBLES/ansible-$v" source "$ANSIBLES/ansible-$v/bin/activate" pip install ansible==$v $MODULES deactivate echo "alias ansible-activate-$v='source $ANSIBLES/ansible-$v/bin/activate'" >> $BASH_SNIPPET done
When this finishes, open up a new terminal and start typing ansible-activate
and use tab completion to pick the specific version
Obviously you can use ansible to install ansible - for instance onto a deployment VM or bastion host:
--- - name: Different Ansible versions become: true hosts: bastions vars: ansible_versions: - "2.3.3" - "2.4.4" - "2.5.2" virtualenv_basepath: /opt/virtualenvs tasks: - name: Ensure basic packages are installed package: name: "{{ item }}" state: present with_items: - python-pip - python-virtualenv - git - name: Ensure ansible versions are available in virtualenv pip: name: ansible virtualenv: "{{ virtualenv_basepath }}/ansible-{{ item }}" version: "{{ item }}" with_items: "{{ ansible_versions }}" - name: Ensure system wide activation aliases are available copy: dest: /etc/profile.d/ansible_virtualenvs.sh content: "{% for i in ansible_versions %}alias ansible-activate-{{ i }}='source {{ virtualenv_basepath }}/ansible-{{ i }}/bin/activate'\n{% endfor %}"