Skip to content

Commit 7c7e67d

Browse files
authored
Merge pull request #40 from stackitcloud/31-enhance-docs-architecture
feat: add architecture documentation
2 parents 6f958e3 + 47ac27d commit 7c7e67d

70 files changed

Lines changed: 344 additions & 42 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/generate-architecture-diagrams.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ on:
66
paths:
77
- "src/**"
88
- "modules/**"
9-
- "assets/**"
10-
- "docs/scripts/generate_example_architecture.py"
11-
- "docs/diagram-generation.md"
9+
- "docs/diagrams/assets/**"
10+
- "docs/diagrams/scripts/generate_example_architecture.py"
11+
- "docs/diagrams/README.md"
1212
push:
1313
branches:
1414
- main
1515
paths:
1616
- "src/**"
1717
- "modules/**"
18-
- "assets/**"
19-
- "docs/scripts/generate_example_architecture.py"
20-
- "docs/diagram-generation.md"
18+
- "docs/diagrams/assets/**"
19+
- "docs/diagrams/scripts/generate_example_architecture.py"
20+
- "docs/diagrams/README.md"
2121

2222
permissions:
2323
contents: write
@@ -44,7 +44,7 @@ jobs:
4444
run: npm install -g @mermaid-js/mermaid-cli
4545

4646
- name: Generate architecture diagrams
47-
run: python3 docs/scripts/generate_example_architecture.py --out-dir docs/diagrams
47+
run: python3 docs/diagrams/scripts/generate_example_architecture.py --out-dir docs/diagrams
4848

4949
- name: Render Mermaid SVG diagrams
5050
run: |

.github/workflows/tflint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,4 @@ jobs:
3838

3939
# runs 6h
4040
# - name: Validate STACKIT flavors (live)
41-
# run: python3 docs/scripts/validate_stackit_flavors.py
41+
# run: python3 docs/diagrams/scripts/validate_stackit_flavors.py

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ openai.token
4444
.env
4545
.env.local
4646
.cache/
47+
.agents
48+
.claude
4749

4850
# Local persistent E2E runtime variables (canonical for this troubleshooting phase)
4951
src/config/e2e.tfvars
50-
src/config/e2e-bootstrap.override.tfvars
52+
src/config/e2e-bootstrap.override.tfvars

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
* @dweezl @mahauber @simpe00
1+
* @lweberru @mahauber @simpe00
22
docs/* @lweberru

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# Landing Zone Accelerator
99

1010
[![Terraform](https://img.shields.io/badge/Terraform-1.15+-623CE4?logo=terraform&logoColor=white)](https://www.terraform.io/)
11-
[![OpenTofu](https://img.shields.io/badge/OpenTofu-1.11+-FFDA18?logo=opentofu&logoColor=black)](https://opentofu.org/)
11+
[![OpenTofu](https://img.shields.io/badge/OpenTofu-1.12+-FFDA18?logo=opentofu&logoColor=black)](https://opentofu.org/)
1212
[![STACKIT](https://img.shields.io/badge/STACKIT-Cloud-004E5A)](https://www.stackit.de/)
1313
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
1414

@@ -17,6 +17,7 @@ The STACKIT Landing Zone Accelerator provides a comprehensive Terraform-based fr
1717
## 📚 Documentation
1818

1919
- [Getting Started](docs/getting-started.md)
20+
- [Architecture/Modules](docs/architecture.md)
2021

2122
## 🤝 Contributing
2223

docs/architecture.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Architecture
2+
3+
This repository is a production-ready OpenTofu/Terraform framework for deploying a STACKIT Landing Zone. It provisions the complete cloud foundation, covering governance hierarchy, identity and access management, shared networking, optional firewall, DNS, secrets management, observability, and repeatable per-workload project templates.
4+
5+
Everything is composed from six modules under `src/modules/` and wired together in `src/main.tf`. A single `terraform apply` with one of the three reference configs in `src/config/` stands up the full platform.
6+
7+
## Two-Layer Model
8+
9+
```
10+
Organization
11+
├── Platform Landing Zone ← managed by platform team, provisioned once
12+
│ ├── Management project (automation, state, secrets, observability)
13+
│ ├── Connectivity project (network hub, firewall, DNS)
14+
│ └── DevOps project (optional managed Git)
15+
└── Application Landing Zones ← one per workload/environment
16+
├── Corporate LZ (attached to shared network, routed via firewall)
17+
└── Public LZ (standalone network, internet-facing)
18+
```
19+
20+
**Platform Landing Zone** is the company-wide foundation. It is deployed once and owned by the platform team. It establishes the governance structure, shared network infrastructure, and automation tooling that all workloads build on.
21+
22+
**Application Landing Zone** is instantiated once per workload and environment (e.g. `data-prod`, `api-staging`). Each instance is an isolated STACKIT project with pre-wired networking, RBAC, secrets, and storage: ready for a team to deploy into without any platform decisions left to make.
23+
24+
## Modules
25+
26+
All modules live under `src/modules/`. The root `src/main.tf` calls them in dependency order.
27+
28+
| Module | Folder in repo | What it builds |
29+
|---|---|---|
30+
| `governance` | `src/modules/governance/` | Resource manager folder hierarchy, org-level RBAC, custom roles |
31+
| `management` | `src/modules/management/` | Automation project: service account, Terraform state bucket, Secrets Manager, Observability |
32+
| `connectivity` | `src/modules/connectivity/` | Network hub: Network Area, WAN routing table, optional firewall VM, DNS zones |
33+
| `devops` | `src/modules/devops/` | Optional DevOps project with managed Git instance |
34+
| `landing-zone` | `src/modules/landing-zone/` | Per-workload project: network, RBAC, Secrets Manager, object storage, DNS child zone, routing |
35+
| `sandboxes` | `src/modules/sandboxes/` | Lightweight sandbox projects for experimentation |
36+
37+
### Governance
38+
39+
Builds the resource manager folder hierarchy under the root organization. Default folders:
40+
41+
- **Platform**: parent for all platform projects (management, connectivity, devops)
42+
- **Landing Zones - Corporate**: parent for network-connected workload projects
43+
- **Landing Zones - Public**: parent for internet-facing workload projects
44+
- **Sandboxes**: parent for ephemeral sandbox projects
45+
46+
Also manages organization-level role assignments for owners (`organization_owners`) and read-only auditors (`organization_auditors`).
47+
48+
Source: `src/modules/governance/`
49+
50+
### Management
51+
52+
Provisions the central automation project (`<company_code>-pltfm-mgmt-prod`). Contains:
53+
54+
- **Service account**: used by CI/CD pipelines to run Terraform. Supports OIDC federation (e.g. GitHub Actions) so pipelines authenticate without long-lived keys.
55+
- **Object storage buckets**: one for Terraform remote state, one for general platform use.
56+
- **Secrets Manager instance**: stores platform secrets such as service account keys and credentials.
57+
- **Observability instance** (optional): centralized logs, metrics, and traces with configurable retention. Enabled via the `observability` variable.
58+
59+
Source: `src/modules/management/`
60+
61+
### Connectivity
62+
63+
Builds the network hub project (`<company_code>-pltfm-hub-prod`) that all corporate landing zones attach to. This is the most complex module.
64+
65+
#### Network Area
66+
67+
A STACKIT Network Area defines a shared private IP address space at the organization level. All corporate landing zone networks are created inside this area and can reach each other over private IPs without any additional peering.
68+
69+
Configuration drives the area's address plan:
70+
71+
```hcl
72+
network_area = {
73+
ranges = ["10.0.0.0/16"] # total address space
74+
transfer_network = "10.255.0.0/24" # internal STACKIT routing fabric
75+
min_prefix_length = 24 # smallest subnet a landing zone may request
76+
max_prefix_length = 28 # largest subnet a landing zone may request
77+
default_prefix_length = 25 # default if landing zone doesn't specify
78+
}
79+
```
80+
81+
#### WAN Routing Table
82+
83+
A routing table named `wan` is created with a single default route:
84+
85+
```
86+
0.0.0.0/0 → internet
87+
```
88+
89+
This is the route for outgoing traffic used by the firewall´s wan network. Traffic exits directly to the internet via STACKIT's default gateway.
90+
91+
#### DNS Zones
92+
93+
One or more DNS zones are created in the connectivity project and serve as the authoritative zones for the platform. Child zones are delegated to individual landing zones automatically. Subdomains are not allowed with domains provided by STACKIT like .stackit.run.
94+
95+
Example: if the hub zone is `example-corp.stackit.run.`, a landing zone for the `data` workload in `prod` in region `eu01` gets a delegated child zone `data-prod-eu01-example-corp.stackit.run.`.
96+
97+
#### Firewall VM (optional)
98+
99+
When `connectivity.firewall` is set, a VM running OPNsense (provided as a `.qcow2` image) is deployed with two network interfaces:
100+
101+
| Interface | STACKIT network | Purpose |
102+
|---|---|---|
103+
| `vtnet0` (WAN) | `wan_network`: attached to the WAN routing table | Outbound internet egress, assigned a static public IP |
104+
| `vtnet1` (LAN) | `lan_network`: a dedicated private subnet | Internal next-hop for all corporate landing zone traffic |
105+
106+
The firewall's LAN IP is exported as `firewall_next_hop_ip` and passed to every corporate landing zone so they can point their default route at it.
107+
108+
Source: `src/modules/connectivity/`
109+
110+
### Landing Zone
111+
112+
Instantiated once per workload/environment via `for_each` over the `landing_zones` variable. Each instance creates a fully isolated STACKIT project containing:
113+
114+
- **STACKIT project**: placed under the corporate or public folder depending on the `corporate` flag.
115+
- **Network**: corporate landing zones get a routed network attached to the shared Network Area; public landing zones get a standalone network.
116+
- **Routing table** (corporate + firewall only): a per-project routing table with a single default route pointing to the firewall LAN IP:
117+
```
118+
0.0.0.0/0 → <firewall_lan_ip>
119+
```
120+
Without a firewall, corporate landing zones use east-west routing through the Network Area but egress directly to the internet via the WAN routing table.
121+
- **RBAC**: role assignments for the application team, defined per landing zone in the `role_assignments` list.
122+
- **Secrets Manager**: isolated instance for workload secrets.
123+
- **Object storage buckets**: one for application data, one for Terraform state.
124+
- **DNS child zone**: delegated from the connectivity hub zone (hub-spoke and firewall flavors only).
125+
- **Service account**: workload-scoped service account with a rotating key stored in Secrets Manager.
126+
127+
The `corporate` flag is the key switch:
128+
129+
| `corporate` | Network attachment | Default route | DNS |
130+
|---|---|---|---|
131+
| `true` | Shared Network Area | Firewall LAN IP (if firewall deployed), else internet via WAN table | Child zone delegated from hub |
132+
| `false` | Standalone network | Internet directly | No DNS delegation |
133+
134+
Source: `src/modules/landing-zone/`
135+
136+
### DevOps (optional)
137+
138+
Provisions a separate DevOps project (`<company_code>-pltfm-devops-prod`) with a managed Git instance (Gitea or equivalent, controlled by `git_flavor`). Network access can be restricted to specific CIDR ranges via `allowed_network_ranges`. Disabled by default: enable by setting the `devops` variable.
139+
140+
Source: `src/modules/devops/`
141+
142+
### Sandboxes (optional)
143+
144+
Provisions one or more lightweight STACKIT projects under the Sandboxes folder for experimentation and PoCs. Each sandbox is a minimal project with an owner: no shared networking or platform integration. Useful for testing before promoting workloads to a proper landing zone.
145+
146+
Source: `src/modules/sandboxes/`
147+
148+
## Deployment Flavors
149+
150+
Three reference configurations are provided in `src/config/`. Select the one that matches your network requirements.
151+
152+
### Standalone
153+
154+
The simplest configuration. Provisions governance, management, and one or more landing zone projects. No shared network infrastructure — each landing zone uses an independent network suitable for internet-facing or isolated workloads.
155+
156+
![Standalone architecture](diagrams/standalone-architecture.svg)
157+
158+
**Use when:** workloads do not require private connectivity to each other or to on-premises systems.
159+
160+
### Hub-Spoke
161+
162+
Adds a connectivity hub with a shared Network Area. All corporate landing zones are attached to this area, enabling private east-west traffic between projects and a shared IP address plan. DNS zones are managed centrally in the hub project.
163+
164+
![Hub-Spoke architecture](diagrams/hub-and-spoke-architecture.svg)
165+
166+
**Use when:** workloads need private connectivity to each other and a shared DNS namespace, but centralized traffic inspection is not required.
167+
168+
### Hub-Spoke + Firewall
169+
170+
Extends the hub-spoke topology with a firewall VM deployed in the connectivity project. All corporate landing zones route their default traffic through the firewall LAN interface, enabling centralized egress inspection and east-west traffic control.
171+
172+
![Hub-Spoke + Firewall architecture](diagrams/hub-and-spoke-firewall-architecture.svg)
173+
174+
**Use when:** compliance requirements mandate traffic inspection, or centralized egress control with a consistent public IP is needed.
175+
176+
## Network Topology
177+
178+
The three deployment flavors differ only in what the connectivity module deploys and how landing zone traffic is routed.
179+
180+
### Standalone
181+
182+
No connectivity module. Each landing zone has an independent network with direct internet access. No shared IP space, no private east-west connectivity, no DNS federation.
183+
184+
```
185+
[LZ Project A]──internet
186+
[LZ Project B]──internet
187+
```
188+
189+
### Hub-Spoke
190+
191+
Connectivity module deploys a Network Area and WAN routing table. All corporate landing zones join the Network Area and can reach each other over private IPs. Default route is the WAN routing table (internet egress, no inspection).
192+
193+
```
194+
[LZ Corporate A] ──┐
195+
[LZ Corporate B] ──┤── Network Area (10.0.0.0/16) ──── internet (WAN table)
196+
[LZ Corporate C] ──┘
197+
[LZ Public D] ──── standalone ──── internet
198+
```
199+
200+
### Hub-Spoke + Firewall
201+
202+
Extends hub-spoke: a firewall VM sits in the connectivity project. Each corporate landing zone routes all traffic (`0.0.0.0/0`) through the firewall LAN IP. The firewall's WAN interface holds a static public IP for consistent egress identity.
203+
204+
```
205+
[LZ Corporate A] ──┐ routing: 0.0.0.0/0 → 10.0.0.4 (firewall LAN)
206+
[LZ Corporate B] ──┤── Network Area (10.0.0.0/16) ──→ [Firewall VM]
207+
[LZ Corporate C] ──┘ vtnet1 (LAN) 10.0.0.4
208+
vtnet0 (WAN) ──→ internet
209+
(static public IP)
210+
[LZ Public D] ──── standalone ──── internet
211+
```
212+
213+
Traffic flow for a corporate landing zone (firewall flavor):
214+
215+
1. VM in LZ sends packet to any destination.
216+
2. Routing table entry `0.0.0.0/0 → 10.0.0.4` forwards it to the firewall LAN interface (`vtnet1`).
217+
3. Firewall inspects and NATs the packet out through `vtnet0` (WAN) using the static public IP.
218+
4. Return traffic arrives at the public IP, firewall translates back and delivers to the originating VM.
219+
220+
East-west traffic between corporate LZs stays within the Network Area and can be permitted or denied by firewall policies.
221+
222+
## Resource Naming
223+
224+
All resources follow a consistent convention driven by `company_code`:
225+
226+
```
227+
<company_code>-<layer>-<component>-<env>
228+
```
229+
230+
| Example name | What it is |
231+
|---|---|
232+
| `exc-pltfm-mgmt-prod` | Management project |
233+
| `exc-pltfm-hub-prod` | Connectivity (hub) project |
234+
| `exc-pltfm-devops-prod` | DevOps project |
235+
| `exc-lz-data-prod` | Application landing zone for workload `data` in `prod` |
236+
| `exc-sbx-*` | Sandbox projects |
237+
238+
`exc` is the `company_code` from the example config. Replace with your organization's short code.

0 commit comments

Comments
 (0)