2 min read | by Jordi Prats
Storing the terraform state into a S3 bucket with dynamoDB for locking has become the de facto standard for being able to share the state across an organization. Nevertheless, there are interesting alternatives: We can use a Kubernetes Secret
By using a Kubernetes Secret we no longer need dynamoDB since it uses a Lease for handling locking.
We can configure the backend as follows:
terraform {
backend "kubernetes" {
config_path = "~/.kube/config"
secret_suffix = "tfstate"
namespace = "default"
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "minikube"
}
resource "kubernetes_namespace" "demo_ns" {
metadata {
name = "testing-k8s-tfstate"
}
}
There are many other options to be able to configure the backend to select the appropriate Kubernetes cluster
We can run this code using the usual workflow:
$ terraform init
$ terraform plan
$ terraform apply
Checking the secret that it has created we will see that it is a regular
$ kubectl get secret -n default
NAME TYPE DATA AGE
default-token-t6662 kubernetes.io/service-account-token 3 6m55s
tfstate-default-tfstate Opaque 1 63s
$ kubectl describe secret tfstate-default-tfstate
Name: tfstate-default-tfstate
Namespace: default
Labels: app.kubernetes.io/managed-by=terraform
tfstate=true
tfstateSecretSuffix=tfstate
tfstateWorkspace=default
Annotations: encoding: gzip
Type: Opaque
Data
====
tfstate: 511 bytes
It is stored as a compressed json, so we can read it's data using the following command:
$ kubectl get secret tfstate-default-tfstate -o jsonpath="{.data.tfstate}" | base64 -d | gzip -d -
{
"version": 4,
"terraform_version": "1.1.3",
(...)
As you might already noticed, the workspace name is part of the secret's name, so if we rerun the code using a new namespace (deleting the namespace to make it work):
$ kubectl delete ns testing-k8s-tfstate
$ terraform workspace new demo
$ terraform apply -auto-approve
We'll find a new Secret for each of the workspaces we are using:
$ kubectl get secret -n default
NAME TYPE DATA AGE
default-token-t6662 kubernetes.io/service-account-token 3 9m29s
tfstate-default-tfstate Opaque 1 3m37s
tfstate-demo-tfstate Opaque 1 89s
Posted on 19/04/2022