# Terraform Module - extract and reuse
# 1 Why we need module
Terraform Module helps us manage the resources in the right way, just like the Method in Java. Generally, the module contains the files:
- main.tf: just like the main function;
- README.md: description about the module;
- variables.tf: define the variables used in module;
- outputs.tf: output the value from the module;
- examples: show how to use;
# 2 create your own module
# 2.1 create the module
I will create a simple module to deploy the nginx to Kubernetes. It helps to deploy the Deployment and Service on k8s for us. There are two files in the simple module:
(1) main.tf: defines the resources(kubernetes Deployment and Service)
(2) variables.tf: defines the variables for the resources
Let's put the two files in the folder nginx-kubernetes:

main.tf:
resource "kubernetes_deployment" "test" {
  metadata {
    name      = var.applicationName
    namespace = var.namespace
  }
  spec {
    replicas = var.replicas
    selector {
      match_labels = {
        app = var.applicationName
      }
    }
    template {
      metadata {
        labels = {
          app = var.applicationName
        }
      }
      spec {
        container {
          image = var.image
          name  = "nginx-container"
          port {
            container_port = 80
          }
        }
      }
    }
  }
}
resource "kubernetes_service" "test" {
  metadata {
    name      = var.applicationName
    namespace = var.namespace
  }
  spec {
    selector = {
      app = var.applicationName
    }
    type = "NodePort"
    port {
      node_port   = var.nodePort
      port        = 80
      target_port = 80
    }
  }
  depends_on = [kubernetes_deployment.test]
}
As code shows, the varibles pattern is var.xxx. The Terraform will try to replace the var with the input varibles.
variables.tf:
variable "namespace" {
    description = "k8s namespace"
}
variable "applicationName" {
    description = "applicationName"
}
variable "image" {
    description = "image"
}
variable "replicas" {
    description = "deployment replicas"
}
variable "nodePort" {
    description = "nodePort"
}
All the var.xxx in main.tf need to be pre-defined here.
# 2.2 How to use the module
It's easy to use the module, just like calling a method in Java:
provider "kubernetes" {
  config_path = "~/.kube/config"
}
module "pkslow-nginx" {
    source = "./nginx-kubernetes"
    namespace = "pkslow"
    applicationName = "pkslow-nginx"
    image = "nginx:1.19.5"
    replicas = 3
    nodePort = 30301
}
- source: where is the module from;
- namespace: input varible for Kubernetes;
- applicationName: input varible for Kubernetes;
- image: input varible for Kubernetes;
- replicas: input varible for Kubernetes;
- nodePort: input varible for Kubernetes;
# 3 external module
Terraform supports many kinds of Module sources: local/Terraform registry/GitHub/http etc.
Local:
module "pkslow" {
  source = "./pkslow"
}
Terraform Registry:
module "consul" {
  source = "hashicorp/consul/aws"
  version = "0.1.0"
}
GitHub:
module "pkslow" {
  source = "github.com/larrydpk/pkslow"
}
GitHub SSH:
module "pkslow" {
  source = "git@github.com:larrydpk/pkslow.git"
}
Zip file:
module "vpc" {
  source = "https://pkslow.com/vpc-module?archive=zip"
}
# 4 the end
Please check the code on: https://github.com/LarryDpk/pkslow-samples
References: