Skip to content

How to handle correctly multi tenant flows in AWS?

0

Hi!

Regarding cloud management on AWS, I'm the only person on the team, and I also want to figure out, for now, what's the most manageable option for me, and whether, if we wanted to change the structure in the future, that's something that's commonly done or not. We have a project using the AWS CDK to manage the 3 environments we have in 3 different regions, which are: development, staging and production. For now the app versions are generic and work for everyone, but we need to start adapting the app for each client.

My questions are the following:

If I have everything in a single account, should I have different CDK projects in order to better manage the stacks per client? Or should I keep the CDK project I have, but organize everything by client and have different stacks per client? Or have common stacks per client, but separated by prefixes? In this case I would have everything isolated per client — their own VPC, their own database, their own S3 buckets, etc. But I'm not sure whether my our clients will be thrilled, so to speak, about having their data in a "shared" cloud, even though in reality their resources would be completely isolated from other clients.

If I have separate accounts, should I have one CDK project per client and per account? Or everything in one? I understand that everything in one is better because I don't have to create a repository per client, but operationally, having everything together in a single CDK perhaps leaves more room for error, and I don't want to run the risk of pushing one client's changes to another, or breaking one client's setup when I push changes to another client.

Regarding the backend: I have a backend with a microservices architecture. Right now I have the develop and main branches connected to their respective regions so that, when a push is made, it triggers the CodeBuild and the deployment based on the GitHub repo. To manage things by client, should I have different branches per client? Or should I split the backend structure at the client and profile level, and then, based on the profile and the CDK, trigger develop or main for one client or another?

2 Answers
1

Handling multi-tenant flows in AWS requires careful consideration of isolation, management complexity, and operational efficiency. Here are some approaches to consider for your situation:

Account and CDK Structure:

For multi-tenant architectures, you have several options depending on your isolation requirements:

If using a single account approach, you can maintain one CDK project but organize stacks by tenant. This reduces repository overhead while providing logical separation. You can use naming conventions, prefixes, or tags to distinguish tenant resources. Each tenant would have isolated resources (VPC, databases, S3 buckets) within the same account. This approach offers moderate operational complexity and allows you to share common infrastructure patterns while maintaining tenant boundaries through IAM policies, resource tagging, and role-based access control.

For separate accounts per tenant, you can still use a single CDK project that deploys to multiple accounts. AWS Organizations and service control policies help enforce governance across accounts. This provides maximum isolation and can address client concerns about data separation, as each tenant operates in a completely separate AWS account. You can use AWS Resource Access Manager to securely share capabilities across accounts when needed.

Managing Deployment Risk:

To minimize the risk of deploying one client's changes to another, consider:

  • Using environment variables and configuration files to differentiate tenant deployments
  • Implementing approval gates and testing stages in your CI/CD pipeline
  • Leveraging AWS AppConfig for dynamic, tenant-specific configuration management
  • Creating separate deployment pipelines per tenant while sharing the same codebase

Backend Architecture:

For your microservices backend, avoid creating separate branches per client as this becomes difficult to maintain. Instead:

  • Use configuration-based approaches where tenant-specific behavior is controlled through parameters
  • Implement tenant-aware routing and configuration at the application level
  • Use feature flags or capability toggling to enable/disable functionality per tenant
  • Maintain develop and main branches for your core application, with tenant customization handled through configuration rather than code branching

Scalability Considerations:

As you grow, consider building your deployment as a service where tenant provisioning becomes automated. Use centralized policy engines and unified observability layers where telemetry is aggregated by tenant context. This transforms your infrastructure from static deployment to dynamic provisioning, making it more scalable as you add clients.

Migration Path:

Changing your multi-tenant structure in the future is possible but requires planning. Starting with a well-organized single-account approach with clear tenant boundaries makes it easier to migrate to separate accounts later if needed. The key is maintaining consistent patterns and avoiding hard-coded tenant-specific logic in your infrastructure code.

For your immediate situation as a solo operator, a single CDK project with tenant-organized stacks in one account offers the best balance of manageability and isolation, with the flexibility to evolve as your needs change.
Sources
Focus area 3: Architect for multi-tenancy and control - AWS Prescriptive Guidance
AWS Glossary - SaaS Tenant Isolation Strategies: Isolating Resources in a Multi-Tenant Environment

answered 4 days ago
EXPERT
reviewed 4 days ago
1

While the previous response outlines the architectural options well, I would like to add some practical advice for your situation as a solo developer:

1. Managing Infrastructure via CDK 'Stages' Instead of creating multiple projects or managing complex Git branching strategies, leverage CDK Stages. You can keep a single codebase and instantiate your stacks per tenant by passing in a configuration object (props). This allows you to deploy to ClientA or ClientB by simply targeting their specific stage, keeping your infrastructure code DRY (Don't Repeat Yourself) while ensuring complete resource isolation.

2. Avoid 'Branch-per-Client' The suggestion to avoid separate branches is critical. Maintaining code across multiple branches will quickly become an operational nightmare, especially when you need to deploy a security patch or a global feature update. Stick to a 'main/develop' strategy and manage client-specific differences through external configuration files (e.g., a tenants.json or dynamic values stored in AWS AppConfig).

3. The 'Single Account' Starting Point As a solo developer, starting with a single account is perfectly fine and highly manageable, provided you use strict naming conventions and tags for your resources. This approach gives you the operational simplicity you need today. Because you are using CDK, you can easily 'lift and shift' a tenant’s entire stack into a separate, dedicated AWS account in the future if a specific client requires it for compliance or security reasons.

4. Tenant-Aware Microservices On the backend side, design your services to be 'tenant-aware' from the start. Your microservices should receive a tenant_id context (passed via headers or tokens) to handle logic. This is generally much easier to maintain than splitting your backend deployment structure based on client profiles.

Summary for your roadmap: Start with one account + CDK Stages + Configuration-as-Code. This strikes the best balance between isolation for your clients and your ability to manage the environment effectively alone."

EXPERT
answered 4 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.