# ๐ŸŒ 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 (`test` and `prod`) - ๐Ÿค– Ansible bootstrap playbooks, shared roles, and inventory 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, and StorageBox mount workflows via in-repo playbooks and shared roles - ๐Ÿš€ **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/test` - `terraform/hetzner/prod` - ๐Ÿค– Ansible automation assets for both environments: - `ansible/test/test-bootstrap.yml` - `ansible/prod/prod-bootstrap.yml` - `ansible/roles/*` - `ansible/test/group_vars/*` and `ansible/prod/group_vars/*` - ๐Ÿ“ฆ Inventory artifacts and output targets: - `ansible/test/inventory/generated/test.yml` (tracked sample) - `ansible/prod/inventory/generated/prod.yml` (expected output path) - ๐Ÿ“˜ Detailed setup phases: - `setup/00-genel-yol-haritasi.md` through `setup/09-prod-runner-ha-ve-swarm.md` - ๐Ÿ›ฃ๏ธ Environment roadmap steps: - `roadmap/test-env/*` - `roadmap/prod-env/*` - ๐Ÿ“ˆ Capacity planning and reference charts: - `hetzner-sizing-report.md` - `test-app-graphs.png` - `test-db-graphs.png` ## ๐Ÿงญ 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/tcp` - `443/tcp` - Critical services remain private-only (for example Vault `8200`, PostgreSQL `5432`, MongoDB `27017`, internal observability and broker ports). - Placement groups are used for host-spread strategy. - `prevent_destroy = true` is 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.md` - `terraform/hetzner/test/firewall.tf` - `terraform/hetzner/prod/firewall.tf` ## ๐Ÿ—‚๏ธ Repository Structure ```text Environment_Infrastructure/ โ”œโ”€โ”€ ansible/ โ”‚ โ”œโ”€โ”€ prod/ โ”‚ โ”‚ โ”œโ”€โ”€ ansible.cfg โ”‚ โ”‚ โ”œโ”€โ”€ group_vars/ โ”‚ โ”‚ โ””โ”€โ”€ prod-bootstrap.yml โ”‚ โ”œโ”€โ”€ roles/ โ”‚ โ”‚ โ”œโ”€โ”€ base/ โ”‚ โ”‚ โ”œโ”€โ”€ docker/ โ”‚ โ”‚ โ”œโ”€โ”€ hardening/ โ”‚ โ”‚ โ”œโ”€โ”€ node_dirs/ โ”‚ โ”‚ โ”œโ”€โ”€ storagebox/ โ”‚ โ”‚ โ”œโ”€โ”€ storagebox_ssh_key/ โ”‚ โ”‚ โ””โ”€โ”€ swarm/ โ”‚ โ”œโ”€โ”€ test/ โ”‚ โ”‚ โ”œโ”€โ”€ ansible.cfg โ”‚ โ”‚ โ”œโ”€โ”€ group_vars/ โ”‚ โ”‚ โ”œโ”€โ”€ inventory/ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ generated/ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ test.yml โ”‚ โ”‚ โ””โ”€โ”€ test-bootstrap.yml โ”‚ โ””โ”€โ”€ requirements.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 โ”œโ”€โ”€ test-app-graphs.png โ””โ”€โ”€ test-db-graphs.png ``` ## โœ… 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`, `sed` or editor of your choice) - Optional but expected in later phases: Ansible, Docker, access to Gitea/Harbor/StorageBox ## ๐Ÿ› ๏ธ Terraform Usage ### 1) ๐Ÿงช Test Infrastructure ```bash cd terraform/hetzner/test cp terraform.tfvars.example terraform.tfvars ``` Edit `terraform.tfvars` values: - `hcloud_token` - `admin_allowed_cidrs` - optional overrides (`location`, image, server types, key path) Then run: ```bash terraform init terraform plan terraform apply mkdir -p ../../../ansible/test/inventory/generated terraform output -raw ansible_inventory_yaml > ../../../ansible/test/inventory/generated/test.yml ``` ### 2) ๐Ÿญ Production Infrastructure ```bash 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: ```bash terraform init terraform plan terraform apply mkdir -p ../../../ansible/prod/inventory/generated terraform output -raw ansible_inventory_yaml > ../../../ansible/prod/inventory/generated/prod.yml ``` ## ๐Ÿงฑ Setup Flow (Canonical Order) Use setup documents in this sequence: 1. `setup/00-genel-yol-haritasi.md` โ€” global decisions and boundaries 2. `setup/01-private-network-port-matrisi.md` โ€” private/public port policy 3. `setup/02-test-terraform-iaac.md` โ€” test Terraform phase 4. `setup/03-test-ansible-bootstrap.md` โ€” test OS/bootstrap/hardening 5. `setup/04-test-db-docker-kurulum.md` โ€” test DB stack setup on Swarm 6. `setup/05-test-runner-ve-deploy-onkosullari.md` โ€” test runner and deploy prerequisites 7. `setup/06-prod-terraform-iaac.md` โ€” prod Terraform phase 8. `setup/07-prod-ansible-bootstrap.md` โ€” prod OS/bootstrap/hardening 9. `setup/08-prod-db-cluster-kurulum.md` โ€” prod DB cluster stack (MongoDB + Patroni/etcd) 10. `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, `.env` secrets - 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/prod/inventory/generated/prod.yml` is an expected output path but may not exist until generated. - Some roadmap steps target files under the broader `iklim.co` application 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/{test,prod}/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