Certificate Leaf
The certificate_leaf resource generates leaf certificates signed by a Certificate Authority (CA). These are end-entity certificates used for servers, clients, or other applications that require TLS/SSL certificates signed by a trusted authority.
Use Cases
Section titled “Use Cases”As a lab author, you can use certificate_leaf resources to:
- Server Certificate Generation: Create TLS certificates for web servers, APIs, and other network services
- Client Certificate Authentication: Generate client certificates for mutual TLS authentication scenarios
- Service-to-Service Communication: Enable secure communication between microservices using signed certificates
Certificate leaf resources provide signed certificates for specific services while maintaining the certificate chain of trust.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "certificate_leaf" "name" { ca_key = resource.certificate_ca.root.private_key.path ca_cert = resource.certificate_ca.root.certificate.path output = "./server-certs"}Full Syntax
Section titled “Full Syntax”resource "certificate_leaf" "name" { ca_key = resource.certificate_ca.root.private_key.path ca_cert = resource.certificate_ca.root.certificate.path output = "./server-certs"
dns_names = [ "localhost", "api.example.com", "www.example.com" ]
ip_addresses = [ "127.0.0.1", "192.168.1.100", "10.0.0.5" ]}Fields
| Field | Type | Required | Description |
|---|---|---|---|
ca_ | string | ✓ | Path to the private key for the root CA |
ca_ | string | ✓ | Path to the root CA certificate |
ip_ | list(string) | — | IP addresses to add to the certificate |
dns_ | list(string) | — | DNS names to add to the certificate |
output | string | ✓ | Output location for the certificate |
Private Key
Private key output
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | — | Filename of the private key |
directory | string | — | Directory containing the private key |
path | string | — | Full path to the private key |
contents | string | — | Contents of the private key |
Public Key PEM
Public key PEM output
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | — | Filename of the public key |
directory | string | — | Directory containing the public key |
path | string | — | Full path to the public key |
contents | string | — | Contents of the public key |
Public Key SSH
Public key SSH output
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | — | Filename of the SSH public key |
directory | string | — | Directory containing the SSH public key |
path | string | — | Full path to the SSH public key |
contents | string | — | Contents of the SSH public key |
Certificate
Certificate output
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | — | Filename of the certificate |
directory | string | — | Directory containing the certificate |
path | string | — | Full path to the certificate |
contents | string | — | Contents of the 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 |
Examples
Section titled “Examples”Simple Server Certificate
Section titled “Simple Server Certificate”resource "certificate_ca" "root" { output = "./ca"}
resource "certificate_leaf" "server" { ca_key = resource.certificate_ca.root.private_key.path # e.g., "./ca/private_key.pem" ca_cert = resource.certificate_ca.root.certificate.path # e.g., "./ca/certificate.pem" output = "./server-certs"
dns_names = ["localhost"] ip_addresses = ["127.0.0.1"]}
output "server_cert_path" { value = resource.certificate_leaf.server.certificate.path # e.g., "./server-certs/certificate.pem"}Multi-Domain Web Certificate
Section titled “Multi-Domain Web Certificate”resource "certificate_leaf" "web" { ca_key = resource.certificate_ca.root.private_key.path ca_cert = resource.certificate_ca.root.certificate.path output = "./web-certs"
dns_names = [ "example.com", "www.example.com", "api.example.com", "admin.example.com" ]
ip_addresses = [ "192.168.1.10", "10.0.0.100" ]}
resource "container" "web_server" { image { name = "nginx:alpine" }
volume { source = resource.certificate_leaf.web.certificate.path # e.g., "./web-certs/certificate.pem" destination = "/etc/ssl/certs/server.crt" type = "bind" read_only = true }
volume { source = resource.certificate_leaf.web.private_key.path # e.g., "./web-certs/private_key.pem" destination = "/etc/ssl/private/server.key" type = "bind" read_only = true }
port { local = "443" host = "8443" }}Client Certificate Authentication
Section titled “Client Certificate Authentication”resource "certificate_leaf" "client" { ca_key = resource.certificate_ca.root.private_key.path ca_cert = resource.certificate_ca.root.certificate.path output = "./client-certs"
dns_names = ["client.internal"]}
resource "template" "client_config" { source = <<-EOF client: certificate: ${resource.certificate_leaf.client.certificate.path} # e.g., "./client-certs/certificate.pem" private_key: ${resource.certificate_leaf.client.private_key.path} # e.g., "./client-certs/private_key.pem" ca_certificate: ${resource.certificate_ca.root.certificate.path} # e.g., "./ca/certificate.pem"
tls: verify_peer: true verify_host: true EOF
destination = "./client-config.yaml"}Service Mesh Certificates
Section titled “Service Mesh Certificates”resource "certificate_ca" "service_mesh_ca" { output = "./mesh-ca"}
# API service certificateresource "certificate_leaf" "api_service" { ca_key = resource.certificate_ca.service_mesh_ca.private_key.path ca_cert = resource.certificate_ca.service_mesh_ca.certificate.path output = "./api-service-certs"
dns_names = [ "api-service", "api-service.default.svc.cluster.local" ]}
# Database service certificateresource "certificate_leaf" "database_service" { ca_key = resource.certificate_ca.service_mesh_ca.private_key.path ca_cert = resource.certificate_ca.service_mesh_ca.certificate.path output = "./database-service-certs"
dns_names = [ "database-service", "database-service.default.svc.cluster.local" ]}
resource "container" "api" { image { name = "api:latest" }
environment = { TLS_CERT_FILE = resource.certificate_leaf.api_service.certificate.path # e.g., "./api-service-certs/certificate.pem" TLS_KEY_FILE = resource.certificate_leaf.api_service.private_key.path # e.g., "./api-service-certs/private_key.pem" CA_CERT_FILE = resource.certificate_ca.service_mesh_ca.certificate.path # e.g., "./mesh-ca/certificate.pem" }}Load Balancer Certificate
Section titled “Load Balancer Certificate”resource "certificate_leaf" "load_balancer" { ca_key = resource.certificate_ca.root.private_key.path ca_cert = resource.certificate_ca.root.certificate.path output = "./lb-certs"
dns_names = [ "lb.example.com", "loadbalancer.internal", "*.apps.example.com" # Wildcard certificate ]
ip_addresses = [ "192.168.1.50", # Load balancer IP "10.0.0.50" # Internal IP ]}
resource "template" "nginx_ssl_config" { source = <<-EOF server { listen 443 ssl; server_name lb.example.com *.apps.example.com;
ssl_certificate ${resource.certificate_leaf.load_balancer.certificate.path}; # e.g., "./lb-certs/certificate.pem" ssl_certificate_key ${resource.certificate_leaf.load_balancer.private_key.path}; # e.g., "./lb-certs/private_key.pem"
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;
location / { proxy_pass http://backend; } } EOF
destination = "./nginx-ssl.conf"}Certificate Contents Usage
Section titled “Certificate Contents Usage”resource "certificate_leaf" "app_cert" { ca_key = resource.certificate_ca.root.private_key.path ca_cert = resource.certificate_ca.root.certificate.path output = "./app-certs"
dns_names = ["app.local"]}
resource "container" "secure_app" { image { name = "myapp:latest" }
environment = { # Pass certificate contents directly as environment variables TLS_CERTIFICATE = resource.certificate_leaf.app_cert.certificate.contents TLS_PRIVATE_KEY = resource.certificate_leaf.app_cert.private_key.contents TLS_CA_CERT = resource.certificate_ca.root.certificate.contents
# Certificate metadata CERT_FILENAME = resource.certificate_leaf.app_cert.certificate.filename # e.g., "certificate.pem" CERT_DIRECTORY = resource.certificate_leaf.app_cert.certificate.directory # e.g., "./app-certs" }}Best Practices
Section titled “Best Practices”- Subject Alternative Names: Always include relevant DNS names and IP addresses for proper certificate validation
- Certificate Organization: Use descriptive output directories to organize certificates by service or purpose
- File References: Use
.pathfor file system operations and.contentsfor inline certificate data - Security: Protect private keys and limit access to certificate files
- Validation: Include all hostnames and IPs that clients will use to connect to your services
- Certificate Chain: Ensure CA certificates are properly distributed to clients for validation
- Naming Conventions: Use clear naming that indicates the certificate’s purpose and scope
- Environment Separation: Generate separate certificates for different environments (dev, staging, prod)
