Module

This guide will show you how to provision (Create, Update, Delete) a Terraform Module using Kubeform Module.

Examples used in this guide can be found here.

At first, let’s look at the Terraform configuration for a Terraform Module below:

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
}

provider "aws" {
  access_key = ""
  region = "us-east-2"
  secret_key = ""
}

module "aws-s3-module-sample" {
  bucket = "kubeform-module"
  force_destroy = true
  source = "github.com/terraform-aws-modules/terraform-aws-s3-bucket"
}

Now, if we apply terraform apply this config will apply the terraform-aws-s3-bueckt module. We’ll create the exact configuration using Kubeform Module. The steps are given below:

1. Before You Begin

At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using kind.

Now, install Kubeform Module operator in your cluster following the steps here. To get a FREE license, please visit here.

To keep things isolated, this tutorial uses a separate namespace called demo throughout this tutorial.

$ kubectl create ns demo
namespace/demo created

2. Create Respective Provider Secret

Then create the secret which is necessary for provisioning module respective provider’s resources, in this module we need AWS Provider.

apiVersion: v1
kind: Secret
metadata:
  name: aws-credentials
  namespace: demo
stringData:
  provider: |
    {
        "access_key": "<ACCESS_KEY>",
        "region": "<REGION_NAME>",
        "secret_key": "<SECRET_KEY>"
    }    

Here we can see that, the provider field of the stringData of the secret is same as the field of the provider part in the terraform config file. The provider secret needs to be provided in json format, under the provider key. Save it in a file (eg. provider-secret.yaml) then apply it using kubectl command.

kubectl apply -f provider-secret.yaml

Note: Here, key of the provider field of the stringData (eg. "access_key", "secret_key" ) must be in snake case format (same as the tf configuration file)

3. Generate Kubeform Module Definition

If we look at the terraform config, we can see in the module block there is a field source in which we basically need to give the source of the respective terraform module, in Kubeform Module we will first generate Kubeform Module Definition which is generated from the given terraform module, we generate Kubeform Module Definition by using Kubeform CLI. Kubeform Module Definition for this terrafrom module is given below:

apiVersion: tf.kubeform.com/v1alpha1
kind: ModuleDefinition
metadata:
  creationTimestamp: null
  name: module-def-public
spec:
  moduleRef:
    git:
      ref: github.com/terraform-aws-modules/terraform-aws-s3-bucket
  provider:
    name: aws
    source: hashicorp/aws
  schema:
    properties:
      input:
        ...
      output:
        ...
    required:
      - input
    type: object
status: {}

Here, in the .spec.schema.input the variables schema and in .spec.schema.output the output variables schemas are generated from the terraform module.

During generation it is saved in a given directory in a file (eg. module-def-public.yaml), now we apply it using kubectl.

kubectl apply -f module-def-public.yaml

Note: this module-def-public is generated by below Kubeform CLI command:

kubectl kf gen-module module-def-public \ 
  --directory=./ \ 
  --source=https://github.com/terraform-aws-modules/terraform-aws-s3-bucket \ 
  --provider-name=aws \
  --provider-source=hashicorp/aws

Kubeform CLI need to be installed for running this command

4. Create Kubeform Module

Now, we’ll create the Kubeform Module Object. The yaml is given below:

apiVersion: tf.kubeform.com/v1alpha1
kind: Module
metadata:
  name: aws-s3-module-sample
  namespace: demo
spec:
  resource:
    input:
      bucket: "kubeform-module"
      forceDestroy: false
  moduleDef: module-def-public
  providerRef:
    name: aws-credentials

Here, in the spec.resource.input the module’s variable which we can pass to the module is provided.

We can see a field named moduleDef, this is a feature of Kubeform Module. Here we refer the respective Kubeform Module Definition of terraform module.

Save it in a file (eg. aws-s3-bucket-module.yaml) then apply it using kubectl.

kubectl apply -f aws-s3-bucket-module.yaml

After applying this command, the module will be in InProgress phase until the cloud creates the module resource. Once the cloud resources get created, the module object will be in Current phase which means we have successfully created the module.

After successful creation of the module, the module state is available under spec.state section and it will be encrypted. This spec.state field is basically the terraform.tfstate. This field contains sensitive fields that’s why it’s encrypted. In the spec.resource.output the module output variables values are stored.

5. Update Kubeform Module

Now, we’ll update the Module. For updating the Module, we will modify the existing aws-s3-bucket-module.yaml, we will use a different forceDestroy (true). The modified yaml is given below:

apiVersion: tf.kubeform.com/v1alpha1
kind: Module
metadata:
  name: aws-s3-module-sample
  namespace: demo
spec:
  resource:
    input:
      bucket: "kubeform-module"
      forceDestroy: true
  moduleDef: module-def-public
  providerRef:
    name: aws-credentials

Now, apply it using kubectl command.

kubectl apply -f aws-s3-bucket-module.yaml

After that, existing Module will be updated!

6. Delete Kubeform Module

To delete the Module just run:

kubectl delete -f aws-s3-bucket-module.yaml

After applying this command the module resources will be in Terminating phase until the cloud resources get destroyed. Once the cloud resource get destroyed, the resource will get deleted successfully.