2
votes

I am trying to use Terraform to create a self signed certificate to use internally in a test/development environment.

I first create a CA private key, self signed certificate.

Then I create a certificate signing request and private key for an internal domain name I want to enable HTTPS for.

Then I sign the certificate. Here's entire Terraform manifest I use:

resource "tls_private_key" "ca" {
  algorithm = "ECDSA"
  ecdsa_curve = "P384"
}

resource "tls_self_signed_cert" "ca" {
  key_algorithm = "${tls_private_key.ca.algorithm}"
  private_key_pem = "${tls_private_key.ca.private_key_pem}"

  subject {
    common_name = "Example CA"
    organization = "Example, Ltd"
    country = "GB"
  }

  validity_period_hours = 43800
  is_ca_certificate = true

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
    "client_auth",
  ]
}

resource "tls_private_key" "registry" {
  algorithm = "ECDSA"
  ecdsa_curve = "P384"
}

resource "tls_cert_request" "registry" {
  key_algorithm = "${tls_private_key.registry.algorithm}"
  private_key_pem = "${tls_private_key.registry.private_key_pem}"

  subject {
    common_name = "registry.test.example.com"
    organization = "Example, Ltd"
    country = "GB"
  }

  dns_names = ["registry.test.example.com"]
}

resource "tls_locally_signed_cert" "registry" {
  cert_request_pem = "${tls_cert_request.registry.cert_request_pem}"

  ca_key_algorithm = "${tls_private_key.ca.algorithm}"
  ca_private_key_pem = "${tls_private_key.ca.private_key_pem}"
  ca_cert_pem = "${tls_self_signed_cert.ca.cert_pem}"

  validity_period_hours = 43800

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
    "client_auth",
  ]
}

I run the Terraform manifest. Then I extracted the generated certificates from the state file and saved them into files.

I tried to verify the final certificate with openssl but get an error:

$ openssl verify -CAfile ca-cert.pem registry.pem 
registry.pem: C = GB, ST = , L = , postalCode = , O = "Example, Ltd", OU = , CN = registry.example.com
error 20 at 0 depth lookup:unable to get local issuer certificate

Any ideas what the problem is? I have spent a lot of time trying to figure this out.

Basically I want to use this to enable HTTPS for a private Docker registry in my test/dev environment.

1

1 Answers

3
votes

You need to add cert_signing to the tls_private_key.ca.allowed_uses:

resource "tls_self_signed_cert" "ca" {
  key_algorithm = "${tls_private_key.ca.algorithm}"
  private_key_pem = "${tls_private_key.ca.private_key_pem}"

  subject {
    common_name = "Example CA"
    organization = "Example, Ltd"
    country = "GB"
  }

  validity_period_hours = 43800
  is_ca_certificate = true

  allowed_uses = [
    "key_encipherment",
    "digital_signature",
    "server_auth",
    "client_auth",
    "cert_signing"
  ]
}

See: https://www.terraform.io/docs/providers/tls/r/self_signed_cert.html#cert_signing