This new README serves as the central documentation for the `iklim.co` Hetzner Cloud environment infrastructure repository. It outlines the project's purpose, scope, and structure, alongside detailed setup guides, security baselines, environment topologies, and usage instructions for Terraform.
8.3 KiB
🌍 Environment Infrastructure
Infrastructure-as-code and operational runbook repository for iklim.co test and production environments on Hetzner Cloud.
This repository defines:
- 🧱 Terraform resources for Hetzner infrastructure (
testandprod) - 📦 Generated Ansible inventory output targets
- 📚 End-to-end setup guides and roadmap documents (mostly Turkish)
- 📊 Sizing/cost analysis and supporting reference assets
🎯 Scope
The main goal is to standardize and document infrastructure provisioning with clear responsibility boundaries:
- 🧱 Terraform: creates cloud infrastructure (servers, private networks, firewalls, placement groups, floating IPs, SSH key registration, inventory output)
- 🤖 Ansible: prepares OS, security hardening, Docker/Swarm, runner setup, StorageBox mount workflows (described in docs; role code is not currently in this repo)
- 🚀 Application/stack deployment: handled in related deployment workflows and stack manifests referenced by roadmap docs
📌 Current Repository Status
As of now, this repository primarily contains:
- 🧱 Ready Terraform code for:
terraform/hetzner/testterraform/hetzner/prod
- 📦 A generated sample inventory file:
ansible/inventory/generated/test.yml
- 📘 Detailed setup phases:
setup/00-genel-yol-haritasi.mdthroughsetup/09-prod-runner-ha-ve-swarm.md
- 🛣️ Environment roadmap steps:
roadmap/test-env/*roadmap/prod-env/*
- 📈 Capacity planning report:
hetzner-sizing-report.md
🧭 Target Environment Topology
🧪 Test
| Node | Role | Private IP | Suggested Type |
|---|---|---|---|
iklim-app-01 |
Swarm manager + app worker + test runner | 10.10.10.11 |
cpx42 |
iklim-db-01 |
DB host (manual/stack-based DB setup path) | 10.10.20.11 |
cpx42 |
🏭 Production
| Node | Role | Private IP | Suggested Type |
|---|---|---|---|
iklim-app-01 |
Swarm manager + app worker + runner (primary FIP target) | 10.20.10.11 |
cpx42 |
iklim-app-02 |
Swarm manager + app worker + runner | 10.20.10.12 |
cpx42 |
iklim-app-03 |
Swarm manager + app worker + runner | 10.20.10.13 |
cpx42 |
iklim-db-01 |
DB cluster node | 10.20.20.11 |
cpx32 |
iklim-db-02 |
DB cluster node | 10.20.20.12 |
cpx32 |
iklim-db-03 |
DB cluster node | 10.20.20.13 |
cpx32 |
🔐 Security and Network Baseline
Core decisions reflected in Terraform and setup docs:
- Test and prod are separated into different Hetzner Cloud projects/tokens.
- Public ingress is limited to:
22/tcp(admin CIDRs only)80/tcp443/tcp
- Critical services remain private-only (for example Vault
8200, PostgreSQL5432, MongoDB27017, internal observability and broker ports). - Placement groups are used for host-spread strategy.
prevent_destroy = trueis enabled on server resources to reduce accidental deletion risk.- Terraform state and secret files must not be committed.
See:
setup/01-private-network-port-matrisi.mdterraform/hetzner/test/firewall.tfterraform/hetzner/prod/firewall.tf
🗂️ Repository Structure
Environment_Infrastructure/
├── ansible/
│ └── inventory/
│ └── generated/
│ └── test.yml
├── roadmap/
│ ├── test-env/
│ └── prod-env/
├── setup/
│ ├── 00-genel-yol-haritasi.md
│ ├── 01-private-network-port-matrisi.md
│ ├── 02-test-terraform-iaac.md
│ ├── 03-test-ansible-bootstrap.md
│ ├── 04-test-db-docker-kurulum.md
│ ├── 05-test-runner-ve-deploy-onkosullari.md
│ ├── 06-prod-terraform-iaac.md
│ ├── 07-prod-ansible-bootstrap.md
│ ├── 08-prod-db-cluster-kurulum.md
│ └── 09-prod-runner-ha-ve-swarm.md
├── terraform/
│ └── hetzner/
│ ├── test/
│ └── prod/
├── hetzner-sizing-report.md
└── setup-vs-roadmap-map.md
✅ Prerequisites
- Terraform
>= 1.6 - Hetzner Cloud account(s) and API token per environment
- SSH key pair (public key path used in Terraform variables)
- Linux/macOS shell tools (
bash,cp,sedor editor of your choice) - Optional but expected in later phases: Ansible, Docker, access to Gitea/Harbor/StorageBox
🛠️ Terraform Usage
1) 🧪 Test Infrastructure
cd terraform/hetzner/test
cp terraform.tfvars.example terraform.tfvars
Edit terraform.tfvars values:
hcloud_tokenadmin_allowed_cidrs- optional overrides (
location, image, server types, key path)
Then run:
terraform init
terraform plan
terraform apply
terraform output -raw ansible_inventory_yaml > ../../../ansible/inventory/generated/test.yml
2) 🏭 Production Infrastructure
cd terraform/hetzner/prod
cp terraform.tfvars.example terraform.tfvars
Edit terraform.tfvars values:
hcloud_token(prod token)admin_allowed_cidrs- optional overrides
Then run:
terraform init
terraform plan
terraform apply
terraform output -raw ansible_inventory_yaml > ../../../ansible/inventory/generated/prod.yml
🧱 Setup Flow (Canonical Order)
Use setup documents in this sequence:
setup/00-genel-yol-haritasi.md— global decisions and boundariessetup/01-private-network-port-matrisi.md— private/public port policysetup/02-test-terraform-iaac.md— test Terraform phasesetup/03-test-ansible-bootstrap.md— test OS/bootstrap/hardeningsetup/04-test-db-docker-kurulum.md— test DB stack setup on Swarmsetup/05-test-runner-ve-deploy-onkosullari.md— test runner and deploy prerequisitessetup/06-prod-terraform-iaac.md— prod Terraform phasesetup/07-prod-ansible-bootstrap.md— prod OS/bootstrap/hardeningsetup/08-prod-db-cluster-kurulum.md— prod DB cluster stack (MongoDB + Patroni/etcd)setup/09-prod-runner-ha-ve-swarm.md— prod runner HA and deploy lock model
🛣️ Roadmap Documents
The roadmap folders track integration work for Swarm stacks, SWAG, APISIX, pipeline updates, and verification checklists:
roadmap/test-env/*roadmap/prod-env/*
These documents often reference files from related repositories (for example application root repo workflows and stack files). Treat them as implementation guidance aligned with this infrastructure baseline.
💰 Sizing and Cost Snapshot
Reference: hetzner-sizing-report.md
Suggested baseline:
- Test:
2 x cpx42(app + db) - Prod:
3 x cpx42(app) +3 x cpx32(db)
Approximate monthly total in the report:
- Test:
$59.98 - Prod:
$139.44 - Combined:
$199.42
🔑 Secrets and State Management
Never commit:
terraform.tfvars,*.tfvars,*.tfstate,.terraform/- private keys, certificates,
.envsecrets - runner tokens and vault password files
See .gitignore for enforced patterns.
Recommended:
- keep runtime secrets in secure secret stores / encrypted vault files
- keep generated runtime artifacts outside version control unless explicitly sanitized
⚠️ Known Gaps / Notes
- Ansible role/playbook source code is described by docs but is not currently present in this repository.
ansible/inventory/generated/prod.ymlis expected output path but may not exist until generated.- Some roadmap steps target files under the broader
iklim.coapplication repository, not this repository alone.
✅ Quick Validation Checklist
After Terraform apply:
- servers are created with expected names and private IPs
- floating IP exists and is attached
- firewalls expose only intended public ports
- placement groups are assigned
- generated inventory YAML is exported to
ansible/inventory/generated/*.yml
After bootstrap/deploy phases:
- Swarm state and labels match documentation
- DB accessibility is private-only
- Vault/API gateways follow public/private exposure rules
- runner and deploy lock behavior align with environment policy
🔗 References
- Hetzner Terraform Provider: https://registry.terraform.io/providers/hetznercloud/hcloud/latest
- Hetzner Networks: https://docs.hetzner.com/cloud/networks/overview/
- Hetzner Firewalls: https://docs.hetzner.com/cloud/firewalls/overview
- Hetzner Placement Groups: https://docs.hetzner.com/cloud/placement-groups/overview
- Docker Swarm overlay networking: https://docs.docker.com/engine/network/drivers/overlay/
- Gitea act_runner: https://docs.gitea.com/usage/actions/act-runner