ARCHITECTURE · LANDING ZONE

How to build a STACKIT landing zone

A STACKIT landing zone is an organization with folders and projects, a decision on whether those projects join a Network Area, an address plan, a DNS answer and the identities that run Terraform. Source clouds hand you a VPC and an account structure; on STACKIT you choose the project layout first, because the project, not a VPC object, is the boundary your networks live in. This page shows the layouts, what a real StackToIT run asks of the landing zone, and the order in which to build it.

Four ways to lay out the target

The options differ in where the private network boundary sits and how much of the source's routing you can reproduce. Facts marked docs come from the STACKIT documentation listed below; facts marked run come from the assessment shown further down.

LayoutWhat it gives youWhat it costs you
One project, no Network AreaThe networks of a project share the project's router and reach each other; security groups are project-wide (run). The run's evidence that STACKIT's default routing gives a routed network the same reachability as the source's NAT route comes from a test in a project outside a Network Area (eu01, 10 October 2026); a project inside an area was not tested.No private connection to other projects. The outbound address is the network's own, shared by every routed network of the project, not fixed and not settable (run). One set of quotas for everything.
Projects in a Network AreaAn area connects projects within an organization at network level and eases the connection to on-premises environments (docs). A network takes its address range from the area's ranges, and the routing tables of all project routers update on their own (docs).The run has not read the default routing table of an area, so a project created inside an area is not covered by its replacement of a NAT route table: that case is your decision. Custom routing tables are an opt-in feature that may still change: up to 20 tables per area and 50 routes per table, switched on by a label when the area is created; an existing area is moved over through the Help Center (docs).
Several projects per environment, grouped in foldersFolders group projects and hold no resources themselves; one level of folders is supported (docs). Quotas are set per project and cover IaaS and Cloud Foundry resources, not every resource in a project (docs), so a workload that needs its own headroom can get a project of its own.More objects to own and more role assignments. Projects do not see each other privately unless an area connects them, which is the previous row.
Area for shared services, public projects for isolated workloadsThe projects page names two project types, Public and Network Area (the latter where it is enabled). Combining them in one organization, shared services reachable over the area and isolated workloads outside it, is a design this page derives from that; the documentation does not describe it as a pattern.Two network models to operate, two sets of routing rules to explain, and the egress decision of the first row still applies to every project outside the area.

The run is one small AWS estate. It tells you what its own resources need; it does not choose a layout for your organization.

A VPC with three subnets, converted

A small estate written for this page and assessed by StackToIT on 4 November 2026. Left: the VPC and two of its three subnets. Right: the two STACKIT networks the draft writes (review comments above each block are left out). The VPC itself has no block, neither network carries its zone, and the public-address flag of public_a is not carried.

Example inputmain.tf
resource "aws_vpc" "core" {
  cidr_block           = "10.40.0.0/16"
  enable_dns_hostnames = true
  tags                 = { Name = "core" }
}

resource "aws_subnet" "public_a" {
  vpc_id                  = aws_vpc.core.id
  cidr_block              = "10.40.0.0/24"
  availability_zone       = "eu-central-1a"
  map_public_ip_on_launch = true
  tags                    = { Name = "public-a" }
}

resource "aws_subnet" "app_a" {
  vpc_id            = aws_vpc.core.id
  cidr_block        = "10.40.10.0/24"
  availability_zone = "eu-central-1a"
  tags              = { Name = "app-a" }
}
STACKIT Terraform by StackToITterraform/network.tf
resource "stackit_network" "app_a" {
  project_id       = var.project_id
  name             = "app-a"
  ipv4_prefix      = "10.40.10.0/24"
  ipv4_nameservers = var.default_ipv4_nameservers
  labels = {
    Name = "app-a"
  }
}

resource "stackit_network" "public_a" {
  project_id       = var.project_id
  name             = "public-a"
  ipv4_prefix      = "10.40.0.0/24"
  ipv4_nameservers = var.default_ipv4_nameservers
  labels = {
    Name = "public-a"
  }
}
  • The project is the boundary

    The draft's own comment states it: the project is the VPC's boundary, and the subnets become networks in that one project, routed by the project's router. A routing table is an area resource, not a project resource.

  • Same prefix, no zone

    Each subnet becomes a stackit_network with the same IPv4 prefix. The availability zone is not carried, because the network serves the region; servers and volumes choose their zone.

  • Public is not a subnet property

    map_public_ip_on_launch has no counterpart on a network. A server gets a public IP as its own resource, so the flag is listed as not carried and decided per server.

  • Closed egress is not available

    The run records that STACKIT documents no way to disable outbound access for a network, so a subnet that had no internet path in the source is flagged as widened, not silently copied.

What the run asks of the landing zone

From the same run. Left: the address ranges and routing precondition as migration/landing-zone-requirements.md states them. Right: how assessment.json records the private DNS zone, the instance role and the route table (id, class, confidence and target; the reasons are summarised in the table below).

Landing zone requirementsmigration/landing-zone-requirements.md
| Resource | Attribute | Prefix |
|---|---|---|
| `stackit_network.app_a` | `ipv4_prefix` | Stated in `terraform/network.tf`: `10.40.10.0/24` |
| `stackit_network.data_a` | `ipv4_prefix` | Stated in `terraform/network.tf`: `10.40.20.0/24` |
| `stackit_network.public_a` | `ipv4_prefix` | Stated in `terraform/network.tf`: `10.40.0.0/24` |

Ranges the security group rules name (the addresses a rule lets in or out, not networks of the target):

- `10.40.0.0/24` (1 rule)

## 5. Routing

- Create the target project outside a Network Area: aws_route_table.app is replaced by STACKIT's default routing, which was observed to give a routed network the same reachability only in a project outside a Network Area (needed before the pilot)
StackToIT assessmentassessment.json
{
  "id": "aws_route53_zone.internal",
  "class": "REDESIGN",
  "confidence": "MEDIUM",
  "target": {
    "service": "self-managed internal DNS (e.g. CoreDNS or BIND on servers or SKE)"
  }
}
{
  "id": "aws_iam_role.deploy",
  "class": "MANUAL_REVIEW",
  "confidence": "LOW",
  "target": {
    "service": "STACKIT service account attached to servers"
  }
}
{
  "id": "aws_route_table.app",
  "class": "RECONFIGURE",
  "confidence": "LOW",
  "target": {
    "service": "implicit (STACKIT network default routing)"
  }
}
  • Ranges are listed, not invented

    Every prefix comes from the source subnets. Open prefixes are marked, with the variable or decision that settles them. Check the list against your on-premises ranges before the first apply; that overlap check is practice, not something the run performs.

  • Routing is a precondition step

    The run turns the NAT route table into a step: create the target project outside a Network Area, before the pilot. It belongs to the Network Architect and sits in the plan's preparation phase, next to the egress decision and ahead of every network block.

  • Identity and DNS stay open

    The run writes no service account for the instance role and no DNS zone for the private zone. Both become manual steps of the execution plan, and the two private-zone settings are listed as not migrated: neither has a one-to-one STACKIT resource.

What the engine classifies, and why

Source constructSTACKIT targetClass and reason from the run
VPCProject networking, or a Network Area when networks must talk privatelyRECONFIGURE: STACKIT has no VPC container object in its general-availability model; each subnet becomes a network in a project.
Subnets (public, app, data)One STACKIT network each, same IPv4 prefixRECONFIGURE: public or private is not a subnet property.
Internet gateway, NAT gateway, Elastic IPImplicit: the network's default gateway and outbound source NATRECONFIGURE: no discrete objects exist; the fixed egress address is lost.
Route table with a NAT default routeSTACKIT's default routingRECONFIGURE, low confidence: matching reachability was observed in a project outside a Network Area; decision on the egress address before the pilot.
Security groupSTACKIT security group with rulesRECONFIGURE: stateful rule sets; AWS-internal ranges must be replaced.
Private hosted zoneDNS server you run, for example on servers or SKEREDESIGN: STACKIT DNS is public authoritative DNS only and cannot be associated with a network.
EC2 instance roleService account attached to the serverMANUAL REVIEW, low confidence: no instance profile in the estate hands the role to a server, so the run cannot tell which servers use it and writes no service account.

Classes and reasons as the run decided them. The DNS Resolver introduction says the full scope of functionality may not yet be implemented and does not mention private zones, so plan internal names around a DNS server you operate.

The order to build it in

  1. 1. Organization and roles

    The organization is the top-level technical scope. Give the people who migrate the Resource Manager roles they need: Project Creator and Folder Creator exist at folder scope, and the legacy organization roles do not inherit down to folders or projects (docs). The run names no organization and assumes none.

  2. 2. Folders and projects

    Create the folder level first (one level only), then the projects: for example one per environment, and one for a workload that needs its own quota. The draft takes the project from the variable project_id, which has no default.

  3. 3. Decide area or no area

    Use the table above. If any project must reach another privately, or on-premises systems must reach it, plan an area. If the run's routing precondition applies to you, keep that project outside it or decide the routing table yourself.

  4. 4. Address plan

    Fix the prefixes from section 4 of the requirements file, remove overlaps, and keep the ranges your security group rules name in step with them.

  5. 5. DNS and egress

    Stand up the DNS server for internal names, and answer the egress decision: accept the network's address, or give each server that an allow-list names its own public IP.

  6. 6. Identities

    Create the service account Terraform acts as. The requirements file says only that the identity needs the role that may create IaaS resources in the project; it names no role, so look it up. Pipelines are covered in the CI/CD guide.

  7. 7. Services and quotas

    Enable the services section 8 lists for the project and region, and check quota for the counts in section 9. The run states no quota and reads none.

  8. 8. Apply foundation first

    The execution plan groups networks and security groups before workloads, and lists the manual preconditions before tofu apply. Run plan against a test project first.

Decisions the architect owns

  • Project layout

    One project, several, or an area. The run cannot choose it; it can only report what its resources need.

  • Egress address

    Record the answer to the egress decision before the pilot; seven plan steps wait for it in this run.

  • Internal DNS

    Which server answers internal names, and who operates it.

  • Boot images and machine types

    The draft leaves the image, machine type and boot volume size to variables because the source names an AMI and an instance type, not a STACKIT equivalent.

  • Who may create projects

    Project creation is a role. Keep it with a small group, and write the rule down before the first project exists.

Landing zone questions

Does STACKIT have a VPC?

Not as a container object in the general-availability model, according to the run. A subnet becomes a network in a project, and the project's router connects the networks of that project. Networks of different projects join through a Network Area.

Do I need a Network Area?

Only if projects must reach each other privately or you connect on-premises environments over it. The routing finding of the run is a reason to decide this early, because a NAT route table is replaced by default routing whose reachability was observed only in a project outside an area.

How deep can folders go?

One level. STACKIT currently supports a single level of folder hierarchy, and folders group projects without holding cloud resources.

Does StackToIT create the organization and projects?

No. The draft needs a project and takes its id from a variable. StackToIT reads and writes files and creates nothing in a cloud account.

What replaces my instance roles?

A service account attached to the server, which the run marks as a manual review with low confidence. Decide the permissions yourself and test them on one server.

Sources

Your next move: STACKIT.

Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.