So we will create 2 VMs using Terraform, then deploying a flask project and the database using Ansible.
π¨ Requirements
I used Ubuntu 22.04 LTS as the OS for this project. If youβre using a different OS, please make the necessary adjustments when installing the required dependencies.
The major pre-requisite for this setup is KVM hypervisor. So you need to install KVM in your system. If you use Ubuntu you can follow this step:
Execute the following command to make sure your processor supports virtualisation capabilities:
Install Terraform
Verify installation:
Install Ansible
Verify installation:
Create KVM
we will use the libvirt provider with Terraform to deploy a KVM Virtual Machine.
Create main.tf, just specify the provider and version you want to use:
Thereafter, run terraform init command to initialize the environment:
Now create our variables.tf. This variables.tf file defines inputs for the libvirt disk pool path, the Ubuntu 20.04 image URL as OS for the VMs , and a list of VM hostnames.
Letβs update our main.tf:
the script will provisions multiple KVM VMs using the Libvirt provider. It downloads an Ubuntu 20.04 base image, clones it for each VM, configures cloud-init for user and network settings, and deploys VMs with specified hostnames, 1GB memory, and SPICE graphics. The setup dynamically adapts based on the number of hostnames provided in var.vm_hostnames.
As Iβve mentioned, Iβm using cloud-init, so lets setup the network config and cloud init under the config directory:
Then create our config/cloud_init.yml, just make sure that you configure your public ssh key for ssh access in the config:
And then network config, in config/network_config.yml:
Our project structure should look like this:
Now run a plan, to see what will be done:
And run terraform apply to run our deployment:
Verify VM creation using virsh command:
Get instances IP address:
Try to access the vm using ubuntu user:
Create Ansible Playbook
Now letβs create the Ansible Playbook to deploy Flask & Postgresql on Docker. First you need to create ansible directory and ansible.cfg file:
Then create inventory file called hosts:
checking our VMs using ansible ping command:
Now create playbook.yml and roles, this playbook will install and configure Docker, Flask and PostgreSQL:
Playbook to install Docker
Now create new directory called roles/docker:
Create a new directory in docker called tasks, then create new file main.yml. This file will install Docker & Docker Compose:
Playbook to install and configure postgresql
Then create new directory called psql, create subdirectory called vars, tempalates & tasks:
After that, in vars, create main.yml. These are variables used to set username, passwords, etc:
Next, we will create jinja file called docker-compose.yml.j2. With this file we will create postgresql container:
Next, create main.yml to tasks. So we will copy docker-compose.yml.j2 and run using docker compose:
Playbook to deploy Flask App
First, you need to create directory called flask, then create sub-directory again:
Next, add main.yml to vars. This file refer to posgtresql variable before, with addition IP address of VM2(database VM):
Next, create config.py.j2 to templates. This file will replace the old config file from Flask project:
Next, create docker-compose.yml.j2 to templates. With this file we will create a container using docker compose:
Next, create main.yml in tasks. With this file we will clone flask project, add compose file, replace config.py and create new container using docker compose:
Our project structure should look like this:
Run Playbook and testing
Finally, letβs run ansible-playbook to deploy PostgreSQL and Flask:
After complete, just make sure there is no error. Then you see there are two containers created. In VM1 is Flask and VM2 is Postgresql:
Try to access the app using browsers, just type http://<vm1_ip>:5000:
Try to add a new task and then the data will be added to the database:
Conclusion
Finally we have created 2 VMs and deploy Flask Project with database.
Thank you for reading this article. Feel free to leave a comment if you have any questions, suggestions, or feedback.