0

I'm looking for the following experience:

  1. User Terraforms my stack. This causes default configuration stanzas to be populated in an according consul KV location, say /app/stackname/config.txt
  2. When I upgrade my code, let's say I have a new default config. If the config is still the old default value, upgrade it to the new default value. If the user has changed it, don't mess with it.
  3. If the KV config is missing, for whatever reason, repopulate it with the default

I'm having trouble managing this.

I've tried using consul_keys as both a data source and resource to detect if my value exists, but I'm unclear on how to handle case (2) above. consul_key_prefix seems too aggressive for my purposes. Any help appreciated.

1 Answers1

2

Using the consul_keys resource would be the way to go here, otherwise, consul_key_prefix will overwrite whatever changes were made by a user.

Now the tricky part as you've stated is how to handle use case no 2. Considering the following statements:

If the config is still the old default value, upgrade it to the new default value.

This would be handled by Terraform, once you update your variable definition, those new changes will be automatically applied.

If the user has changed it, don't mess with it.

This is where it gets complicated. Depending on the Terraform version you use, you could use a precondition block in combination with a data block.

I think defining a new key/property here /app/stackname/ named like is_user_managed could help.

By using a data source block you could retrieve the value set (true or false) and then reference it in the precondition block of the resource.

data "consul_keys" "is_user_managed" {
  key {
    name    = "is_user_managed"
    path    = "/app/stackname/is_user_managed"
    default = "false"
  }
}

resource "consul_keys" "this" {

  ...

  lifecycle {
    precondition {
      condition     = data.consul_keys.var.is_user_managed == "false"
      error_message = "This resource is being managed by an external identity"
    }
  }
}

Now the downside of this approach is that if the condition is not met, it'll block all the operations(which can be easily solved by going into Consul and setting the value to "false"), so it really depends on how your code is structured.

Another idea is to get the KV (/app/stackname/is_user_managed) using the consul CLI, and then based on the result of that run Terraform using the target flag which it's not recommended.

javierlga
  • 1,409
  • 9
  • 14
  • Thanks for this. I'm almost at a point of just using Terraform to generate a HOWTO value as just a human-readable guide of what keys to set for which behavior. – Frank Siler Feb 25 '23 at 03:41