Automating Flask & PostgreSQL Deployment on KVM with Terraform & Ansible
π Intro
Hi, in this post, we will use Libvirt with Terraform to provision 2 KVM locally and after that, we will Deploy Flask App & PostgreSQL using Ansible.
Content
π Project Architecture
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.
NB: Project Repo: danielcristho/that-i-write/terrafrom-ansible-flask