Terraform-provider-kubernetes: kubernetes_secret should allow the `.` character in the name

Created on 10 Nov 2017  路  6Comments  路  Source: hashicorp/terraform-provider-kubernetes

The . character is allowed by Kubernetes and we use it for many of our existing secrets.

bug kubernete1.6

Most helpful comment

For those arriving from their preferred search engine, as I did:

Importantly, the validation described seems to only allow lowercase characters for secret names. This precludes camelCase.

My version:
version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-10-30T21:39:38Z", GoVersion:"go1.11.1", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.5", GitCommit:"490c6f13df1cb6612e0993c4c14f2ff90f8cdbf3", GitTreeState:"clean", BuildDate:"2017-06-14T20:03:38Z", GoVersion:"go1.7.6", Compiler:"gc", Platform:"linux/amd64"}

All 6 comments

Does wrapping the secret key in quotes help?

It doesn't. Replacing the . with - resolves the issue but that means we would have to rename all our secrets.

@rochdev could you paste an example config that isn't working?

I'm able to create a secret with . in the name:

resource "kubernetes_secret" "dot-test" {
  metadata {
    name      = "dot.test"
  }

  data {
    ".start" = "foo"
    "mid.dle" = "foo"
    "end." = "foo"
  }

}
terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + kubernetes_secret.dot-test
      id:                          <computed>
      data.%:                      "3"
      data..start:                 <sensitive>
      data.end.:                   <sensitive>
      data.mid.dle:                <sensitive>
      metadata.#:                  "1"
      metadata.0.generation:       <computed>
      metadata.0.labels.%:         <computed>
      metadata.0.name:             "dot.test"
      metadata.0.namespace:        "default"
      metadata.0.resource_version: <computed>
      metadata.0.self_link:        <computed>
      metadata.0.uid:              <computed>
      type:                        "Opaque"


Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

kubernetes_secret.dot-test: Creating...
  data.%:                      "" => "3"
  data..start:                 "<sensitive>" => "<sensitive>"
  data.end.:                   "<sensitive>" => "<sensitive>"
  data.mid.dle:                "<sensitive>" => "<sensitive>"
  metadata.#:                  "" => "1"
  metadata.0.generation:       "" => "<computed>"
  metadata.0.labels.%:         "" => "<computed>"
  metadata.0.name:             "" => "dot.test"
  metadata.0.namespace:        "" => "default"
  metadata.0.resource_version: "" => "<computed>"
  metadata.0.self_link:        "" => "<computed>"
  metadata.0.uid:              "" => "<computed>"
  type:                        "" => "Opaque"
kubernetes_secret.dot-test: Creation complete after 0s (ID: default/dot.test)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

However, I'm not able to create a secret with a . at the start or end of the name, but that's the same when I try create via kubectl:

kubectl create secret generic ".my-secret" --from-literal=foo=bar
The Secret ".my-secret" is invalid: metadata.name: Invalid value: ".my-secret": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')

@sl1pm4t Just tried your exact example and cannot even get a plan working.

tf plan

Error: kubernetes_secret.dot-test: metadata.0.name a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name',  or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')

When using the CLI it works:

kubectl create secret generic "dot.secret" --from-literal=foo=bar
secret "dot.secret" created

I am using Terraform v0.11.0 with provider.kubernetes v1.0.1

I don't know if it would make a difference but the cluster is using Kubernetes 1.7.8-gke.0.

The issue arises from the metadata validation we apply.

https://github.com/terraform-providers/terraform-provider-kubernetes/blob/master/kubernetes/validators.go#L32-L42

We are performing DNS label validation (which only permits alphanum and dashes). However the docs for k8s state:
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

By convention, the names of Kubernetes resources should be up to maximum length of 253 characters and consist of lower case alphanumeric characters, -, and ., but certain resources have more specific restrictions.

Meaning the DNS label is too strict for the name attribute. I would open the PR myself but I'm concerned about the effects of changing this general schema (metadata). Furthermore it appears that "certain resources have more specific restrictions", I think we will need to dig through k8s to find the validation rules for this resource. As mentioned in above comments "starting or ending with a ." is not allowed in kubectl, however the definition I pasted doesn't describe any restriction like that.

UPDATE:
the error posted by @sl1pm4t

The Secret ".my-secret" is invalid: metadata.name: Invalid value: ".my-secret": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is 'a-z0-9?(.a-z0-9?)*')

Actually revealed to me kubectl is applying the DNS subdomain validation. Traced to the source in k8s:

const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"

For those arriving from their preferred search engine, as I did:

Importantly, the validation described seems to only allow lowercase characters for secret names. This precludes camelCase.

My version:
version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-10-30T21:39:38Z", GoVersion:"go1.11.1", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.5", GitCommit:"490c6f13df1cb6612e0993c4c14f2ff90f8cdbf3", GitTreeState:"clean", BuildDate:"2017-06-14T20:03:38Z", GoVersion:"go1.7.6", Compiler:"gc", Platform:"linux/amd64"}

Was this page helpful?
0 / 5 - 0 ratings