What goes wrong without a landing zone
The usual pattern is a single cloud account where the first project started. Workloads land in it, then others, with shared credentials, no consistent tagging and no central audit trail. A year later, nobody can say which resources belong to which team, a developer has administrator rights in production, and a security review asks for evidence that logs are retained. Fixing this means moving live workloads, which is the riskiest kind of cleanup.
A landing zone prevents that by treating the foundation as a deliverable. It is stage two of our cloud migration service, built after the roadmap is agreed and before the first wave moves. Teams already living with unmanaged sprawl will recognise the problem from ClickOps.
What good looks like
- A clear organisational structure: production and non-production separated, with dedicated accounts or subscriptions for audit logs, security tooling and shared network services.
- Sign-in through a central identity provider, with short-lived credentials and no long-lived access keys for people.
- Preventive guardrails that block dangerous actions, plus detective controls that report on drift.
- Audit logs written to a protected location that workload administrators cannot alter.
- Budgets and tagging rules so cost has an owner from the first day.
- All of it defined in code, not clicked together.
How it works on AWS
The structure is an AWS Organization with organisational units, for example a security OU, an infrastructure OU, and workload OUs for production and non-production. Service control policies sit on OUs to set the maximum permissions an account can ever have.
A typical set of preventive guardrails denies leaving the organisation, disabling CloudTrail, creating resources outside approved regions and removing the baseline security roles. An example policy limiting regions looks like this:
resource "aws_organizations_policy" "region_restriction" {
name = "deny-unapproved-regions"
type = "SERVICE_CONTROL_POLICY"
content = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "DenyOutsideApprovedRegions"
Effect = "Deny"
NotAction = ["iam:*", "organizations:*", "route53:*", "support:*", "cloudfront:*"]
Resource = "*"
Condition = {
StringNotEquals = {
"aws:RequestedRegion" = ["eu-west-1", "eu-central-1"]
}
}
}]
})
}
Global services are excluded from the region check so that identity and DNS keep working. Always test a policy like this in a sandbox OU before attaching it widely, because a wrong deny can lock out administrators.
Control Tower can bootstrap the log archive and audit accounts and a set of guardrails. We often use it for that and manage the rest, such as network, workload accounts and customisations, with Terraform.
How it works on Azure
Azure uses management groups to organise subscriptions, with Azure Policy assignments at group level. The Microsoft landing zone reference architecture separates platform subscriptions (identity, management, connectivity) from application landing zones. Policy definitions enforce allowed locations, required tags, diagnostic settings and encryption, and deny public exposure of storage and databases by default.
We follow the reference architecture where it fits and simplify where an organisation does not need the full enterprise shape. Infrastructure is provisioned with Terraform or Bicep, whichever your team will maintain, and delivered through a pipeline as in our Azure DevOps consulting work.
Decisions and trade-offs
Control Tower or custom. Control Tower gets you running quickly but constrains some design choices and can lag new features. A custom build gives full control at the price of more maintenance. For a typical scale-up, a hybrid is the practical answer.
Terraform or native tooling. Terraform keeps AWS and Azure under one language and plan workflow, which suits teams on both clouds. Bicep or CloudFormation integrate tightly with their platforms. Choose what your team will actually run after we leave. Our Terraform service covers state layout and pipeline design.
One account per team or per environment. Per environment per application gives the strongest isolation but creates many accounts to manage. We use an account vending process so creating one is a pull request, not a project.
When not to over-build. If you run a single product with a small team, you do not need a dozen organisational units. Start with the minimum separation that protects production and logs, and add structure when there is a reason.
A worked example: vending a new workload account
When a team needs a new environment, the request is a pull request that adds one module call: an account name, an owner tag, an organisational unit and a budget. The pipeline creates the account, attaches the baseline roles, enables logging into the central archive and applies the guardrails inherited from the OU. A reviewer from the platform team approves the change, and the requesting team receives access through central sign-in rather than a shared password. Nothing in that flow needs a ticket queue or a console session, which is the point of building the foundation as code.
Common failure modes
- Guardrails written but not tested. A broad deny blocks a legitimate pipeline and the team disables the policy. We test in a sandbox OU.
- Management account misuse. Workloads should never run in the account that governs the organisation.
- Network added as an afterthought. Overlapping address ranges are painful to fix, so the address plan is agreed up front, as covered in network architecture.
- Identity left until later. Local users appear and never leave. We set up central sign-in first, described in identity and directory integration.
- No ownership. A landing zone nobody owns drifts. We agree who maintains it.
Delivery and handover
The code lives in your repository, and the pipeline runs in your tooling. We document the structure, how to request a new account, how to change a guardrail safely and how to recover if a policy locks something out. The security baseline is layered on top of this foundation.
How to tell it is working
A new environment can be created from a pull request in under a day of review time. Every account sends logs to the central location. No human uses long-lived keys. Policy compliance reports are mostly green and the exceptions are explained. To discuss the right shape for your organisation, contact us.