Dev-Cluster GitOps Provisioning
Provisioning, configuration and manifests for my Kubernetes dev cluster on Hetzner Cloud, set up for GitOps with Flux CD.
Prerequisites
- OpenTofu
- SOPS
- Age
- A Hetzner Cloud account and API token
- Cloudflare DNS API token
- A GitHub account and personal access token (for Flux)
- S3 compatible storage credentials
Deployment
-
Generate an Age key:
age-keygen -o key.txt -
Edit
.sops.yamlfile in your project root:creation_rules: - unencrypted_regex: "^(apiVersion|metadata|kind|type)$" age: <your-age-public-key>Replace
<your-age-public-key>with the public key from yourkey.txtfile. -
Create a
secrets.yamlfile with your sensitive data:username: <your-username> user_hashed_password: <your-hashed-password> user_ssh_public_key: <your-ssh-public-key> github_username: <your-github-username> github_repo: <your-flux-repo-name> github_token: <your-github-token> -
Encrypt the secrets file:
sops -e secrets.yaml > secrets.enc.yaml -
Create a
terraform.tfvarsfile for your Hetzner Cloud token and Cloudflare Token:hcloud_token = "your-hetzner-cloud-token" cloudflare_api_token = "your-cloudflare-token -
Create
s3_env.yamlfile with your S3 compatible storage credentialsAWS_ENDPOINT_URL_S3AWS_ACCESS_KEY_IDAWS_REGIONAWS_SECRET_ACCESS_KEY -
Encrypt the
s3_env.yamlfile:sops -e s3_env.yaml > s3_env.enc.yaml -
Run OpenTofu:
sops exec-env s3_env.enc.yaml 'tofu init' sops exec-env s3_env.enc.yaml 'tofu apply'
Post Deployment
-
Connect to the server
Replace username with your username and public ip with the output value of
tofu applyssh ${username}@${public_ip} -
Create sops secret
Use the key generated in step 1. of the deployment
kubectl create ns flux-system cat age.key | kubectl create secret generic sops-age \ --namespace=flux-system \ --from-file=age.key=/dev/stdin -
Bootstrap flux
export GITHUB_TOKEN=${github_token} && flux bootstrap github --owner=${github_username} --repository=${github_repo} --path=clusters/prod --personal