ENV:
hashicorp/vault - v2.23.0 & 2.24.0
hashicorp/tls - v3.1.0
Vault - 1.8.2
terraform - 1.0.7-1.
Server - Linux (Amazon)
Hi One for the brains trust.
I have written a number of Terraform scripts that install and configure a root & intermediate CA server in Vault.
Everything is going well in the configuration, with the exception of writing the certificates back to the CA server.
My code is based on the instructions at
I have exactly what I would like in a dev instance of vault, this was created using the vault CLI.
But I would like a repeatable process in order to be able to do this in multiple environments.
With the Terraform instance of the configuration, I can perform all tasks, including writing the keypairs out to files. The keypairs are matched as confirmed using openssl modulus/md5.
Occasionally, my code works as required, but then as part of my testing I hose the vault instance, reinitialize and rerun, and is not repeatable. The 2 CA’s are created with all roles/groups/policies, but when you go into secrets/CA/Configuration/Configure I am presented with 2 buttons for ‘Configure CA’ and ‘Set signed Intermediate’.
This should instead present me with the options to download CA Certificates in either Pem or Der format and ‘download ca certificate chain’
Unless there is something wrong, it appears that the 2 code blocks for ‘vault_pki_secret_backend_config_ca’ are not working as advertised.
For the CA I create the private key using tls_private_key and sign the ca cert with it.
resource "vault_mount" "root" {
type = "pki"
path = "pki-root-ca"
default_lease_ttl_seconds = 31556952 # 1 years
max_lease_ttl_seconds = 157680000 # 5 years
description = "Root Certificate Authority"
}
resource "vault_pki_secret_backend_role" "pki_root_r" {
backend = vault_mount.root.path
name = "pki_root_r"
ttl = 3600
allow_ip_sans = false
key_type = "rsa"
key_bits = 4096
allowed_domains = ["<REDACTED>"]
allow_subdomains = false
allow_localhost = false
allow_bare_domains = false
allow_any_name = false
allow_glob_domains = false
enforce_hostnames = true
ou = ["${tls_self_signed_cert.ca_cert.subject[0].organizational_unit}"]
organization = ["${tls_self_signed_cert.ca_cert.subject[0].organization}"]
country = ["${tls_self_signed_cert.ca_cert.subject[0].country}"]
}
resource "vault_mount" "pki_int" {
path = "pki-intermediate"
type = "pki"
description = "This is the intermediate CA"
default_lease_ttl_seconds = 3600
max_lease_ttl_seconds = 86400
}
# Modify the mount point and set URLs for the issuer and crl.
resource "vault_pki_secret_backend_config_urls" "config_urls" {
depends_on = [ vault_mount.root ]
backend = vault_mount.root.path
issuing_certificates = ["https://<REDACTED>:8300/v1/pki/ca"]
crl_distribution_points= ["http://<REDACTED>:8300/v1/pki/crl"]
}
resource "tls_private_key" "ca_key" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "tls_self_signed_cert" "ca_cert" {
private_key_pem = tls_private_key.ca_key.private_key_pem
key_algorithm = "RSA"
subject {
common_name = "<REDACTED> Root CA"
organization = "<REDACTED>"
organizational_unit = "<REDACTED>"
country = "<REDACTED>"
}
# 175200 = 20 years
validity_period_hours = 175200
allowed_uses = [
"cert_signing",
"crl_signing"
]
is_ca_certificate = true
}
I then try to write the keypairs to the root ca
resource "vault_pki_secret_backend_config_ca" "root_ca_config" {
depends_on = [ vault_mount.root, tls_private_key.ca_key ]
backend = vault_mount.root.path
pem_bundle = local_file.root_ca_pem_bundle.sensitive_content
}
I have tried creating the CSR with both internal/exported types no difference.
resource "vault_pki_secret_backend_intermediate_cert_request" "intermediate" {
depends_on = [ vault_mount.pki_int ]
backend = vault_mount.pki_int.path
type = "internal" #'exported/internal'
# This appears to be overwritten when the CA signs this cert, I'm not sure
# the importance of common_name here.
common_name = "<REDACTED> Intermediate Certificate"
format = "pem"
private_key_format = "der"
key_type = "rsa"
key_bits = "4096"
}
resource "vault_pki_secret_backend_root_sign_intermediate" "intermediate" {
depends_on = [
vault_pki_secret_backend_intermediate_cert_request.intermediate
]
backend = vault_mount.root.path
csr = vault_pki_secret_backend_intermediate_cert_request.intermediate.csr
common_name = "<REDACTED> Intermediate Certificate"
exclude_cn_from_sans = true
ou = "<REDACTED>"
organization = "<REDACTED>"
country = "<REDACTED>"
# Note that I am asking for 8 years here, since the vault_mount.root has a max_lease_ttl of 5 years
# this 8 year request is shortened to 5.
ttl = 252288000 #8 years
}
resource "vault_pki_secret_backend_intermediate_set_signed" "intermediate" {
backend = vault_mount.pki_int.path
certificate = "${vault_pki_secret_backend_root_sign_intermediate.intermediate.certificate}\n${tls_self_signed_cert.ca_cert.cert_pem}"
}
resource "vault_pki_secret_backend_config_ca" "int_ca_config" {
depends_on = [
vault_mount.pki_int
]
backend = vault_mount.pki_int.path
#pem_bundle = local_file.ca_int_pem_bundle.sensitive_content
pem_bundle = "${path.root}/output/int_ca/int_ca_pem_bundle.pem"
}
resource "local_file" "ca_int_pem_bundle" {
sensitive_content = vault_pki_secret_backend_root_sign_intermediate.intermediate.certificate
filename = "${path.root}/output/int_ca/int_ca_pem_bundle.pem"
file_permission = "0777"
}
resource "vault_pki_secret_backend_role" "role-server-cer" {
backend = vault_mount.pki_int.path
name = "pki_int_r"
allowed_domains = [ "<REDACTED>" ]
allow_subdomains = true
allow_glob_domains = false
allow_any_name = false
enforce_hostnames = true
allow_ip_sans = true
server_flag = true
client_flag = false
ou = ["<REDACTED>"]
organization = ["<REDACTED>"]
country = ["<REDACTED>"]
# 2 years
max_ttl = 63113904
# 30 days
ttl = 2592000
no_store = true
}
When I upgrade the vault provider to the latest version I get the following error
URL: PUT http://127.0.0.1:8200/v1/pki-root-ca/root/sign-intermediate
│ Code: 500. Errors:
│
│ * 1 error occurred:
│ * could not fetch the CA certificate (was one set?): backend must be configured with a CA certificate/key
│
│
│
│ with vault_pki_secret_backend_root_sign_intermediate.intermediate,
│ on ca.tf line 152, in resource "vault_pki_secret_backend_root_sign_intermediate" "intermediate":
│ 152: resource "vault_pki_secret_backend_root_sign_intermediate" "intermediate" {
│
The logs, in debug, don’t show anything in relation to the CA keypairs being added to the vault instance.
There are no firewalls, Selinux is disabled.