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:
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
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)
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
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.
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!
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.