· 5 min read

What a cloud landing zone needs before your first workload

Accounts, identity, logging, networking and guardrails: the foundation that is cheap to build on day one and painful to retrofit later.

CloudTerraformAWS

Most cloud estates start the same way: one account, a few engineers with admin access, and resources created by hand to hit a deadline. That works until the second team arrives, the first auditor asks for access logs, or someone deletes the wrong database. A landing zone is the set of decisions you make once, up front, so every workload after that lands somewhere safe by default.

It does not have to be a big programme. A useful landing zone is a few weeks of work, all of it in code. Here is what we put in place before the first production workload, using AWS terms — the same ideas map to GCP folders and organization policies, and to Azure management groups and Azure Policy.

1. Separate accounts, not separate tags

The account is the strongest isolation boundary the cloud gives you: separate IAM, separate quotas, separate blast radius. Tags and naming conventions are not a security boundary. A small, sensible starting layout:

  • A management account that runs AWS Organizations and billing — and nothing else.
  • A log archive account that receives audit logs and that almost nobody can write to.
  • A security tooling account that hosts GuardDuty, Security Hub and AWS Config as delegated administrator.
  • Workload accounts per environment — at minimum separate production and non-production, and per team once you have several.
  • A shared services account for networking and CI runners, if you need them.

Group them into organizational units (OUs) so that policies apply to a whole class of accounts at once. New accounts should come from a pipeline — AWS Control Tower's Account Factory, or your own Terraform module — so that every account starts with the same baseline instead of whatever the creator remembered.

2. Identity: SSO in, long-lived keys out

People should sign in through your identity provider and IAM Identity Center, receiving short-lived credentials scoped to a permission set per account. That gives you one place to offboard someone and one log of who assumed what. Long-lived IAM users with access keys are the most common root cause we see in cloud incidents; the target is to have none.

Machines follow the same rule. CI pipelines should use OIDC federation — GitHub Actions and GitLab both support it — to assume a role per environment, instead of storing access keys as repository secrets. Lock the root user of every account with MFA and do not use it day to day.

3. Guardrails with service control policies

Service control policies (SCPs) set the outer limit of what any identity in an account can do, including its administrators. Keep them few and obvious, so they rarely surprise anyone:

  • Deny actions outside the regions you actually use.
  • Deny disabling or deleting CloudTrail, GuardDuty and AWS Config.
  • Deny leaving the organization.
  • Deny creating IAM users and access keys in workload accounts, once SSO and OIDC are in place.

Test new SCPs on a sandbox OU first. An SCP that blocks a service the platform team depends on is an outage for every account under it.

4. Logging that an attacker cannot erase

Turn on an organization-wide CloudTrail trail that writes to a bucket in the log archive account, with versioning and Object Lock or a restrictive bucket policy so that nobody in a workload account can delete it. Add AWS Config recording in every account and region you use. When something goes wrong, these logs are how you find out what happened; during an audit, they are a large share of the evidence.

5. A network plan before the first VPC

Overlapping IP ranges are cheap to avoid and expensive to fix: once two VPCs share a CIDR range, you cannot route between them without NAT tricks or a migration. Allocate address space from a central plan — AWS VPC IPAM can enforce it — and leave room for regions and environments you do not have yet. Connect VPCs through a Transit Gateway in the shared services account rather than a growing mesh of peering connections, and decide early where egress to the internet happens and how it is inspected.

6. Terraform foundations

All of the above should live in code, in a repository with review rules, applied by a pipeline rather than from a laptop. A few habits save a lot of pain later:

  • Keep state remote, encrypted and locked. On AWS that is an S3 backend; recent Terraform versions can lock with the bucket itself through use_lockfile, without a DynamoDB table.
  • Split state by account and component, so one plan never touches everything at once and a broken module cannot block unrelated changes.
  • Pin provider and module versions, and upgrade them deliberately.
  • Run terraform plan on every pull request and post the output for review; apply only from the main branch.
  • Detect drift on a schedule, so changes made by hand in the console show up within a day instead of during the next incident.
terraform {
  backend "s3" {
    bucket       = "example-terraform-state"
    key          = "prod/network/terraform.tfstate"
    region       = "eu-central-1"
    encrypt      = true
    use_lockfile = true
  }
}

7. Cost visibility from day one

Enforce a small set of tags — owner, environment, cost centre — with tag policies, activate them as cost allocation tags, and set a budget with alerts on every account. It takes an hour, and it means the first surprising bill comes with a name attached. Our cloud cost checklist covers what to do once the spend is visible.

What can wait

A landing zone should be small. Multi-region failover, a full service catalogue, custom compliance frameworks and elaborate network inspection can all come later, when a real workload needs them. What cannot wait is the account structure, identity, logging and address plan — those are the decisions that are hard to change once people build on top of them.

Setting up landing zones and Terraform foundations is a core part of our cloud infrastructure work, and it was the starting point of a fintech's migration to Kubernetes. If your estate grew faster than its foundations, get in touch.

Let's build something awesome.

Tell us about your infrastructure or product challenge. We'll reply within one business day.