In this tutorial, we’re going to show you how to use your Ansible playbooks to provision your Vagrant boxes. Configuration management is key to ensuring your test and development servers match your production servers. Without which predicting the behavior of your application after deployment is impossible, since every environment might be set up slightly different.
We’re going to create a multi-server Vagrantfile for this tutorial. The first server will be our NodeJS web application and the second will be the database server.
Two different playbooks will be used — one for each server role. Each playbook will have multiple Ansible roles for the different components that will be configured for each server.
Workspace Setup
Create the following directory structure for your Vagrant workspace. The directory will host the Vagrantfile, as well as our Ansible playbooks and roles.
/Vagrant Vagrantfile / Provisioning all.yml database.yml webapp.yml / roles / common / tasks main.yml / webapp / tasks main.yml / mysql / handlers main.yml / tasks main.yml / templates mysql.conf.j2
All Playbook
The all.yml playbook will apply all servers roles to the targeted host. It will deploy and configure our web application and install the database server. This is useful for when we want to consolidate all roles onto a single server.
Webapp Playbook
The webapp playbook will configure the server to host our web application. It will also deploy the application to the server after it has been configured.
Database playbook
The database playbook will install and configure our backend database server, MySQL.
Vagrant Ansible Provisioner
When your Ansible playbooks and roles are ready you will need to tell Vagrant to use them during the provisioning stage.
Single Server Vagrantfile
In our single server example, we’re going to apply all server roles to our instance using the all.yml playbook. This is the simplest, lightest method of creating a development box on your desktop or laptop.
Vagrant.configure("2") do |config| config.vm.box = "ubuntu/xenial64" config.vm.box_check_update = true config.vm.hostname = "myserver01" config.vm.network "private_network", ip: "192.168.50.50" config.vm.provider "virtualbox" do |v| v.name = "myserver01" v.memory = 1024 v.cpus = 1 v.linked_clone = true v.gui = false end server.vm.provision "ansible" do |ansible| ansible.playbook = "provisioning/all.yml" end endMulti Server Vagrantfile
Multi-Server Vagrantfile
To better mimic your staging or production environments, you may want to separate everything onto different hosts. The following vagrant file will create three instances, two for hosting our web application and the third that will host our application’s database.
The two webapp servers will use our webapp.yml playbook. The database server will use the database.yml playbook.
Vagrant.configure("2") do |config| config.vm.box = "ubuntu/xenial64" config.vm.box_check_update = true config.vm.define "webapp1" do |server| server.vm.hostname = "webapp1" server.vm.network "private_network", ip: "192.168.50.30" server.vm.provider "virtualbox" do |v| v.name = "webapp1" v.memory = 768 v.cpus = 1 v.linked_clone = true v.gui = false end server.vm.provision "ansible" do |ansible| ansible.playbook = "provisioning/webapp.yml" end end config.vm.define "webapp2" do |server| server.vm.hostname = "webapp2" server.vm.network "private_network", ip: "192.168.50.31" server.vm.provider "virtualbox" do |v| v.name = "webapp2" v.memory = 768 v.cpus = 1 v.linked_clone = true v.gui = false end server.vm.provision "ansible" do |ansible| ansible.playbook = "provisioning/webapp.yml" end end config.vm.define "db1" do |server| server.vm.hostname = "db1" server.vm.network "private_network", ip: "192.168.50.32" server.vm.provider "virtualbox" do |v| v.name = "db1" v.memory = 1024 v.cpus = 1 v.linked_clone = true v.gui = false end server.vm.provision "ansible" do |ansible| ansible.playbook = "provisioning/mysql-server.yml" end end end