3
votes

I am setting up an EKS cluster with Terraform following the example https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/aws_auth.tf and I now have two Terraform files:

kubeconfig.tf

resource "local_file" "kubeconfig" {
  content  = "${data.template_file.kubeconfig.rendered}"
  filename = "tmp/kubeconfig"
}

data "template_file" "kubeconfig" {
  template = "${file("template/kubeconfig.tpl")}"
...
}

aws-auth.tf

resource "null_resource" "update_config_map_aws_auth" {
  provisioner "local-exec" {
    command = "kubectl apply -f tmp/config-map-aws-auth_${var.cluster-name}.yaml --kubeconfig /tmp/kubeconfig"
  }

  ...
 }

When I run this the local-exec command fails with

Output: error: stat tmp/kubeconfig: no such file or directory

On a second run it succeeds. I think that the file is created after local-exec tries to use it and local-exec should depend on the file resource. So I try to express the dependency by using interpolation (implicit dependency) like this:

resource "null_resource" "update_config_map_aws_auth" {
  provisioner "local-exec" {
    command = "kubectl apply -f tmp/config-map-aws-auth_${var.cluster-name}.yaml --kubeconfig ${resource.local_file.kubeconfig.filename}"
  }

But this always gives me

Error: resource 'null_resource.update_config_map_aws_auth' provisioner local-exec (#1): unknown resource 'resource.local_file' referenced in variable resource.local_file.kubeconfig.filename

1
You don't need the resource. part when using the interpolation in the last code block. When Terraform first started it just had resources so you don't need to say that something's a resource as that was the only case. They then added modules and data sources which required some differentiation in the naming so these get module. and data. so Terraform can tell resources and data sources etc apart.ydaetskcoR
Thanks! That worked.Nils El-Himoud

1 Answers

6
votes

You don't need the resource. part when using the interpolation in the last code block.

When Terraform first started it just had resources so you don't need to say that something's a resource as that was the only case. They then added modules and data sources which required some differentiation in the naming so these get module. and data. so Terraform can tell resources and data sources etc apart.

So you probably want something like this:

resource "local_file" "kubeconfig" {
  content  = "${data.template_file.kubeconfig.rendered}"
  filename = "tmp/kubeconfig"
}

data "template_file" "kubeconfig" {
  template = "${file("template/kubeconfig.tpl")}"
  ...
}

resource "null_resource" "update_config_map_aws_auth" {
  provisioner "local-exec" {
    command = "kubectl apply -f tmp/config-map-aws-auth_${var.cluster-name}.yaml --kubeconfig ${local_file.kubeconfig.filename}"
  }
}