Using Vault terraform to manage root CA rotation

We are currently making use of the vault terraform modules vault_pki_secret_backend and vault_pki_secret_backend_root_cert to provision a root CA.

I’m now looking at the Vault functionality to rotate the root CA as described in Build your own certificate authority (CA) | Vault | HashiCorp Developer. That mentions being able to rotate the certificate using a CLI command like vault write pki/root/rotate/internal.

I’m trying to avoid the need to run any commands, and am hoping to manage this as an enhancement to the current terraform we have.

So far though, looking at the vault terraform docs (Terraform Registry), I can’t see anyway to manage this via vault terraform.

Reaching out to see if the experts here know if it is possible and if so for some guidance on how to rotate the root CA via terraform.

Thanks

These are not modules, they are resources.

The root/rotate/ endpoint is a rather pointless endpoint which is identical to issuers/generate/root/, except that the default value for issuer_name is changed to next.

So, I think you might be able to just use vault_pki_secret_backend_root_cert for that part, setting issuer_name to your choice of name for the new CA, to implement that step of that tutorial using Terraform.

Thanks for the tips @maxb. We started to try to implement this with terraform. What we are currently experiencing is the following:
On the first terraform “apply”, we see two issuers for the “vault mount” (I’ve called them “current” and “next”).

However on a subsequent apply (with no changes to the terraform), we see one of the issuers is deleted and we are only left with one. Any further runs just switch between having “current” or “next”.

The output of the terraform apply gives some further clues:

vault_pki_secret_backend_root_cert.root-current: Refreshing state... [id=pki/root/root/generate/internal]
vault_pki_secret_backend_root_cert.root-next: Refreshing state... [id=pki/root/root/generate/internal]

Note that the two different resources have the same id.

Looking at the vault terraform implementation, it doesn’t look like this is supported.

This assumes the ID is the mount path.

And likewise the delete logic assumes the resource is unique for a given path. https://github.com/hashicorp/terraform-provider-vault/blob/02ed3c793a6be82346fe5938d804c6ff3481cc79/vault/resource_pki_secret_backend_root_cert.go#L469

So while we have tried to use vault_pki_secret_backend_root_cert as part of following the root CA rotation guide, it doesn’t appear to support what is required.

Looking for some guidance on next steps.

Thanks

Luke

Here is a minimal terraform example which reproduces the issue for us:

locals {
  vault_addr                   = "<vault-addr>"
  path = "pki/root"
  pki_ca_key_bits = 2048
  root_cert_ttl =  "17520h" # 2 years
}

provider "vault" {
  version = "3.18.0"
  token   = "<vault-token>"
  address = "<vault-addr>"
}

resource "vault_mount" "pki" {
  path = local.path
  type = "pki"
}

resource "vault_pki_secret_backend_root_cert" "root-current" {
  depends_on   = [vault_mount.pki]
  backend      = vault_mount.pki.path
  type         = "internal"
  common_name  = "current.root"
  key_bits     = local.pki_ca_key_bits
  ttl          = local.root_cert_ttl
  organization = "root_cert_for_${vault_mount.pki.accessor}"
  issuer_name  = "current"
}

resource "vault_pki_secret_backend_config_urls" "config_urls" {
  backend                 = vault_mount.pki.path
  issuing_certificates    = ["${local.vault_addr}/v1/${vault_mount.pki.path}/ca"]
  crl_distribution_points = ["${local.vault_addr}/v1/${vault_mount.pki.path}/crl"]
}

resource "vault_pki_secret_backend_root_cert" "root-next" {
  depends_on   = [vault_mount.pki]
  backend      = vault_mount.pki.path
  type         = "internal"
  common_name  = "next.root"
  key_bits     = local.pki_ca_key_bits
  ttl          = local.root_cert_ttl
  organization = "root_cert_for_${vault_mount.pki.accessor}"
  issuer_name  = "next"
}

Oh… That’s unfortunate. It appears the full range of multi issuer workflows were not considered when updating terraform-provider-vault when multi-issuer support was added.

It appears a fix to the provider will be needed (it would be good if you could file an issue, if there isn’t one already.)

Thanks again @maxb. I’ve raised an issue vault_pki_secret_backend_root_cert resource does not support multiple issuers · Issue #1968 · hashicorp/terraform-provider-vault · GitHub.