Vagrant - Multi-Group Ansible Provisioning
Refreshed June 2026: the Vagrant
ansible.groupsmechanism shown here still works the same way, so the core of the post is unchanged. What needed updating was the example playbook (FQCN, list arguments,community.mysqlmodules, current PHP packages instead of the long-deadphp5) and the generated inventory, which modern Vagrant writes withansible_hostrather than the oldansible_ssh_host.
Background
I keep a common Vagrantfile across scenarios and only adjust variables per scenario. One of those variables defines the Ansible groups each box lands in. This post spins up 5 boxes and places them into several Ansible groups. If you want the full base Vagrantfile, see my complex Vagrantfile post.
Defining The Groups
Bump the node count from 1 to 5:
N = 5
Then define the group mapping. A node can appear in more than one group:
ansible_groups = {
"db-nodes" => [
"node0"
],
"test-nodes" => [
"node3"
],
"random-nodes" => [
"node[4:#{N-1}]"
],
"mixed-nodes" => [
"node1",
"node4"
],
"renamed-nodes" => [
"node1"
]
}
After vagrant up, the generated Ansible inventory looks like this. Note the modern connection variables (ansible_host, ansible_port, ansible_user); older Vagrant emitted the now-deprecated ansible_ssh_host forms:
## Generated by Vagrant
node0 ansible_host=127.0.0.1 ansible_port=2222 ansible_user='vagrant' ansible_ssh_private_key_file='~/projects/Vagrant/ansible/.vagrant/machines/node0/virtualbox/private_key'
node1 ansible_host=127.0.0.1 ansible_port=2200 ansible_user='vagrant' ansible_ssh_private_key_file='~/projects/Vagrant/ansible/.vagrant/machines/node1/virtualbox/private_key'
node2 ansible_host=127.0.0.1 ansible_port=2201 ansible_user='vagrant' ansible_ssh_private_key_file='~/projects/Vagrant/ansible/.vagrant/machines/node2/virtualbox/private_key'
node3 ansible_host=127.0.0.1 ansible_port=2202 ansible_user='vagrant' ansible_ssh_private_key_file='~/projects/Vagrant/ansible/.vagrant/machines/node3/virtualbox/private_key'
node4 ansible_host=127.0.0.1 ansible_port=2203 ansible_user='vagrant' ansible_ssh_private_key_file='~/projects/Vagrant/ansible/.vagrant/machines/node4/virtualbox/private_key'
[db-nodes]
node0
[test-nodes]
node3
[random-nodes]
node4
[mixed-nodes]
node1
node4
[renamed-nodes]
node1
Provisioning By Group
With the groups in place, the playbook targets them. Here it is modernized to FQCN, list arguments, and the community.mysql modules:
- hosts: db-nodes
become: true
vars:
install_django: true
mysql_root_password: root
pri_domain_name: test.vagrant.local
roles:
- role: ansible-django
when: install_django
- role: ansible-mariadb-mysql
tasks:
- name: Install prerequisites
ansible.builtin.apt:
name:
- curl
- libapache2-mod-php
- php-curl
- php-sqlite3
- php-mbstring
- sqlite3
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Allow root login to MySQL from anywhere
community.mysql.mysql_user:
name: root
host: "%"
password: "{{ mysql_root_password }}"
priv: "*.*:ALL,GRANT"
- name: Create the Django database
community.mysql.mysql_db:
name: django_db
state: present
when: install_django
- name: Install Django related apps
ansible.builtin.pip:
name:
- django-markdown-deux
- django-tables2
state: present
when: install_django
- hosts: mixed-nodes
become: true
vars:
pri_domain_name: test.vagrant.local
roles:
- role: ansible-nginx
- hosts: all
become: true
vars:
enable_manage_ssh_keys: true
manage_ssh_keys:
- remote_user: vagrant
state: present
keys:
- "~/.ssh/id_rsa.pub"
roles:
- role: ansible-manage-ssh-keys
A few notes on the changes:
ansible.builtin.aptandansible.builtin.piptake a list directly, so the oldwith_itemsloops are gone.- The
php5packages (libapache2-mod-php5,php5-curl,php5-mcrypt) are long retired. The current equivalents arelibapache2-mod-php,php-curl, andphp-mbstring.php-mcryptwas removed from PHP entirely in 7.2, so it is dropped. mysql_userandmysql_dbnow live incommunity.mysql, and the single-itemwith_itemson the MySQL user is replaced withhost: "%"directly. Heads up: these modules are being promoted to a newansible.mysqlcollection, andcommunity.mysqlwill drop them in its 6.0.0 release, so expect to switch the namespace toansible.mysqlbefore long.
Conclusion
The grouping trick is the same as it was: define ansible_groups in the Vagrantfile, let Vagrant generate the inventory, and target groups in your plays. Only the playbook contents needed a modern coat of paint.
Enjoy!
Comments