# Install cert-manager (Helm)
# helm install cert-manager jetstack/cert-manager # --namespace cert-manager # --create-namespace # --set installCRDs=true
---
# ClusterIssuer for Let's Encrypt (staging)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: devops@example.com
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: nginx
---
# ClusterIssuer for Let's Encrypt (production)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: devops@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
# HTTP-01 for standard domains
- http01:
ingress:
class: nginx
# DNS-01 for wildcards (Route53 example)
- dns01:
route53:
region: us-east-1
hostedZoneID: Z1234567890ABC
selector:
dnsZones:
- "example.com"
---
# Certificate resource
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-tls
namespace: production
spec:
secretName: app-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: app.example.com
dnsNames:
- app.example.com
- api.example.com
- "*.app.example.com"
duration: 2160h # 90 days
renewBefore: 720h # 30 days before expiry
---
# Ingress with automatic TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/hsts: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app
port:
number: 80
#!/bin/bash
# Certbot for non-Kubernetes environments
# Install certbot
apt-get update && apt-get install -y certbot python3-certbot-nginx
# Obtain certificate (Nginx plugin)
certbot --nginx -d app.example.com -d api.example.com --email devops@example.com --agree-tos --non-interactive
# Obtain certificate (standalone)
certbot certonly --standalone -d app.example.com --email devops@example.com --agree-tos
# Obtain wildcard (DNS challenge)
certbot certonly --manual --preferred-challenges dns -d "*.example.com" --email devops@example.com --agree-tos
# Test renewal
certbot renew --dry-run
# Auto-renewal (cron)
# 0 12 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
# Check certificate expiry
echo | openssl s_client -servername app.example.com -connect app.example.com:443 2>/dev/null | openssl x509 -noout -dates
# Certificate locations
# /etc/letsencrypt/live/app.example.com/fullchain.pem
# /etc/letsencrypt/live/app.example.com/privkey.pem
TLS certificates encrypt traffic between clients and servers. Let's Encrypt provides free, automated certificates via the ACME protocol. In Kubernetes, cert-manager automates certificate issuance and renewal. A ClusterIssuer configures the ACME server and solver method. HTTP-01 challenges validate domain ownership via HTTP endpoints. DNS-01 challenges use DNS TXT records, required for wildcard certificates. Certificate resources request certificates for specific domains. cert-manager stores certificates as Kubernetes Secrets. Ingress annotations like cert-manager.io/cluster-issuer trigger automatic certificate provisioning. Certificates auto-renew before expiration. For non-Kubernetes environments, certbot handles certificate management with automatic renewal via cron or systemd timers.
Related snips
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
S3 bucket policy that enforces TLS and blocks public reads
package deps
import (
"crypto/tls"
"crypto/x509"
"net/http"
mTLS client configuration with custom root CA pool
server {
listen 443 ssl;
server_name internal-api.example.com;
ssl_certificate /etc/nginx/tls/server.crt;
ssl_certificate_key /etc/nginx/tls/server.key;
Mutual TLS between internal services with Nginx
import requests
response = requests.get('https://crt.sh/', params={'q': '%.example.com', 'output': 'json'}, timeout=15)
response.raise_for_status()
certs = response.json()
print(certs[:5])
Certificate transparency checks for unexpected certificate issuance
#!/usr/bin/env bash
set -euo pipefail
certbot renew --quiet --deploy-hook "systemctl reload nginx"
openssl x509 -enddate -noout -in /etc/letsencrypt/live/example.com/fullchain.pem
TLS certificate automation with certbot and strict renewal checks
final class PinnedSessionDelegate: NSObject, URLSessionDelegate {
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
Client certificate pinning considerations for mobile apps
Share this code
Here's the card — post it anywhere.