Terraform
microk8s

IaS

Automation

Cloud

SRE | Apache Benchmark Tool

Terraform and Kubernetes

Intro

When you deploy full stack app to Kubernetes, you need to create lots of Kubernetes items like deployments, services, secrets, ingresses, etc...

If you do not do this daily, for sure you will forget something and need some time to refresh memory next time you need to modify or correct something.

I found Terraform useful to create the whole environment and make it written as a code, so you can easily reconstruct the whole (or parts) of environment if needed

My deployment environment is created in Hetzner cloud using MicroK8s as a platform.

Connection to MicroK8s

    
    microk8s config > k8s_config   

    # create main.tf
    provider "kubernetes" {
        config_path = "k8s_config"
    }

    terraform apply
                

This will configure Terraform to work with Kubernetes and make connection to your k8s cluster. main.tf is the main file where we will describe the whole environment needed for the app.

Example - Express, Svelte and Redis

Classic web app consisting of Redis, NodeJS/Express backend and Svelte frontend. Here is how to start creating deployments and services.

    
    # Add new namespace definition to main.tf

    # Create Namespaces
    resource "kubernetes_namespace" "NewNamespace" {
        metadata {
                name = "NewNamespace"
        }
    }

    # Execute in shell - check what will be done
    terraform plan

    # Create new namespace
    terraform apply
                

Here is the rest of the file.

                
    # Redis Deployment and Service

    
    # Create Redis Deployment
    resource "kubernetes_deployment" "redis" {
        metadata {
            name = "redis-app"
            namespace = "terra-api"
            labels = {
                app = "redis-app"
            }            
        }

        spec {
            replicas = 1
            selector {
                match_labels = {
                    app = "redis-app"
                }
            }

            template {
                metadata {
                    labels = {
                        app = "redis-app"
                        label-key = "redis-app-key"
                    }
                }

                spec {
                    image_pull_secrets {
                        name = "image-registry-credentials"
                    }

                    container {
                        image = "${var.registry}/redis"
                        name = "redis-app-container"
					
                        port {
                            container_port = 6379
                        }
                    }
                }
            }
        }
    }
    

    # Create Redis Service 
    resource "kubernetes_service" "redis-service" {
	metadata {
		name = "redis-app-service"
		namespace = "terra-api"
	}

	spec {
		selector = {
			app = "redis-app"
		}

		port {
			port = 6379
			target_port = 6379
		}

		type = "LoadBalancer"
	}

	# Do not wait for externalIP to be assigned
	wait_for_load_balancer = false

    }