If you’re building multiple projects or apps on AWS, you will need an approach to keep each one separate. Whether you’re developing websites for different clients or disparate products within a single organisation, you need to protect against:

  • Traffic bursts in minor apps bringing down mission-critical ones.
  • Developers reusing security groups and deciding to open 1 more port to get their new app working.
  • Releases being accidentally deployed to the wrong website.
  • A large monthly bill and no idea which app has caused it.
  • Developers having unauthorised access to certain client’s data.

There are a few potential approaches you could take:

  1. Use a naming convention and tags
  2. Isolate projects via separate VPC and IAM groups
  3. Completely separate accounts for each app

Let’s look at these in a bit more detail…

Approach #1 – Separation by Naming Convention and Tags

This approach involves adopting a convention whereby you prefix each resource name with an abbreviated version of the app or project’s name.

Pros

  • Developers only need a single set of login credentials to connect to the AWS Console and CLI
  • Team members can clearly identify what each resource is intended for
  • Itemised per-app billing is available through use of cost allocation tags

Cons

  • Long resource names
  • Enforcing convention across a team is difficult to police
  • Easy to forget to assign a allocation tag when creating a resource, making cost analysis difficult
  • Compute resources such as EC2 instances are not isolated by default
  • No enforced access control

Approach #2 – Separation by VPC and IAM role

This approach involves creating a separate Virtual Private Cloud (VPC) for each project and using IAM Groups to restrict access to project-specific resources to certain groups of users.

Pros

  • Application-specific EC2 and RDS instances are isolated at a network level so cannot interfere with each other
  • Access control is enforceable per team member
  • Developers only need a single set of login credentials to connect to the AWS Console and CLI

Cons

Approach #3 – Separation by AWS Account

This involves creating a totally separate AWS account for each project. Within each account, the root user would need to create an IAM user for each team member working on the project.

Pros

  • All resources are completely isolated, so no risk of interference
  • Team member access control is provided by default simply by being added to the account
  • Consolidated billing is available via AWS Organisations for no extra charge, so you don’t need to pay each project’s bill separately
  • Credit card isn’t required for creating individual accounts under a pre-existing master organisation
  • If a project’s owner is changed (e.g. an app is sold), it is trivial to transfer the account ownership
  • AWS Free Tier discounts are spread out across all accounts in an organisation

Cons

  • One-time setup is slightly more involved:
    • A master account needs to be created and associated to a credit card (for AWS Organisations) and a master account user with Create Account permission (or the master root user) is needed to create new accounts
    • IAM users and associated groups/policies need to be created for each developer per project
    • If you use CloudTrail to audit account activity, you will need to set this up for each account
  • Developers need to maintain separate logins for each project account and to log out and back in to the Console whenever they switch projects (or use separate browsers or Chrome profiles)

Despite the extra upfront effort in setting up a new account, approach #3 is what I would generally recommend. In fact, I find the overhead forces you to consider using infrastructure automation (e.g. through CloudFormation or Terraform) if you’re setting up new accounts relatively frequently, which is definitely a good practice to adopt instead of relying on the AWS Console to configure everything.

But isn’t separate accounts overkill for teams of 1?

Whilst access control isn’t an issue when it’s just you working on a project, co-hosting apps within the same account still makes them vulnerable to issues caused by competing for compute or network resources. It also means that transferring ownership down the line will involve the upheaval of recreating resources in a new account – much easier to kept them separate from the start.

That said, I would make a few exceptions:

  • If you’re creating purely static websites using S3 and CloudFront, then you can probably get away with Approach #1.
  • If you want to optimise costs by hosting multiple disparate apps on the same single EC2 instance and don’t care for isolation, then you can get away with co-hosting.

Caution: NEVER use the email address associated with an existing personal Amazon.com account for your root login as there is currently no way of disconnecting it from the AWS account, despite Amazon being aware of the issue for at least 6 years. This means if you ever need to transfer ownership of your AWS account, you either have to migrate all resources into a new AWS account (very risky for a production system) or make peace with transferring all your personal Amazon.com and Kindle purchase history to the new owner! This is particularly pertinent to freelancers starting side-projects which they may some day wish to sell.

In Summary

  • Create separate accounts for each project unless you’re building purely static websites and don’t care about enforcing per-project access control.
  • Create IAM users (as per AWS recommended best practice) for every team member working on the project.
  • If you’re in an organisation with a need to regularly create new projects, consider setting up AWS Organisations to help automate account creation using secure defaults.
  • Don’t use personal email addresses when creating a root account if it’s already linked to an Amazon.com commerce account.

Comments