Skip to content

You are viewing documentation for Instruqt 2.0 Labs - our upcoming product releasing in September 2026. For current Tracks documentation, please visitdocs.instruqt.com.

Certificate Leaf


Defined incertificates.hcl

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.

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.

resource "certificate_leaf" "name" {
ca_key = resource.certificate_ca.root.private_key.path
ca_cert = resource.certificate_ca.root.certificate.path
output = "./server-certs"
}
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

FieldTypeRequiredDescription
ca_keystringPath to the private key for the root CA
ca_certstringPath to the root CA certificate
ip_addresseslist(string)IP addresses to add to the certificate
dns_nameslist(string)DNS names to add to the certificate
outputstringOutput location for the certificate

Private Key

certificate_leafPrivate Key

Private key output

FieldTypeRequiredDescription
filenamestringFilename of the private key
directorystringDirectory containing the private key
pathstringFull path to the private key
contentsstringContents of the private key

Public Key PEM

certificate_leafPublic Key PEM

Public key PEM output

FieldTypeRequiredDescription
filenamestringFilename of the public key
directorystringDirectory containing the public key
pathstringFull path to the public key
contentsstringContents of the public key

Public Key SSH

certificate_leafPublic Key SSH

Public key SSH output

FieldTypeRequiredDescription
filenamestringFilename of the SSH public key
directorystringDirectory containing the SSH public key
pathstringFull path to the SSH public key
contentsstringContents of the SSH public key

Certificate

certificate_leafCertificate

Certificate output

FieldTypeRequiredDescription
filenamestringFilename of the certificate
directorystringDirectory containing the certificate
pathstringFull path to the certificate
contentsstringContents of the certificate

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
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"
}
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"
}
}
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"
}
resource "certificate_ca" "service_mesh_ca" {
output = "./mesh-ca"
}
# API service certificate
resource "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 certificate
resource "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"
}
}
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"
}
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"
}
}
  1. Subject Alternative Names: Always include relevant DNS names and IP addresses for proper certificate validation
  2. Certificate Organization: Use descriptive output directories to organize certificates by service or purpose
  3. File References: Use .path for file system operations and .contents for inline certificate data
  4. Security: Protect private keys and limit access to certificate files
  5. Validation: Include all hostnames and IPs that clients will use to connect to your services
  6. Certificate Chain: Ensure CA certificates are properly distributed to clients for validation
  7. Naming Conventions: Use clear naming that indicates the certificate’s purpose and scope
  8. Environment Separation: Generate separate certificates for different environments (dev, staging, prod)