Automation Example¶
This example demonstrates how to automate certificate generation using Certica’s Python API, perfect for integration with deployment scripts and CI/CD pipelines.
Scenario¶
You need to automatically generate certificates for multiple services during deployment. The script should:
Create a CA if it doesn’t exist
Generate certificates for a list of services
Update configuration files
Handle errors gracefully
Complete Python Script¶
#!/usr/bin/env python3
"""
Automated certificate generation script
"""
import sys
from pathlib import Path
from certica.ca_manager import CAManager
from certica.cert_manager import CertManager
# Configuration
BASE_DIR = "output"
CA_NAME = "production-ca"
CA_ORG = "My Company Inc."
CA_COUNTRY = "US"
CA_STATE = "California"
CA_CITY = "San Francisco"
CA_VALIDITY_DAYS = 3650 # 10 years
# Services configuration: {name: {dns: [...], ip: [...]}}
SERVICES = {
"web-server": {
"dns": ["example.com", "www.example.com"],
"ip": ["192.168.1.100"]
},
"api-server": {
"dns": ["api.example.com"],
"ip": ["192.168.1.101"]
},
"admin-server": {
"dns": ["admin.example.com"],
"ip": ["192.168.1.102"]
}
}
CERT_VALIDITY_DAYS = 365 # 1 year
CERT_KEY_SIZE = 2048
def create_ca_if_needed(ca_manager):
"""Create CA if it doesn't exist"""
ca_info = ca_manager.get_ca(CA_NAME)
if ca_info:
print(f"✓ CA '{CA_NAME}' already exists")
return ca_info
print(f"Creating CA: {CA_NAME}...")
try:
result = ca_manager.create_root_ca(
ca_name=CA_NAME,
organization=CA_ORG,
country=CA_COUNTRY,
state=CA_STATE,
city=CA_CITY,
validity_days=CA_VALIDITY_DAYS,
key_size=CERT_KEY_SIZE
)
print(f"✓ CA created successfully")
return ca_manager.get_ca(CA_NAME)
except Exception as e:
print(f"✗ Error creating CA: {e}")
sys.exit(1)
def create_certificate(cert_manager, ca_info, service_name, config):
"""Create a certificate for a service"""
print(f" Creating certificate for {service_name}...")
try:
result = cert_manager.sign_certificate(
ca_key=ca_info["key"],
ca_cert=ca_info["cert"],
ca_name=ca_info["name"],
cert_name=service_name,
cert_type="server",
common_name=config["dns"][0] if config["dns"] else service_name,
dns_names=config.get("dns", []),
ip_addresses=config.get("ip", []),
organization=CA_ORG,
country=CA_COUNTRY,
state=CA_STATE,
city=CA_CITY,
validity_days=CERT_VALIDITY_DAYS,
key_size=CERT_KEY_SIZE
)
print(f" ✓ Certificate created: {result['cert']}")
return result
except Exception as e:
print(f" ✗ Error creating certificate: {e}")
return None
def update_config_file(service_name, cert_info):
"""Update configuration file with certificate paths"""
config_file = Path(f"config/{service_name}.json")
config_file.parent.mkdir(parents=True, exist_ok=True)
config = {
"ssl_certificate": str(cert_info["cert"]),
"ssl_certificate_key": str(cert_info["key"])
}
import json
with open(config_file, "w") as f:
json.dump(config, f, indent=2)
print(f" ✓ Configuration updated: {config_file}")
def main():
"""Main function"""
print("=" * 60)
print("Automated Certificate Generation")
print("=" * 60)
# Initialize managers
ca_manager = CAManager(BASE_DIR)
cert_manager = CertManager(BASE_DIR)
# Create or get CA
ca_info = create_ca_if_needed(ca_manager)
if not ca_info:
print("✗ Failed to get CA information")
sys.exit(1)
# Generate certificates for each service
print(f"\nGenerating certificates for {len(SERVICES)} services...")
results = {}
for service_name, config in SERVICES.items():
cert_info = create_certificate(cert_manager, ca_info, service_name, config)
if cert_info:
results[service_name] = cert_info
update_config_file(service_name, cert_info)
# Summary
print("\n" + "=" * 60)
print("Summary")
print("=" * 60)
print(f"CA: {ca_info['name']}")
print(f"Certificates created: {len(results)}/{len(SERVICES)}")
if len(results) == len(SERVICES):
print("✓ All certificates created successfully!")
return 0
else:
print("✗ Some certificates failed to create")
return 1
if __name__ == "__main__":
sys.exit(main())
Using the Script¶
Save the script as generate_certs.py and make it executable:
chmod +x generate_certs.py
./generate_certs.py
Integration with CI/CD¶
GitHub Actions Example:
name: Generate Certificates
on:
workflow_dispatch:
push:
branches: [main]
jobs:
generate-certs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install Certica
run: pip install certica
- name: Generate certificates
run: python generate_certs.py
- name: Upload certificates
uses: actions/upload-artifact@v3
with:
name: certificates
path: output/
GitLab CI Example:
generate_certificates:
stage: build
image: python:3.9
before_script:
- pip install certica
script:
- python generate_certs.py
artifacts:
paths:
- output/
expire_in: 1 week
Integration with Ansible¶
Create an Ansible playbook:
- name: Generate certificates
hosts: localhost
tasks:
- name: Install Certica
pip:
name: certica
- name: Generate certificates
command: python generate_certs.py
register: cert_result
- name: Display results
debug:
var: cert_result.stdout
Error Handling¶
The script includes basic error handling, but you can enhance it:
def create_certificate_safe(cert_manager, ca_info, service_name, config, retries=3):
"""Create certificate with retry logic"""
for attempt in range(retries):
try:
return create_certificate(cert_manager, ca_info, service_name, config)
except Exception as e:
if attempt < retries - 1:
print(f" Retrying... (attempt {attempt + 1}/{retries})")
time.sleep(1)
else:
print(f" ✗ Failed after {retries} attempts: {e}")
return None
return None
Logging¶
Add logging for better debugging:
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('cert_generation.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
def create_ca_if_needed(ca_manager):
logger.info(f"Checking for CA: {CA_NAME}")
# ... rest of function
Best Practices¶
Validate inputs before generating certificates
Use configuration files instead of hardcoding values
Implement retry logic for network operations
Log all operations for audit trails
Test in development before using in production
Back up CA keys before automation runs
Monitor certificate expiration and set up alerts