DEV Community

Alvaro Valarezo de la Fuente
Alvaro Valarezo de la Fuente

Posted on

Create an API with FastApi, Kubernetes, Traefik and Ansible


Backend API (Python) in FastApi in a Kubernetes Cluster using Traefik as an API Gateway and Ansible as a configuration management tool.

Clone Github repo

Clone my repo and follow the steps below

Description of the directories

  • ansible : Folder with the resources to deploy the traefik pods using Ansible

  • kubernetes: Folder with the YAML files to deploy the API and the Postgres Database

  • sa-service-2: Folder with the source code of the API

Requirements for installing the project

  • Docker

To install Docker:

Note: In Docker Desktop Preferences, enable Kubernetes to run the cluster

  • Ansible

To install ansible use pip: python -m pip install --user ansible

  • Minikube (kubectl)

Follow these steps:

  • Python (PIP)

  • openshift

  • pyyaml

  • kubernetes

To install python libraries run Eg: pip install openshift

  • Helm V3 (Kubernetes Package Manager)

To install run brew install helm

1.- Steps to start the K8s cluster

After installing everything above and running Docker Desktop in your PC

Run in your terminal:

In this URL, you can check that there aren’t any deployments yet in the default namespace.

2.- Steps to deploy Traefik using Ansible

The Traefik Service is managed by using Ansible, so you can open the file ansible/templates/traefik_values_default.yml.j2 where you can check that the type of deployment is a DaemonSet

  • Traefik listens on port 80 on all interfaces of the host for incoming HTTP requests

  • Traefik listens on port 443 on all interfaces of the host for incoming HTTPS request

  • Traefik dashboard is enabled and is not exposed to the public internet.

Ports exposed:

# To access the dashboard you can use "kubectl port-forward" e.g.:

# kubectl -n traefik port-forward $(kubectl get pods --selector "" --output=name -A | head -1) 9000:9000

# Opening http://localhost:9000/dashboard/ should show the dashboard.


port: 9000

expose: true

protocol: TCP

Enter fullscreen mode Exit fullscreen mode


# CPU and RAM resource limits. These settings should also be set to

# reasonable values in case of a memory leak e.g.



cpu: "100m"

memory: "50Mi"


cpu: "300m"

memory: "150Mi"

Enter fullscreen mode Exit fullscreen mode

In the ansible/defaults/main.yml, you can change the namespace for the deployment (Traefik) , name for the ingress controller,etc.

The ansible playbook will detect these settings and apply them to the cluster when it runs the playbook.

In the ansible/k8s.yml you can look that the host is traefik. to recognize this dns we need to edit the /etc/ansible/hosts file.

** If you don’t have the file or folder, please create it using sudo mkdir /etc/ansible and sudo touch hosts then edit it:

and paste this:



Enter fullscreen mode Exit fullscreen mode

We are telling Ansible that the traefik dns will translate to localhost

After doing this we are ready to deploy:

To deploy the Traefik Service in the traefik namespace:

  • cd ansible

  • ansible-playbook --tags=role-traefik-kubernetes --extra-vars action=install k8s.yml

One of the final tasks is called TASK [githubixx.traefik-kubernetes : Output rendered template]. This allows to check the YAML file before Traefik gets deployed

If everything is OK , run kubectl -n traefik get pods -o wide and you will see a pod with the traefik initials.

To forward the ports to check the traefik dashboard, run:

kubectl -n traefik port-forward $(kubectl get pods --selector "" --output=name -A | head -1) 9000:9000


http://localhost:9000/dashboard/#/http/services to check that everything is working correctly.

Steps to deploy the Postgres Database

To deploy the database in the K8s cluster, we are going to use diferent YAML files.

  • cd kubernetes

In this folder, there are 4 YAML files for the Postgres Deployment.

  • postgres-configmap.yaml A K8s ConfigMap allows me to save important variables like the name of the db, POSTGRES_USER, POSTGRES_PASSWORD.

  • postgres-storage.yaml 2 different kinds of volume: PersistentVolume and PersistentVolumeClaim used to preserve the data if a pod is deleted.

  • postgres-service.yaml A K8s Service that allows me to connect to the Postgres DB and with other pods in the same cluster.

  • postgres-deployment.yaml A K8s Deployment with a Postgres 10.1 image.

In the kubernetes folder:


  • kubectl apply -f postgres-configmap.yaml

  • kubectl apply -f postgres-storage.yaml

  • kubectl apply -f postgres-deployment.yaml

  • kubectl apply -f postgres-service.yaml

  • If you run kubectl get all you can check that everything is deployed.

  • Run kubectl port-forward --namespace default svc/postgres-ip-service 5432:5432 to port forwarding and access the database using localhost:5432

  • Connect to the database using your favorite DB client like Datagrip, DBeaver,etc.

Inside the users database, run this query:

CREATE TABLE rappiuser (

user_id serial PRIMARY KEY,


lastname VARCHAR ( 50 ) NOT NULL,

address VARCHAR ( 250 ) NOT NULL,



hire_date DATE,

fire_date DATE


Enter fullscreen mode Exit fullscreen mode

That’s all for the db configuration.

Steps to deploy the FastApi Backend

Finally, the last step is deploying the API.

  • cd sa-service-2

Inside the app folder you can check that is structured in models, schemas, services and utils with a file that contains the routes.

Inside the sa-service-2 folder, run:

  • minikube image build -t sa-service-2 .

This command upload the backend image to the minikube local registry, to use it for the deployment.

  • cd .. return to the previous dir.

  • kubectl apply -f resource-manifests/service-two.yml Apply a Deployment, Service and an Ingress Controller.


Define the name for the deployment, and the image that will be used sa-service-2.


Define the port that will be exposed in this case is the Port 80


The Ingress Controller will be handled by Traefik and will listen in the port 80

Now you can go to http://localhost/docs and start testing the API :)

In the http://localhost:9000/dashboard/#/http/services you can check there is a new ingress controller that handles 2 pods

Top comments (0)