Skip to main content
The platform layer deploys essential Kubernetes infrastructure components that applications will depend on. This includes certificate management, secrets synchronization, load balancing, and HashiCorp Vault.

What Gets Deployed

This layer installs:
  • AWS Load Balancer Controller: Manages Application Load Balancers for Kubernetes ingress
  • Cert Manager: Automated TLS certificate provisioning and renewal
  • External Secrets Operator: Syncs secrets from Vault to Kubernetes
  • Vault: HashiCorp Vault deployed via Helm for secrets management

Environment Variables

No additional environment variables are required for deployment. However, after deployment, you’ll need to configure Vault credentials.

Deployment Steps

1

Navigate to platform directory

cd terraform/dev/2-platform
2

Initialize Terraform

terraform init
This initializes the remote backend and downloads provider plugins.
3

Review the plan

terraform plan
Review the resources that will be created:
  • IAM roles and policies for AWS Load Balancer Controller
  • Helm releases for cert-manager, external-secrets, and Vault
  • Kubernetes service accounts and RBAC configurations
4

Apply the configuration

terraform apply
Type yes when prompted. This process takes approximately 5-10 minutes.

Vault Initialization

After the platform layer is deployed, you must initialize and unseal Vault.
Vault initialization is a critical one-time operation. The root token and recovery keys must be stored securely.

Wait for Vault Pods

First, ensure Vault pods are running:
kubectl get pods -n vault -w
Wait until you see pods in Running state (they may show 0/1 ready, which is expected before initialization).

Run Bootstrap Script

1

Navigate to scripts directory

cd scripts
2

Execute bootstrap script

./vault-bootstrap.sh
This script:
  • Initializes Vault with auto-unseal using AWS KMS
  • Generates recovery keys and root token
  • Saves credentials to ~/.vault-secrets/vault.env
  • Configures Vault for Kubernetes authentication
3

Save credentials securely

The script outputs:
  • Root Token: Required for admin operations
  • Recovery Keys: Needed for disaster recovery
Store these credentials in a secure password manager immediately. Loss of these credentials may result in permanent data loss.
4

Source Vault environment

source ~/.vault-secrets/vault.env
This sets:
  • VAULT_ADDR: Vault server URL
  • VAULT_TOKEN: Root token for authentication

Verify Vault Status

# Check Vault status
kubectl exec -n vault vault-0 -- vault status

# Should show:
# Sealed: false
# Initialized: true

Platform Components

AWS Load Balancer Controller

The AWS Load Balancer Controller provisions Application Load Balancers when you create Kubernetes Ingress resources. Features:
  • Automatic ALB creation from Ingress manifests
  • Target group management
  • SSL/TLS termination
  • Path-based and host-based routing
Configuration:
  • Deployed in kube-system namespace
  • Uses IAM Roles for Service Accounts (IRSA)
  • Monitors Ingress resources with alb.ingress.kubernetes.io annotations

Cert Manager

Cert Manager automates TLS certificate issuance and renewal from Let’s Encrypt. Features:
  • Automated certificate provisioning
  • Automatic renewal before expiration
  • ACME DNS-01 challenge support via Cloudflare
Configuration:
  • Deployed in cert-manager namespace
  • ClusterIssuers for Let’s Encrypt staging and production
  • Cloudflare DNS integration for wildcard certificates

External Secrets Operator

External Secrets Operator syncs secrets from Vault to Kubernetes Secrets. Features:
  • Automatic secret synchronization
  • Refresh on secret changes
  • Multiple secret backend support
Configuration:
  • Deployed in external-secrets namespace
  • SecretStore resources configured for Vault
  • Kubernetes auth method for Vault authentication

Vault

HashiCorp Vault provides centralized secrets management. Features:
  • KV secrets engine for key-value storage
  • Dynamic secrets generation
  • Encryption as a service
  • Audit logging
Configuration:
  • Deployed in vault namespace via Helm
  • High availability with DynamoDB backend
  • Auto-unseal using AWS KMS
  • Ingress for HTTPS access via Tailscale

Accessing Vault

Via kubectl Port Forward

For local access without ingress:
kubectl port-forward -n vault svc/vault 8200:8200
Then access at http://localhost:8200. Once connected to Tailscale, access Vault directly:
export VAULT_ADDR="https://vault.yourdomain.com"
vault status

Verification

Check All Pods

# AWS Load Balancer Controller
kubectl get pods -n kube-system | grep aws-load-balancer

# Cert Manager
kubectl get pods -n cert-manager

# External Secrets
kubectl get pods -n external-secrets

# Vault
kubectl get pods -n vault
All pods should be in Running state.

Verify Cert Manager Issuers

kubectl get clusterissuers
You should see:
  • letsencrypt-staging
  • letsencrypt-prod

Test Vault Access

# Port forward to Vault
kubectl port-forward -n vault svc/vault 8200:8200 &

# Set Vault address
export VAULT_ADDR="http://localhost:8200"

# Check status
vault status

# List secrets engines
vault secrets list

Outputs

The platform layer exports the following outputs:
OutputDescription
vault_addrVault server URL
vault_namespaceKubernetes namespace where Vault is deployed
cert_manager_readyBoolean indicating cert-manager is deployed

Troubleshooting

Vault Pods Not Starting

Check pod events:
kubectl describe pod -n vault vault-0
Common issues:
  • KMS key permissions not granted to node role
  • DynamoDB table not accessible
  • Insufficient resources on nodes

AWS Load Balancer Controller Errors

Check controller logs:
kubectl logs -n kube-system deployment/aws-load-balancer-controller
Common issues:
  • IAM permissions insufficient
  • Subnets not properly tagged for auto-discovery
  • Security group rules blocking traffic

Cert Manager Certificate Issues

Check certificate status:
kubectl get certificates -A
kubectl describe certificate <cert-name> -n <namespace>
Common issues:
  • Cloudflare API token permissions insufficient
  • DNS propagation delays
  • Rate limiting from Let’s Encrypt

Next Steps

With the platform layer deployed and Vault initialized, you’re ready to deploy applications.

Apps Layer

Deploy ArgoCD, Traefik, and application services

Build docs developers (and LLMs) love