08a. Infrastructure Templates
Prerequisites: Familiarity with OpenTofu, Kubernetes, and cloud infrastructure concepts
This section provides production-ready Infrastructure as Code templates for deploying sovereign cloud infrastructure across EU, UK, Canadian, and Australian jurisdictions.
Repository Structure
- 📁 sovereign-cloud-iac/
- 📁 opentofu/
- 📁 modules/
- 📁 compute/
- 📁 networking/
- 📁 storage/
- 📁 security/
- 📁 monitoring/
- 📁 environments/
- 📁 eu-production/
- 📁 uk-production/
- 📁 ca-production/
- 📁 au-production/
- 📁 modules/
- 📁 kubernetes/
- 📁 base/
- 📁 overlays/
- 📁 helm-charts/
- 📁 ansible/
- 📁 playbooks/
- 📁 roles/
- 📁 opentofu/
Template Categories
Compute Foundation
Kubernetes cluster provisioning with sovereign control plane requirements.
- Multi-master HA configuration
- Node pools with jurisdiction labels
- GPU nodes for AI workloads
- Spot/preemptible cost optimization
Providers: OVHcloud, Hetzner, IONOS, AARNet
Network Architecture
VPC/VNet configuration with sovereign routing requirements.
- Multi-region mesh networking
- Private peering between jurisdictions
- Egress controls and DLP
- Zero-trust network policies
Note: No traffic routed through US territory
Storage Layer
S3-compatible object storage with encryption at rest.
- MinIO cluster deployment
- Cross-region replication
- Immutable backup buckets
- Lifecycle policies
Encryption: AES-256, jurisdiction-specific keys
Security Baseline
OpenBao deployment with HSM integration.
- Auto-unseal with sovereign HSM
- PKI secrets engine
- Database credentials rotation
- Kubernetes auth method
Compliance: FIPS 140-2 Level 3
Identity & Access
Keycloak deployment for federated identity management.
- SAML 2.0 / OIDC support
- Multi-factor authentication
- Government ID federation
- Role-based access control
Integration: GOV.UK Verify, EU eIDAS
Observability Stack
Prometheus, Grafana, and Loki deployment.
- High-availability Prometheus
- Long-term metrics storage (Thanos)
- Centralized logging
- Alertmanager with PagerDuty
Retention: 7 years audit log compliance
OpenTofu Module: Kubernetes Cluster
Module Interface
# modules/compute/kubernetes/variables.tf
variable "cluster_name" {
description = "Name of the Kubernetes cluster"
type = string
}
variable "jurisdiction" {
description = "Deployment jurisdiction (eu, uk, ca, au)"
type = string
validation {
condition = contains(["eu", "uk", "ca", "au"], var.jurisdiction)
error_message = "Jurisdiction must be one of: eu, uk, ca, au"
}
}
variable "kubernetes_version" {
description = "Kubernetes version to deploy"
type = string
default = "1.29"
}
variable "control_plane_nodes" {
description = "Number of control plane nodes (must be odd)"
type = number
default = 3
validation {
condition = var.control_plane_nodes % 2 == 1
error_message = "Control plane nodes must be an odd number for quorum"
}
}
variable "worker_pools" {
description = "Worker node pool configurations"
type = list(object({
name = string
instance_type = string
min_size = number
max_size = number
labels = map(string)
taints = list(object({
key = string
value = string
effect = string
}))
}))
}
variable "network_config" {
description = "Network configuration"
type = object({
vpc_cidr = string
pod_cidr = string
service_cidr = string
enable_ipv6 = bool
})
}
variable "enable_sovereign_controls" {
description = "Enable sovereign data controls (encryption, egress filtering)"
type = bool
default = true
}
Example Usage
# environments/uk-production/main.tf
module "uk_sovereign_cluster" {
source = "../../modules/compute/kubernetes"
cluster_name = "uk-prod-sovereign-01"
jurisdiction = "uk"
kubernetes_version = "1.29"
control_plane_nodes = 3
worker_pools = [
{
name = "general"
instance_type = "cx41" # Hetzner instance type
min_size = 3
max_size = 20
labels = {
"workload-type" = "general"
"jurisdiction" = "uk"
}
taints = []
},
{
name = "high-memory"
instance_type = "cx51"
min_size = 2
max_size = 10
labels = {
"workload-type" = "database"
"jurisdiction" = "uk"
}
taints = [{
key = "dedicated"
value = "database"
effect = "NoSchedule"
}]
}
]
network_config = {
vpc_cidr = "10.100.0.0/16"
pod_cidr = "10.200.0.0/14"
service_cidr = "10.204.0.0/16"
enable_ipv6 = true
}
enable_sovereign_controls = true
}
output "kubeconfig" {
value = module.uk_sovereign_cluster.kubeconfig
sensitive = true
}
output "api_endpoint" {
value = module.uk_sovereign_cluster.api_endpoint
}
Provider-Specific Configurations
| Provider | Jurisdiction | OpenTofu Provider | Key Considerations |
|---|---|---|---|
| OVHcloud | EU, UK, CA, AU | ovh/ovh |
Public Cloud API, Managed Kubernetes available |
| Hetzner | EU (Germany, Finland) | hetznercloud/hcloud |
Cost-effective, bare metal available, no managed K8s |
| Scaleway | EU (France, Netherlands) | scaleway/scaleway |
SecNumCloud qualified, managed Kubernetes |
| IONOS | EU (Germany, Spain, UK) | ionos-cloud/ionoscloud |
German sovereignty, managed Kubernetes |
| AARNet/NeCTAR | AU | opentofu-provider-openstack |
OpenStack-based, academic/government focus |
| Exoscale | EU (Switzerland) | exoscale/exoscale |
Swiss data protection, SKS Kubernetes |
Deployment Pipeline
GitOps Workflow
# .github/workflows/opentofu-deploy.yml
name: OpenTofu Sovereign Cloud Deploy
on:
push:
branches: [main]
paths:
- 'opentofu/**'
pull_request:
branches: [main]
paths:
- 'opentofu/**'
env:
TF_VERSION: "1.7.0"
jobs:
plan:
runs-on: self-hosted # Sovereign runner, not GitHub-hosted
strategy:
matrix:
jurisdiction: [eu, uk, ca, au]
steps:
- uses: actions/checkout@v4
- name: Setup OpenTofu
uses: opentofu/setup-opentofu@v3
with:
opentofu_version: ${{ env.TF_VERSION }}
- name: OpenTofu Init
working-directory: opentofu/environments/${{ matrix.jurisdiction }}-production
run: opentofu init -backend-config=backend-${{ matrix.jurisdiction }}.hcl
- name: OpenTofu Plan
working-directory: opentofu/environments/${{ matrix.jurisdiction }}-production
run: opentofu plan -out=tfplan-${{ matrix.jurisdiction }}
env:
TF_VAR_jurisdiction: ${{ matrix.jurisdiction }}
- name: Upload Plan
uses: actions/upload-artifact@v4
with:
name: tfplan-${{ matrix.jurisdiction }}
path: opentofu/environments/${{ matrix.jurisdiction }}-production/tfplan-${{ matrix.jurisdiction }}
apply:
needs: plan
runs-on: self-hosted
if: github.ref == 'refs/heads/main'
environment: production
strategy:
matrix:
jurisdiction: [eu, uk, ca, au]
steps:
- uses: actions/checkout@v4
- name: Download Plan
uses: actions/download-artifact@v4
with:
name: tfplan-${{ matrix.jurisdiction }}
path: opentofu/environments/${{ matrix.jurisdiction }}-production
- name: OpenTofu Apply
working-directory: opentofu/environments/${{ matrix.jurisdiction }}-production
run: opentofu apply -auto-approve tfplan-${{ matrix.jurisdiction }}
State Management
Sovereign State Backend Configuration
# backend-uk.hcl
bucket = "uk-sovereign-tfstate"
key = "uk-production/opentofu.tfstate"
region = "uk-london-1"
encrypt = true
dynamodb_table = "uk-sovereign-tfstate-locks"
# Using MinIO S3-compatible storage on sovereign infrastructure
endpoint = "https://s3.sovereign.gov.uk"
skip_credentials_validation = true
skip_metadata_api_check = true
force_path_style = true
Related Documentation
- Security Hardening Guidelines - Compliance requirements for templates
- Workload Migration Patterns - Using templates for migrations
- Provider Evaluation Criteria - Provider selection guidance