Trigger local exec when resources changes

Hi @apparentlymart ,

Apologizes for asking TF Qs. Learning new stuff everyday :slight_smile:

I have the following snippet for example which is a K8s Custom Resource

terraform {
  required_version = ">= 0.13.0"
  required_providers {
    kubectl = {
      source = "github.com/gavinbunney/kubectl"
      version = "1.5.1"
    }
  }
}

provider "kubectl" {
  config_path      = "/tmp/configs/my.kubeconfig"
  load_config_file = true
}

resource "kubectl_manifest" "gardener_shoot" {
   yaml_body = templatefile("${path.module}/templates/gardener-shoot.yaml.tmpl", {
          shoot_cluster_name = var.shoot_cluster_name,
          project_name = var.project_name,
          create_timeout = var.create_timeout,
          update_timeout = var.update_timeout,
          delete_timeout = var.delete_timeout,
          dashboard_enabled = var.dashboard_enabled,
          nginx_enabled = var.nginx_enabled,
          target_profile = var.target_profile,
          kubernetes_version = var.kubernetes_version,
          maintenance_k8s_version_enabled = var.maintenance_k8s_version_enabled,
          maintenance_machine_image_version_enabled = var.maintenance_machine_image_version_enabled,
          networking_nodes = var.networking_nodes,
          networking_pods = var.networking_pods,
          networking_services = var.networking_services,
          networking_type = var.networking_type,
          vnetcidr = var.vnetcidr,
          cloud_provider = var.cloud_provider,
          machine_image_name = var.machine_image_name,
          machine_image_version = var.machine_image_version,
          machine_type = var.machine_type,
          worker_max_surge = var.worker_max_surge,
          worker_max_unavailable = var.worker_max_unavailable,
          worker_maximum = var.worker_maximum,
          worker_minimum = var.worker_minimum,
          worker_name = var.worker_name,
          disk_size = var.disk_size,
          disk_type = var.disk_type,
          location = var.location,
          target_secret = var.target_secret,
          zones = var.zones,
          subnets = var.subnets,
        })
}

resource "null_resource" "check_shoot_status" {
  provisioner "local-exec" {
    command = "/tmp/shoot-status"
  }
  depends_on = [kubectl_manifest.gardener_shoot]
}

To check the status of the K8s resource creation. I created a binary to check the status which works on initial run. How do i trigger the null_resource when the resource changes ?

Kevin

It seems that you can achieve your goal with triggers argument. Here is the link to docs โ€“ https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource

Hi @vasylenko,

Thanks for the reply. I did the following

resource "null_resource" "check_shoot_status" {
  triggers = {
    //shoot_id = kubectl_manifest.gardener_shoot.id
    always_run = "${timestamp()}"
  }

  provisioner "local-exec" {
    command = "/tmp/shoot-status"
  }

  depends_on = [kubectl_manifest.gardener_shoot]
}

Which works well every time irrespective if the resource changes. However is there a way to trigger only when the resource changes or associate shoot_id to the provisioner?

Kevin

@linuxbsdfreak It looks that you already have the answer in your commented code

triggers {
  shoot_id = "${kubectl_manifest.gardener_shoot.id}"
}

This is exactly how you can map trigger to specific attribute of another resource (within a module scope of course).
I am not sure what shoot_id is (and I could not find documentation for your provider online), but your idea is correct. So if the kubectl_manifest resource type of your provider does have the id attribute, then your trigger should work as expected: be triggered once the id attribute is changed.

Hi @vasylenko,

Thanks for the feedback. I tried that however it did not work. I am only doing a kubectl apply with the kubectl provider from the github.com site. It detects the change. However it does not trigger the local-exec. Wondering what trigger value I need to set for the resource.

Kevin

@linuxbsdfreak The main idea is that you need to reference a value that changes in order to make your trigger do its work. Perhaps uid or live_uid (found that in docs you provided). Unfortunately Iโ€™m not quite good with k8s yet, so I canโ€™t say for sure from the provider point of view. But the trigger will work only if the value (you are referencing to) is changed.