DevOps Coding Challenge #8: Certificate Expiry Guardian
The Scenario
It's 2 AM. Your monitoring alerts are going crazy. Half your microservices are down because the payment gateway's SSL certificate expired overnight. Sound familiar?
Your team has been burned by certificate expiry outages one too many times. The boss wants a proactive solution that catches these issues before they become 3 AM wake-up calls.
Your Mission
Build a certificate expiry monitoring tool that DevOps teams can run as a cron job or integrate into their CI/CD pipeline.
Requirements
Your tool must:
Read configuration from a YAML file listing all endpoints to monitor
Check SSL certificate expiry for each endpoint in parallel
Categorize certificates by urgency:
🔴 CRITICAL: Expires ≤ 7 days
🟡 WARNING: Expires ≤ 30 days
🟢 OK: Expires > 30 days
Output results in both human-readable and JSON formats
Handle failures gracefully (timeouts, invalid certs, unreachable hosts)
Exit with appropriate codes for automation (0 = all good, 1 = warnings, 2 = critical)
Sample Config (endpoints.yaml)
endpoints:
- name: "Production API"
host: "api.company.com"
port: 443
- name: "Payment Gateway"
host: "payments.company.com"
port: 443
- name: "Internal Dashboard"
host: "dashboard.internal.com"
port: 8443
timeout: 10
Expected Output
Certificate Expiry Report - 2025-07-12
=======================================
🔴 CRITICAL (≤7 days):
└─ api.company.com:443 → Expires in 3 days (2025-07-15)
🟡 WARNING (≤30 days):
└─ payments.company.com:443 → Expires in 25 days (2025-08-06)
🟢 OK (>30 days):
└─ dashboard.internal.com:8443 → Expires in 89 days (2025-10-09)
SUMMARY: 1 critical, 1 warning, 1 healthy
Exit code: 2 (CRITICAL findings detected)
Solution Guidance
Key Implementation Tips:
Use
concurrent.futures
(Python) or goroutines (Go) for parallel checkingSet reasonable timeouts (5-10 seconds) for SSL handshakes
Parse certificate expiry dates carefully - they're in UTC
Handle edge cases like self-signed certs and SNI requirements
Python Starter Code:
import ssl
import socket
import yaml
from datetime import datetime, timezone
from concurrent.futures import ThreadPoolExecutor
def get_certificate_expiry(host, port, timeout=10):
"""Get SSL certificate expiry date for a host:port"""
try:
context = ssl.create_default_context()
with socket.create_connection((host, port), timeout=timeout) as sock:
with context.wrap_socket(sock, server_hostname=host) as ssock:
cert = ssock.getpeercert()
expiry_str = cert['notAfter']
# Parse: 'Jan 15 12:00:00 2025 GMT'
expiry_date = datetime.strptime(expiry_str, '%b %d %H:%M:%S %Y %Z')
return expiry_date.replace(tzinfo=timezone.utc)
except Exception as e:
raise Exception(f"Failed to get certificate for {host}:{port} - {str(e)}")
def check_endpoint(endpoint):
"""Check a single endpoint and return status"""
# Your implementation here
pass
if __name__ == "__main__":
# Load config, check endpoints in parallel, format output
pass
Go Starter Code:
package main
import (
"crypto/tls"
"fmt"
"net"
"time"
"gopkg.in/yaml.v2"
)
type Endpoint struct {
Name string `yaml:"name"`
Host string `yaml:"host"`
Port int `yaml:"port"`
Timeout int `yaml:"timeout"`
}
func getCertificateExpiry(host string, port int, timeout time.Duration) (time.Time, error) {
dialer := &net.Dialer{Timeout: timeout}
conn, err := tls.DialWithDialer(dialer, "tcp", fmt.Sprintf("%s:%d", host, port), &tls.Config{
ServerName: host,
})
if err != nil {
return time.Time{}, err
}
defer conn.Close()
certs := conn.ConnectionState().PeerCertificates
if len(certs) == 0 {
return time.Time{}, fmt.Errorf("no certificates found")
}
return certs[0].NotAfter, nil
}
func main() {
// Your implementation here
}
Testing Strategy
Test with real sites:
google.com:443
,github.com:443
Test edge cases: Invalid hosts, connection timeouts
Verify parallel execution: Should be much faster than sequential
Test output formats: Both human-readable and JSON
Bonus Challenges
Add Slack/Teams webhook notifications
Generate Prometheus metrics
Support client certificate authentication
Add certificate chain validation
Include issuer and SAN information
Language: Python or Go (your choice!)
Drop your solution in the comments! Let's see who can build the most elegant certificate guardian.