← Back to list

Designing a Secure Multi-Account AWS Setup for Wilvor — Aviation Operations Intelligence Platform

Authors:

Syed Ibrahim Hamza · 2026-06-27 20:52 · 27 claps · 13.4 min read
#aws #data-science #data-engineering #big-data #agentic-ai
Open on Medium ↗
Wiki topics: AGT · AI Agents ML · Machine Learning LIT · Literature & Writing ☁️ · DevOps & Cloud 🔧 · Data Engineering 🔬 · Science · General

Designing a Secure Multi-Account AWS Setup for Wilvor — Aviation Operations Intelligence Platform

Authors:

Hamza Wajid Paracha LinkedIn | GitHub

Syed Ibrahim Hamza LinkedIn | GitHub

TL;DR

In this phase of Wilvor, We moved from project planning into real cloud foundation work.

Wilvor is an aviation operations intelligence platform. The goal is to process aircraft, weather, airport, and risk data in a way that can support real-time decisions. Before building the actual pipelines, dashboards, APIs, and data stores, We wanted the AWS account structure to be clean and secure.

So instead of using one AWS account for everything, we created a production-style multi-account setup using AWS Organizations.

The final setup looks like this:

Wilvor AWS Organization
│
├── Wilvor Management Account
│   └── AWS Organizations, IAM Identity Center, billing, budgets
│
├── Wilvor Development Account
│   └── Development and testing
│
└── Wilvor Production Account
    └── Final demo and production-style deployment

we also configured IAM Identity Center, individual users, groups, permission sets, MFA, account assignments, billing visibility, budgets, and a simple account register.

This article explains the full process step by step.

Introduction

In the earlier Wilvor articles, we focused on the vision, data sources, business requirements, and workflow.

We decided that Wilvor should not just be another flight tracker. The goal is to build a cloud-native aviation operations intelligence platform that can understand aircraft movement, weather risk, airport conditions, and operational recommendations.

That sounds exciting, but it also creates a serious cloud architecture question:

Where should this system actually live?

At first, it is tempting to create everything in one AWS account. That is simple and fast. But as the project grows, one account becomes messy.

Development resources mix with production resources.

Billing becomes harder to understand.

Security boundaries become weak.

Access control becomes confusing.

And if something breaks, the blast radius is bigger than it needs to be.

So before building the Wilvor VPC, Kinesis streams, Lambda functions, DynamoDB tables, APIs, and dashboards, we decided to set up the AWS foundation properly.

This article documents that foundation.

It is not the most glamorous part of the project, but it is one of the most important.

Press enter or click to view image in full size

Why We Started with Account Structure

Wilvor will eventually have many moving parts:

  • Real-time aircraft ingestion
  • Aviation weather ingestion
  • Event-driven processing
  • Risk scoring
  • Recommendation logic
  • APIs
  • Dashboards
  • Analytics storage
  • Monitoring
  • Security controls

If all of that is placed inside one AWS account, the project can still work.

But it would not feel production-grade.

A better approach is to separate the project into accounts.

For Wilvor, we chose three accounts:

Management
Development
Production

The Management account controls the organization.

The Development account is where we build and test.

The Production account is where the clean final deployment will live.

This setup is simple enough for a two-person project, but still close to how real cloud teams organize AWS environments.

The Final Account Plan

The account structure we planned was:

AWS Organization
│
├── Wilvor Management
│   └── wilvor@gmail.com
│
├── Wilvor Development
│   └── wilvor+dev@gmail.com
│
└── Wilvor Production
    └── wilvor+prod@gmail.com

We used Gmail plus addressing for the Dev and Prod accounts.

That means AWS sees these as separate email addresses:

wilvor@gmail.com
wilvor+dev@gmail.com
wilvor+prod@gmail.com

But all emails still arrive in the same main Gmail inbox.

This made the setup easier because I did not need to create three separate mailboxes.

Step 1 — Secure the Wilvor Management Account

The first account we created was the main Wilvor AWS account.

This became the Management account.

The Management account should not be used for application workloads. I do not want Lambda functions, Kinesis streams, DynamoDB tables, or application buckets inside this account.

Its purpose is different.

It is responsible for:

  • AWS Organizations
  • IAM Identity Center
  • Billing
  • Budgets
  • Account governance
  • Central access management

The first thing we did was secure the root user.

we signed in as the root user and enabled MFA.

we also confirmed that there were no root access keys.

Root access keys are dangerous because they give full programmatic access to the entire account. For this setup, we did not need them at all.

Step 2 — Create the AWS Organization

After securing the Management account, we opened AWS Organizations.

Then we created a new organization.

we selected the full organization setup instead of only consolidated billing.

This is important because we want more than shared billing.

We want the ability to manage accounts, permissions, policies, and governance from one place.

After this step, the original Wilvor account became the Management account of the organization.

The Management account is now the control plane for the AWS environment.

Step 3 — Create a Workloads Organizational Unit

Next, we created an Organizational Unit, also called an OU.

An OU is basically a folder for AWS accounts.

I created one OU called:

Workloads

The structure became:

Root
│
├── Wilvor Management
│
└── Workloads

I kept the OU structure simple.

For a large company, I could create separate OUs for development, production, security, logging, and sandbox accounts. But for Wilvor, that would be too much at this stage.

For now, one Workloads OU is enough.

Step 4 — Create the Development Account

Next, we created the Wilvor Development account from inside AWS Organizations.

We did not create a new AWS account separately from the normal AWS signup page.

Instead, we used:

AWS Organizations → Add AWS account → Create AWS account

The account details were:

Account name: Wilvor Development
Email: wilvor+dev@gmail.com
Role name: OrganizationAccountAccessRole

This created a separate AWS account under the Wilvor organization.

The Development account is where we can build, test, destroy, and recreate resources without touching Production.

This is where most of the early Wilvor engineering work will happen.

Step 5 — Create the Production Account

After Dev, we created the Production account in the same way.

The account details were:

Account name: Wilvor Production
Email: wilvor+prod@gmail.com
Role name: OrganizationAccountAccessRole

This account will hold the final production-style version of the platform.

For now, Production will stay mostly empty.

That is intentional.

I do not want to experiment directly in Production. The clean approach is to test in Dev first, then deploy stable infrastructure into Prod later.

After creating both accounts, the structure looked like this:

Step 6 — Choose One IAM Identity Center Region

Before enabling IAM Identity Center, we had to think about Region selection.

IAM Identity Center is managed from one selected AWS Region.

The important thing is not which Region someone picks. The important thing is to pick one and stay consistent.

For Wilvor, we chose one Region for IAM Identity Center and continued the setup there.

This avoids confusion later when users, permission sets, and account assignments appear in one Region but not another.

Step 7 — Enable IAM Identity Center

After selecting the Region, we opened IAM Identity Center from the Management account.

I enabled the organization instance of IAM Identity Center.

This is the central login system for the team.

Instead of creating IAM users inside every AWS account, IAM Identity Center lets users sign into one AWS access portal and then choose which AWS account and role they want to access.

This is much cleaner.

The access flow becomes:

Hamza / Ibrahim
        ↓
AWS Access Portal
        ↓
Choose Account
        ↓
Choose Permission Set
        ↓
Open AWS Console

This is better than creating separate IAM users in Dev, Prod, and Management.

Step 8 — Create Identity Center Users

Next, I created individual IAM Identity Center users.

For this project, there are two people:

Hamza
Ibrahim

Each person has their own user.

We did not create a shared account like:

wilvor-admin
team-user
dev-login

Shared users are a bad habit because actions become harder to trace.

If something changes in AWS, we want to know who did it.

So the users were created individually:

hamza
ibrahim

Each user received an invitation email to set up their password and login.

Step 9 — Create Groups

After creating users, we created groups.

Groups make access management easier.

Instead of assigning permissions to each person one by one, we can assign permissions to a group.

For Wilvor, I created groups like:

Wilvor-Developers
Wilvor-Production-Admins
Wilvor-Management-Administrator

Both users were added to the right groups.

At this stage, the team is small, so this may look unnecessary. But it keeps the setup clean.

Later, if another person joins the project, we can just add them to the correct group instead of rebuilding access from scratch.

Step 10 — Create Permission Sets

Permission sets are one of the most important parts of IAM Identity Center.

A permission set defines what kind of access someone gets inside an AWS account.

For Wilvor, we created permission sets for:

WilvorDevAdministrator
WilvorProdAdministrator
WilvorProdReadOnly
WilvorManagementAdministrator

The idea was simple.

In Development, we need admin access because we are building and testing.

In Production, admin access should be more controlled.

For Production, we also created a read-only option so we can inspect resources without changing anything.

For the Management account, we created a dedicated administrator permission set. This should only be used for organization, billing, identity, and governance tasks.

Step 11 — Assign Account Access

This was the step that made the permissions actually work.

Creating a user is not enough.

Creating a permission set is not enough.

The missing piece is account assignment.

We had to connect:

User or Group
+
AWS Account
+
Permission Set

For example:

Wilvor-Developers
→ Wilvor Development
→ WilvorDevAdministrator

And:

Wilvor-Production-Admins
→ Wilvor Production
→ WilvorProdAdministrator

For the Management account:

Hamza / Ibrahim
→ Wilvor Management
→ WilvorManagementAdministrator

This is where IAM Identity Center creates the actual access path into each AWS account.

Step 12 — Test Access Before Logging Out of Root

Before trusting the setup, we tested access.

We opened the AWS access portal and signed in as my Identity Center user.

Then we checked whether we could see:

Wilvor Management
Wilvor Development
Wilvor Production

We opened each account and confirmed that the top-right account name matched the account I expected.

This step is important.

If access is broken and you already logged out of root, you may need to go back and fix things from the root account.

So we tested everything first.

Step 13 — Configure IAM Identity Center MFA

Security was a major reason for doing this setup properly.

So the next step was MFA.

There are two types of MFA in this setup:

Root MFA

This protects the original root user.

IAM Identity Center MFA

This protects Hamza and Ibrahim when they log in through the AWS access portal.

We configured IAM Identity Center MFA so users must register and use an MFA device.

This means even if a password is compromised, the attacker still needs the second factor.

In my setup, Hamza registered an MFA device successfully. Ibrahim still had to complete MFA registration at the time we checked the user page.

This was a good reminder that creating the user is not the same as completing the user setup.

Step 14 — Add Account Contact Information

After access and MFA, we reviewed account contact information.

Each AWS account should have useful contact details.

This includes:

  • Billing contact
  • Operations contact
  • Security contact

For a small project, these can point to the same monitored team inbox.

The important thing is that critical AWS emails do not go to an inbox nobody checks.

This matters for billing alerts, security notices, abuse reports, and account recovery.

Step 15 — Configure Billing Visibility

This step caused some confusion, and I think it is worth mentioning honestly.

Even after signing in as:

WilvorManagementAdministrator / hamza

We still saw:

Access denied

inside the Cost and Usage widget.

At first, this looked like my IAM Identity Center setup was broken.

But it was not broken.

The issue was Billing access.

AWS Billing has an extra setting that must be activated from the root account before IAM roles can access billing pages.

This was a useful real-world lesson. Administrator access does not always mean billing access is already enabled.

Step 16 — Create Organization-Level Budgets

After billing visibility, we created budgets.

Budgets are important because this is still a project.

Wilvor is designed like a production-grade system, but that does not mean we want surprise AWS charges.

We created monthly budgets for:

Organization-wide cost
Development account cost
Production account cost

A simple starting point was:

Development: $25/month
Production:  $15/month
Total:       $40/month

The exact amount can change later, but the important part is having alerts.

We configured alerts at different thresholds, such as:

50%
80%
100%
Forecasted 100%

Budgets do not automatically stop spending, but they give early warning.

Step 17 — Enable Cost Explorer

Next, we enabled Cost Explorer.

Cost Explorer helps track spending over time.

The useful view for this setup is:

Group by → Linked account

That means we can see how much is being spent by:

Wilvor Management
Wilvor Development
Wilvor Production

This will become more useful after we start deploying infrastructure.

For now, it gives a clean base for future cost tracking.

Step 18 — Keep Service Control Policies Simple

AWS Organizations supports Service Control Policies, also called SCPs.

SCPs are powerful.

They can restrict what accounts are allowed to do.

For example, an SCP can deny access to certain Regions or prevent disabling security services.

But SCPs can also cause problems if used too early or applied incorrectly.

So for Phase 1, we kept SCPs simple and left the default policy in place.

The goal of this phase was to build a clean foundation, not create a complicated governance system on day one.

Later, we can add SCPs carefully.

Possible future SCPs include:

  • Deny disabling CloudTrail
  • Deny public S3 bucket settings
  • Restrict unused Regions
  • Deny expensive services unless approved

But those should be tested carefully before applying them broadly.

Step 19 — Create a Shared Account Register

After the setup, we created a simple account register.

This is not a password file.

It is just a clean inventory of accounts.

It includes:

Account name
Purpose
Root email
Account ID
OU
Identity Center Region
Access portal URL

The account register helps avoid confusion later.

When working with multiple AWS accounts, it is very easy to forget which account is which.

A simple register prevents mistakes.

Example:

Wilvor Management
Purpose: Organizations, billing, identity
Email: wilvor@gmail.com
OU: Root
Wilvor Development
Purpose: Development and testing
Email: wilvor+dev@gmail.com
OU: WorkloadsWilvor Production
Purpose: Final production-style deployment
Email: wilvor+prod@gmail.com
OU: Workloads

Secrets, passwords, MFA recovery codes, and access keys should not be stored in this register.

Those belong in a secure password manager.

Step 20 — Final Validation Checklist

The last step was validation.

We checked that the setup actually matched the design.

The checklist looked like this:

Management account
- Root MFA enabled
- No root access keys
- AWS Organizations enabled
- IAM Identity Center enabled
- Billing access configured
- Budgets created
Organization
- Workloads OU exists
- Dev account exists
- Prod account exists
- Accounts are in the correct OUIdentity
- Hamza user exists
- Ibrahim user exists
- Groups exist
- Permission sets exist
- Account assignments work
- MFA is configuredCost
- Organization budget exists
- Dev budget exists
- Prod budget exists
- Cost Explorer enabled

After this validation, Phase 1 was complete.

The Final Architecture After Phase 1

At the end of this phase, the Wilvor AWS foundation looked like this:

Wilvor AWS Organization
│
├── Wilvor Management Account
│   │
│   ├── AWS Organizations
│   ├── IAM Identity Center
│   ├── Billing
│   ├── Budgets
│   └── Account governance
│
└── Workloads OU
    │
    ├── Wilvor Development Account
    │   └── Future dev infrastructure
    │
    └── Wilvor Production Account
        └── Future production-style deployment

This gives Wilvor a clean base before the actual cloud architecture begins.

Now Dev and Prod are separated.

Users are managed centrally.

MFA is enabled.

Billing is visible.

Budgets are configured.

And the Management account is not polluted with application resources.

Insights

This phase helps understand that cloud architecture is not only about services like Lambda, Kinesis, DynamoDB, S3, or API Gateway.

Those services matter, but account structure comes first.

A weak foundation can make the rest of the architecture harder to manage.

The biggest lessons are:

  1. Separate environments by account, not by naming conventions only.
  2. Do not use root for daily work.
  3. IAM Identity Center is cleaner than creating IAM users in every account.
  4. Permission sets only work after account assignments.
  5. Billing access has its own root-level activation step.
  6. Budgets should be created before expensive services are deployed.
  7. Keep governance simple at the start and improve it step by step.

This setup may feel like extra work for a two-person project.

But it makes the project more professional.

It also makes future architecture decisions easier.

Why This Matters for Wilvor

Wilvor is not just a small script or dashboard.

The long-term vision includes real-time aviation data, weather intelligence, airport analysis, risk detection, recommendations, analytics, and eventually AI-assisted operations.

That kind of platform needs a serious cloud foundation.

The multi-account setup gives us room to grow.

Development can move fast.

Production can stay clean.

Billing can be tracked.

Access can be controlled.

And the architecture is easier to explain to engineers, recruiters, or anyone reviewing the project.

This is the kind of setup I wanted before building the actual AWS workload.

What Comes Next

Now that Phase 1 is complete, the next phase is infrastructure design.

The next major work will be:

  • Terraform setup
  • Remote Terraform state
  • Dev networking baseline
  • Prod networking baseline
  • VPC design
  • Private subnets
  • VPC endpoints
  • IAM roles
  • KMS keys
  • S3 buckets
  • DynamoDB tables
  • Kinesis streams
  • Lambda processors
  • EventBridge events
  • Monitoring and alerts

This is where Wilvor will start moving from account foundation into real platform infrastructure.

The account setup was the base layer.

The next layer is the secure AWS network and infrastructure.

Conclusion

This phase was not about writing application code.

It was about building the foundation correctly.

I created a production-style AWS organization for Wilvor with separate Management, Development, and Production accounts. I configured IAM Identity Center, created individual users, organized access with groups and permission sets, enabled MFA, fixed billing visibility, created budgets, and documented the final setup.

It took some time, and I did run into confusion around billing access.

But that is exactly why this phase was valuable.

Real cloud work is not only about knowing which button to click.

It is about understanding why the setup exists, what can go wrong, and how to build something that remains clean as the project grows.

Wilvor now has a proper AWS foundation.

The next step is to build the infrastructure on top of it.

If you enjoyed this article, feel free to connect with us and follow our Wilvor Journey:

🔗 LinkedIn 💻 GitHub


메타데이터
post_id
4fa085d07c1f
slug
designing-a-secure-multi-account-aws-setup-for-wilvor-aviation-operations-intelligence-platform-4fa085d07c1f
url
https://medium.com/@ibrahim.hamza01/designing-a-secure-multi-account-aws-setup-for-wilvor-aviation-operations-intelligence-platform-4fa085d07c1f
canonical_url
https://medium.com/@ibrahim.hamza01/designing-a-secure-multi-account-aws-setup-for-wilvor-aviation-operations-intelligence-platform-4fa085d07c1f
author_url
https://medium.com/@ibrahim.hamza01
status
ok
fetched_at
2026-06-28 10:39:35