Certificate CA
The certificate_ca resource generates Certificate Authority (CA) certificates and private keys. It creates self-signed root certificates that can be used to sign other certificates in PKI (Public Key Infrastructure) scenarios within lab environments.
Use Cases
Section titled “Use Cases”As a lab author, you can use certificate_ca resources to:
- Custom Root CA: Replace default CAs with lab-specific certificate authorities for controlled environments
- TLS/SSL Certificate Management: Generate root certificates for signing server and client certificates in HTTPS scenarios
Certificate CA resources provide the foundation for PKI-based security scenarios while ensuring consistent certificate generation.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "certificate_ca" "name" {  output = "./certs"}Full Syntax
Section titled “Full Syntax”resource "certificate_ca" "name" {  output = "./certificates"}Fields
Section titled “Fields”| Field | Required | Type | Description | 
|---|---|---|---|
| output | ✓ | string | Output directory where certificate and key files will be written | 
Computed Attributes
Section titled “Computed Attributes”These attributes are set by the system after certificate generation:
| Field | Type | Description | 
|---|---|---|
| private_key | File | The private key of the generated CA certificate | 
| public_key_pem | File | The PEM-formatted public key | 
| public_key_ssh | File | The SSH-formatted public key | 
| certificate | File | The generated CA certificate | 
File Object Structure
Section titled “File Object Structure”The File object contains information about generated certificate files:
| Field | Type | Description | 
|---|---|---|
| filename | string | The name of the generated file | 
| directory | string | The directory where the file is written | 
| path | string | The full absolute path to the file | 
| contents | string | The contents of the generated file | 
Validation Rules
Section titled “Validation Rules”- Output directory must be a valid path
- Generated files are written with appropriate permissions for certificate files
- Certificate generation is idempotent - same configuration produces same output
- Directory structure is created automatically if it doesn’t exist
Examples
Section titled “Examples”Simple CA Certificate
Section titled “Simple CA Certificate”resource "certificate_ca" "root" {  output = "./certs"}
output "ca_cert_path" {  value = resource.certificate_ca.root.certificate.path  # e.g., "./certs/certificate.pem"}
output "ca_key_path" {  value = resource.certificate_ca.root.private_key.path  # e.g., "./certs/private_key.pem"}CA for Signing Leaf Certificates
Section titled “CA for Signing Leaf Certificates”resource "certificate_ca" "lab_ca" {  output = "./ca-certificates"}
resource "certificate_leaf" "server_cert" {  ca_key  = resource.certificate_ca.lab_ca.private_key.path      # e.g., "./ca-certificates/private_key.pem"  ca_cert = resource.certificate_ca.lab_ca.certificate.path      # e.g., "./ca-certificates/certificate.pem"  output  = "./server-certs"
  dns_names    = ["localhost", "api.lab.local"]  ip_addresses = ["127.0.0.1", "192.168.1.100"]}Multiple Environment CAs
Section titled “Multiple Environment CAs”resource "certificate_ca" "production_ca" {  output = "./prod-ca"}
resource "certificate_ca" "staging_ca" {  output = "./staging-ca"}
resource "certificate_ca" "development_ca" {  output = "./dev-ca"}
# Use production CA for production servicesresource "certificate_leaf" "prod_api" {  ca_key  = resource.certificate_ca.production_ca.private_key.path  ca_cert = resource.certificate_ca.production_ca.certificate.path  output  = "./prod-api-certs"
  dns_names = ["api.production.local"]}
# Use development CA for dev servicesresource "certificate_leaf" "dev_api" {  ca_key  = resource.certificate_ca.development_ca.private_key.path  ca_cert = resource.certificate_ca.development_ca.certificate.path  output  = "./dev-api-certs"
  dns_names = ["api.development.local"]}Template Integration
Section titled “Template Integration”resource "certificate_ca" "webapp_ca" {  output = "./webapp-ca"}
resource "template" "ca_config" {  source = <<-EOF    # Certificate Authority Configuration    ca_certificate: ${resource.certificate_ca.webapp_ca.certificate.path}        # e.g., "./webapp-ca/certificate.pem"    ca_private_key: ${resource.certificate_ca.webapp_ca.private_key.path}        # e.g., "./webapp-ca/private_key.pem"    ca_public_key: ${resource.certificate_ca.webapp_ca.public_key_pem.path}      # e.g., "./webapp-ca/public_key.pem"
    # File information    ca_cert_filename: ${resource.certificate_ca.webapp_ca.certificate.filename}  # e.g., "certificate.pem"    ca_key_directory: ${resource.certificate_ca.webapp_ca.private_key.directory} # e.g., "./webapp-ca"  EOF
  destination = "./ca-config.yaml"}Certificate Contents Usage
Section titled “Certificate Contents Usage”resource "certificate_ca" "api_ca" {  output = "./api-ca"}
resource "container" "secure_api" {  image {    name = "nginx:alpine"  }
  environment = {    # Pass certificate contents as environment variables    CA_CERTIFICATE = resource.certificate_ca.api_ca.certificate.contents    CA_PUBLIC_KEY  = resource.certificate_ca.api_ca.public_key_pem.contents  }
  volume {    source      = resource.certificate_ca.api_ca.certificate.path    destination = "/etc/ssl/certs/ca.pem"    type        = "bind"    read_only   = true  }}Best Practices
Section titled “Best Practices”- Output Organization: Use descriptive output directories to organize different CA certificates
- File References: Use .pathattribute for file system operations and.contentsfor inline usage
- Security: Protect CA private keys - they are the root of trust for your certificate hierarchy
- Naming: Use meaningful names that reflect the CA’s purpose or environment
- Directory Structure: Organize certificates by environment or purpose for better maintainability
- Template Integration: Use templates to create configuration files that reference certificate paths
- Container Usage: Mount certificate files into containers using volume binds when needed
