Files
homelab/k8s/hooks/phase4/terraform-apply-hook.yaml
T
Story Crater Bot b568c015e2 feat(phase4): ArgoCD-driven Terraform with PVC imports
Phase 4 implementation (true IaC):
- ArgoCD Application: terraform-apply (PostSync Hook Job)
- Hook Job runs: terraform init && terraform apply -auto-approve
- ServiceAccount + ClusterRole for cluster-admin
- SOPS-encrypted S3 credentials (terraform-s3-secrets.enc.yaml)
- Pre-commit hook blocks local 'terraform apply'
- In-cluster kubeconfig for Kubernetes provider
- AWS credentials file with minio profile

State imports:
- Imported kubernetes_persistent_volume_claim.portainer (dashboard/portainer)
- Imported kubernetes_persistent_volume_claim.grafana (logging/grafana)
- Imported kubernetes_persistent_volume_claim.loki (logging/storage-loki-0)

Workflow:
1. Edit terraform/*.tf files
2. git push to main
3. ArgoCD detects changes in k8s/hooks/phase4
4. Hook Job automatically runs terraform apply
5. No manual 'terraform apply' needed ever again
2026-07-15 17:48:18 -07:00

119 lines
3.5 KiB
YAML

apiVersion: batch/v1
kind: Job
metadata:
name: terraform-apply
namespace: argocd
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
backoffLimit: 3
template:
spec:
serviceAccountName: terraform-apply
containers:
- name: terraform
image: hashicorp/terraform:latest
command: ["/bin/sh", "-c"]
args:
- |
set -e
echo "=== Terraform Apply Hook (ArgoCD PostSync) ==="
# Trust homelab CA for self-signed Forgejo certificate
cp /etc/ssl/certs/homelab-ca.crt /usr/local/share/ca-certificates/homelab-ca.crt
update-ca-certificates
# Clone repo
git clone --depth 1 https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git /repo
cd /repo/terraform
# Load S3 credentials from mounted secrets
export AWS_ACCESS_KEY_ID=$(cat /run/secrets/s3/AWS_ACCESS_KEY_ID)
export AWS_SECRET_ACCESS_KEY=$(cat /run/secrets/s3/AWS_SECRET_ACCESS_KEY)
export AWS_ENDPOINT_URL=$(cat /run/secrets/s3/AWS_ENDPOINT_URL)
# Create AWS credentials file with minio profile
mkdir -p ~/.aws
cat > ~/.aws/credentials << EOF
[minio]
aws_access_key_id = $(cat /run/secrets/s3/AWS_ACCESS_KEY_ID)
aws_secret_access_key = $(cat /run/secrets/s3/AWS_SECRET_ACCESS_KEY)
EOF
cat > ~/.aws/config << EOF
[default]
region = us-east-1
EOF
# Generate in-cluster kubeconfig for Terraform provider
mkdir -p /root/.kube
cat > /root/.kube/config << KUBEEOF
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
server: https://kubernetes.default:443
name: in-cluster
contexts:
- context:
cluster: in-cluster
user: terraform
name: in-cluster
current-context: in-cluster
users:
- name: terraform
user:
tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
KUBEEOF
export KUBECONFIG=/root/.kube/config
# Initialize and apply
echo "Initializing Terraform..."
terraform init
echo "Planning Terraform changes..."
terraform plan \
-var "kubeconfig_path=/root/.kube/config" \
-out=tfplan
echo "Applying Terraform..."
terraform apply -auto-approve tfplan
echo "✓ Terraform apply complete"
volumeMounts:
- name: s3-creds
mountPath: /run/secrets/s3
readOnly: true
- name: homelab-ca
mountPath: /etc/ssl/certs/homelab-ca.crt
subPath: tls.crt
readOnly: true
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1"
volumes:
- name: s3-creds
projected:
sources:
- secret:
name: terraform-s3-creds
items:
- key: AWS_ACCESS_KEY_ID
path: AWS_ACCESS_KEY_ID
- key: AWS_SECRET_ACCESS_KEY
path: AWS_SECRET_ACCESS_KEY
- key: AWS_ENDPOINT_URL
path: AWS_ENDPOINT_URL
- name: homelab-ca
secret:
secretName: homelab-ca-secret
restartPolicy: Never