I’ve been trying to figure out how to create a Kubernetes secret that will have an id, description and collection of key value pares, all from an input variable.
I’m having two issues.
- I can’t figure out how to create a TF .12 variable that has those three properties, one of which is a list object
- I can’t figure out how to spit out a list in the data field.
Here’s some sample code
This is the kind of thing I’m trying to do in creating the variable. This does not work
# Optional additional secrets to be created in Rancher / Kubernetes for injection into a build pod
variable "additional_text_secrets" {
type = object ({
id = string
description = string
list(object({
key = string
value = string
}))
})
default = {[]}
description = "An additional list of Rancher secrets to create for the user to inject into build pods"
}
This produces the error:
On .terraform\modules\jenkins\variables.tf line 189: Expected an attribute value, introduced by an equals sign ("=").
To create the secret I’m trying something like this.
# Additional Rancher / Kubernetes secrets that the user might need to inject into their build pods
# Text based secrets, we will base64 encode these for the user
resource "rancher2_secret" "additional-text-secrets" {
name = var.additional_text_secrets.id
description = var.additional_text_secrets.description
project_id = var.rancher_project
namespace_id = rancher2_namespace.jenkins-namespace.id
labels = {
"cattle.io/creator" = "norman"
}
data = {
%{ for secret in var.additional_text_secrets.secret }
secret.key = base64encode("${secret.value}")
%{ endfor }
}
}
This produces the error
On .terraform\modules\jenkins\secrets.tf line 11: Expected the start of an expression, but found an invalid expression token.
Note: The above is a Rancher2 secret, i.e. not a straight up k8s secret but I don’t think that matters??
I’m trying the above because I found out that this works
# Create a list of container repository auths used to store Docker images, usually in Artifactory
resource "rancher2_secret" "container-repositories" {
name = "container-repositories"
description = "List of container repository auths used to store Docker images, usually in Artifactory"
project_id = var.rancher_project
namespace_id = rancher2_namespace.jenkins-namespace.id
# Using a heredoc becuase you can't pass a complex object to a template
data = {
"config.json" = base64encode(<<EOT
{
"auths": {
%{ for auth in var.container_repositories }
"${auth.url}": {
"username": "${auth.username}",
"password": "${auth.password}"
},
%{ endfor }
}
}
EOT
)
}
}
Which is basically the same thing, except I’m creating a list of auths in JSON format as the value inside of base64encode (so that’s probably why it works, it is inside the function . . . )
Also note that I know I could just create a list of secrets and do this
# A file that has already been base64 encoded
resource "rancher2_secret" "additional-file-secrets" {
count = length(var.additional_file_secrets)
name = var.additional_file_secrets[count.index].id
description = var.additional_file_secrets[count.index].description
project_id = var.rancher_project
namespace_id = rancher2_namespace.jenkins-namespace.id
labels = {
"cattle.io/creator" = "norman"
}
data = {
var.additional_file_secrets[count.index].file_name = var.additional_file_secrets[count.index].encoded_bytes
}
}
However that is not as useful as it creates many secrets, one per item in the list and NOT one secret with many key value pares.
This is what we are doing now and found the one major issue is that you cannot mount more than secret to a volume location at a time.
The expected input and output should look like the below
Variable assignment
additional_text_secrets = {
id = "sarge-test-secret-1"
description = "This is a test of a multi value secret"
secret = [
{
key = "secret1"
value = "This is the value"
},
{
key = "secret2"
value = "This is the second value."
}
]
}
Output
resource "rancher2_secret" "additional-text-secrets" {
name = "sarge-test-secret-1"
description = "This is a test of a multi value secret"
project_id = var.rancher_project
namespace_id = rancher2_namespace.jenkins-namespace.id
labels = {
"cattle.io/creator" = "norman"
}
data = {
"secret1" = base64encode("This is the value")
"secret2" = base64encode("This is the second value")
}
}
I’m starting to think there isn’t a way to do this, would love it if I’m proved wrong.