Storing and externalizing sensitive data is a foundational architectural pattern for secure platforms and applications. The following documentation demonstrates the procedure for setting and retrieving secrets within HashiCorp Vault utilizing Terraform or OpenTofu on deploying k3s node.
1. Provider Configuration
To interact with Vault and generate secure tokens, the environment must specify the required providers.
terraform {
required_providers {
vault = {
source = "hashicorp/vault"
}
random = {
source = "hashicorp/random"
}
}
}
2. Generating the Secret Data
In this implementation, a token is required to bootstrap a K3s cluster. The random provider is utilized to generate a secure, 32-character string.
resource "random_password" "k3s_cluster_token" {
length = 32
special = false
}
3. Storing Sensitive Data in Vault (Set)
The generated token is injected into Vault using the vault_kv_secret_v2 resource. This operation assumes the target Vault mount path is configured for KV Version 2.
-
Mount Point:
home-lab-secrets -
Secret Path:
k3s-cluster-token -
Payload Format: JSON encoded key-value pair.
resource "vault_kv_secret_v2" "k3s_cluster_token" { mount = "home-lab-secrets" name = "k3s-cluster-token" data_json = jsonencode({ token = random_password.k3s_cluster_token.result }) }
4. Retrieving Sensitive Data from Vault (Get)
To utilize the stored secret elsewhere in the infrastructure code, a Terraform data source fetches the values from Vault. The depends_on meta-argument ensures the secret is fully provisioned before retrieval is attempted.
data "vault_kv_secret_v2" "k3s_cluster_token" {
depends_on = [vault_kv_secret_v2.k3s_cluster_token]
mount = "home-lab-secrets"
name = "k3s-cluster-token"
}
5. Usage Example: Bootstrapping a Node
Once retrieved, the secret data can be accessed via data.vault_kv_secret_v2.<name>.data.<key>. In the provided example, the token is passed as an environment variable (K3S_TOKEN) over an SSH connection using a remote-exec provisioner to join a node to the existing K3s cluster.
provisioner "remote-exec" {
inline = [
"cloud-init status --wait",
"curl -sfL https://get.k3s.io | K3S_URL='https://${local.master_node.network.ip}:6443' K3S_TOKEN='${data.vault_kv_secret_v2.k3s_cluster_token.data.token}' sh -"
]
}
Leave a Reply