'Separating Environments in AWS

Is there a best practice around separating environments in AWS?

I've got a solution that employs the following services:

  • Lambda
  • SNS
  • SQS
  • DyanmoDB
  • API Gateway
  • S3
  • IAM

We're not live yet, but we're getting close. By the time we go-live, I'd like a proper production, test, and development environment with a "reasonable" amount of isolation between them.

  1. Separate account per environment
  2. Single Account and separate VPC per environment

I read the article AWS NETWORKING, ENVIRONMENTS AND YOU by Charity Majors. I'm down with segmentation via VPC, but I don't know that all the services in my stack are VPC scoped? Here are some of my requirements:

  • Limit Service Name Collision (for non global services)
  • Establish a very clear boundary between environments
  • Eventually, grant permissions at the environment level

I am using an AWS Organization.

P.S. Apologies if this isn't the right forum for the question. If there is something better, just let me know and I'll move it.



Solution 1:[1]

I recommend one AWS account per environment. The reasons, in no particular order:

  1. security: managing complex IAM policies to create boundaries within a single account is really hard; conversely, one account per environment forces boundaries by default: you can enable cross account access but you have to be very deliberate
  2. auditing access to your different environments is more difficult when all activity happens in the same account
  3. performance: some services don't have the same performance characteristics when operating in VPC vs non-VPC (ie. Lambda cold starts increased latency when operating in VPC)
  4. naming: instead of using the AWS account id to identify the environment you're operating in, you have to add prefixes or suffixes to all the resources in the account - this is a matter of preference but nonetheless..
  5. compliance: if you ever need to adhere to some compliance standard such as HIPAA which imposes strict restrictions on how long you can hold on to data and who can access data, it becomes really difficult to prove which data is production and which data is test etc. (this goes back to #1 and #2 above)
  6. cost control: in dev, test, staging environments you may want to give people pretty wide permissions to spin up new resources but put low spending caps to prevent accidental usage spikes; conversely in a production account you'll want restricted ability to spin up resources but higher spending caps; easy to enforce via separate account - not so much in the same account

Did I miss anything? Possibly! But these are the reasons why I would use separate accounts.

By the way - I am NOT advocating against using VPCs. They exist for a reason and you should definitely use VPCs for network isolation. What I am trying to argue is that anybody who also uses other services such as DynamoDb, Lambda, SQS, S3 etc - VPCs are not really the way to isolate resources, IMO.

The downsides to one account per stage that I can think of are mostly around continuous deployment if you use tools that are not flexible enough to be able to deploy to different accounts.

Finally, some people like to call on billing as a possible issue but really, wouldn’t you want to know how much money you spend on Production vs Staging vs Development ?!

Solution 2:[2]

Avoid separate accounts for each environment to avoid additional complexity and obstacles in accessing shared resources. Try rather using:

Solution 3:[3]

The account separation is recommended by the AWS Well Architected Framework security pillar.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 marcinros
Solution 3 Francisco Cardoso