Preventing secrets from getting stomped when running terraform apply

We’re a Core Services team, starting to stand up HCP Vault for other teams to use. I’m leaning heavily on templated ACL policies and for_each loops in my TF files. One of the things I want to do for each team/application being onboarded is to provide them with security boundaries within their engine - eg the MobileApp team will get a kv-v2 engine, with paths at /secrets/MobileApp/dev , /secrets/MobileApp/prod, etc. We’ll make AppRole entities that only get access to /dev and /prod , using templated ACLs.

Terraform won’t let me make empty paths, so I create a dummy “example” secret under each path, looks like this

resource "vault_kv_secret_v2" "example" {
   for_each = {
       for app in local.app_boundaries : 
        "${app.app_name}/${app.boundary}" => app  if app.engine_type == "kv-v2"
   }

  provider      = vault
  mount         = vault_mount.engine[each.value.app_name].path
  name          = "${each.value.boundary}/example"
  data_json = jsonencode(
  {
    "${each.value.boundary}-foo"       = "${each.value.boundary}-bar"
  }
  )

  depends_on = [null_resource.kv1_to_kv2_migration]
}

When the using teams then start to make their own secrets in the future, via the UI inside our HCP instance, how do I keep terraform from deleting their newly-created secrets? I’m currently just running OSS TF from my own desktop but if we start using HCP TF, that has drift detection and I’m unsure how to do this.

I know I can do lifecycle { prevent_destroy = true } but I don’t care if they do delete their “example” secret, and I don’t see how that prevents items manually created from being destroyed.

Why do you think it would do that? You’re not instructing it to manage them, only the example path alone.

Though, I would hesitate to try to create an example secret with Terraform, as there is then no way to avoid Terraform fighting with the users if they change their example secret in any way.

I’m still learning Terraform as well, so if that won’t happen, awesome.

As I said, I wish I could just make a secret path without a secret (the “dev” and “prod” in my example), but that can’t be done, so I do have to make “example” secrets. If you have another way to do it, I’m very interested.

Don’t create an example, just write a doc for your teams with a naming convention.
Documentation is very important.

I take your point as general advice, but please re-read my original scenario. I need paths to exist within an engine to apply ACLs to, but Terraform doesn’t allow you to create a path in Vault without a secret.

There are no such things as empty paths in Vault, only secrets.

This is similar to objects in S3 buckets, rather than being like directories in a filesystem. In reality Vault secrets are named using strings, with the ability for those names to contain the / character. As a convenience the UI and certain API calls allow you to show secrets via a “virtual directory” type interface.

As a result until there is a secret there is no “directory”, so it isn’t possible to create an “empty directory”. This isn’t something specific to Terraform, but part of the design of K/V secrets within Vault.