ericchiang/terraform-provider-k8s

apiVersion leaks into resource name

Opened this issue · 0 comments

I have a CRD:

# From https://github.com/jetstack/cert-manager/blob/912c7672bd3e6ba1e7ef9dff48083ee6f3d6cbab/contrib/manifests/cert-manager/with-rbac.yaml                                                                                                                                                                                                                                  
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: clusterissuers.certmanager.k8s.io
  annotations:
    "helm.sh/hook": crd-install
  labels:
    app: cert-manager
    chart: cert-manager-v0.6.0-dev.1
    release: cert-manager
    heritage: Tiller
spec:
  group: certmanager.k8s.io
  version: v1alpha1
  names:
    kind: ClusterIssuer
    plural: clusterissuers
  scope: Cluster

and I'm trying to create an object of its type:

apiVersion: certmanager.k8s.io/v1alpha1                                                                                                                                                                                                                                                                                                                                      
kind: ClusterIssuer
metadata:
  name: letsencrypt-issuer
  namespace: default
spec:
  ...

with

data "jsone_template" "certificate_clusterissuer" {
  template = "${file("${path.module}/certificate/clusterissuer.yaml")}"
}

resource "k8s_manifest" "certificate_clusterissuer" {
  content    = "${data.jsone_template.certificate_clusterissuer.rendered}"
}

(jsone_template in this case is equivalent to a yaml parser, as there are no JSON-e operators or expressions in the input)

Terraform apply creates the resource correctly:

tf@eb5a5de314f4:/repo/tf$ kubectl get --ignore-not-found clusterissuer/letsencrypt-issuer
NAME                 AGE
letsencrypt-issuer   18m

and

tf@eb5a5de314f4:/repo/tf$ terraform state show module.taskcluster.k8s_manifest.certificate_clusterissuer
id      = /apis/certmanager.k8s.io/v1alpha1/letsencrypt-issuer
content = {"apiVersion":"certmanager.k8s.io/v1alpha1","kind":"ClusterIssuer","metadata":{"name":"letsencrypt-issuer","namespace":"default"},"spec":{"acme":{"email":"taskcluster-accounts@mozilla.com","http01":{},"privateKeySecretRef":{"name":"letsencrypt-staging"},"server":"https://acme-staging-v02.api.letsencrypt.org/directory"}}}

but the resulting 'id' seems to cause issues on subsequent terraform runs:

* module.taskcluster.k8s_manifest.certificate_clusterissuer: k8s_manifest.certificate_clusterissuer: /google-cloud-sdk/bin/kubectl kubectl get --ignore-not-found v1alpha1/letsencrypt-issuer exit status 1: the server doesn't have a resource type "v1alpha1"

The selfLink for the resource is /apis/certmanager.k8s.io/v1alpha1/letsencrypt-issuer, so

func resourceFromSelflink(s string) (resource, namespace string, ok bool) {
parts := strings.Split(s, "/")
if len(parts) < 2 {
return "", "", false
}
resource = parts[len(parts)-2] + "/" + parts[len(parts)-1]

naturally produces that k8s resource name. I'm not sure where the bug is, here -- is there a spec for the format of the selfLink that is being violated here?

/cc @imbstack