gruntwork-io / website-comments

This repository captures all comments written in the guides
Other
1 stars 8 forks source link

guides/foundations/how-to-configure-production-grade-aws-account-structure/ #10

Open utterances-bot opened 4 years ago

utterances-bot commented 4 years ago

How to configure a production-grade AWS account structure using Gruntwork AWS Landing Zone

Learn about why you need multiple AWS accounts and how to create and manage them with a customizable security baseline defined in Terraform.

https://gruntwork.io/guides/foundations/how-to-configure-production-grade-aws-account-structure/

kylelundstedt commented 4 years ago

Nice update, Team Gruntwork!

Here's a bit of feedback on some items that probably got lost during the update.

  1. Found a minor typo in this section. When you document how to commit the "root account baseline wrapper module", your initial Git command is git add security/iam. I think you mean git add landingzone/account-baseline-root, or something to that effect.

  2. Also, throughout the Deployment Walkthrough section, you continually refer to the "security baseline" in the subsection headings and the paragraph text. However, all of the code examples, and the subject area of this Guide more broadly (i.e., account structure), refer to "account baseline" (i.e., account-baseline-root, account-baseline-security).

  3. Finally, Rob's nice blog post makes reference to Ben's work on the CIS Compliance offering, but I couldn't find any reference herein to that Compliance Guide. For example, in lieu of creating the IAM users in the security account as described above, you could refer to The Compliance Guide's section on SAML authentication. We use JumpCloud as our IDP for federated authentication, and the idea of zero IAM users across all of our AWS accounts has a lot of appeal!

kylelundstedt commented 4 years ago

Quick follow-up question. This guide creates the following child accounts - security, shared-services, dev, stage, and prod - which mirrors AWS's account structure from their Landing Zone solution. Do you feel like the other AWS child accounts (e.g., logs, network) make sense to create when using the Gruntwork IaC Library?

brikis98 commented 4 years ago

@robmorgan Could you respond to these when you get a chance?

robmorgan commented 4 years ago

Thanks @kylelundstedt, I'll take a look in more detail next week, but quickly:

Quick follow-up question. This guide creates the following child accounts - security, shared-services, dev, stage, and prod - which mirrors AWS's account structure from their Landing Zone solution. Do you feel like the other AWS child accounts (e.g., logs, network) make sense to create when using the Gruntwork IaC Library?

No, we suggest creating the account structure we have described (e.g: root, security, shared-services, dev, stage, prod). We suggest storing shared IAM resources and logs in the security account.

robmorgan commented 4 years ago

Hi @kylelundstedt,

I've implemented some of your typo fixes and we'll deploy them shortly. Thanks for the feedback about the mention of "account baseline" vs "security baseline". At this stage I prefer leaving the security baseline references, because I think they read better. e.g:

Learn about why you need multiple AWS accounts and how to create and manage them with a customizable security baseline defined in Terraform.

instead of

Learn about why you need multiple AWS accounts and how to create and manage them with a customizable account baseline defined in Terraform.

I'll check with the team and see if they have any opinion, otherwise I'll leave it for now and re-evaluate whether or not it makes sense in the future.

marshall7m commented 3 years ago

Thanks Gruntwork for the awesome info! I just have a quick question regarding the account-baseline-root module. I'm wondering how the module is able to provision the CloudTrail bucket and KMS within the logs account from the root AWS provider when the AWS logs account doesn't exists before running terraform commands on the module? Given that Terraform needs to know the provider before applying the infrastructure, I completely stumped on how this module performs this wizardry. If the answer to this question is something exclusive to Gruntwork subscribers, it would still wonderful if somebody can point me to the right resources/documentation to where I can learn how to do this. Thanks!

robmorgan commented 3 years ago

Hi @marshall7m, thanks for your question!

The short answer is that the solution is non-trivial and only available to Gruntwork customers with a paid subscription, however I’ll quickly explain how we manage to pull this off. We use AWS Organizations to create the child accounts and wait until all of the accounts are created. Then we go and find the ID of the logs account and assume a role in that account using a second AWS provider in order to create the S3 buckets (Note: a Terraform AWS provider can assume a role that is computed using variables) This is all achieved using a combination of Terraform provider blocks, null_resource resources and python scripts. It amounts to roughly ~220 lines of Terraform code with a lot of comments.

marshall7m commented 3 years ago

@robmorgan thanks for the reply!

Configuring the second AWS provider with the logs role did the trick! I overlooked the fact that providers could be configured via variables even within child modules.

robmorgan commented 3 years ago

@marshall7m not a problem!

marshall7m commented 3 years ago

@robmorgan If I could pick your brain one more time, I have one more question regarding the account-baseline-root module. I'm wondering, how does the module create account-level AWS Config for the dynamic map of var. child_accounts? Given that the caller of Terraform modules can't use for_each, count or depends_on when the provider is configured via variables, my current workaround is to dynamically generate a child AWS config module for each account in var.child_accounts via a .tpl file within a local_file resource. I'm hoping not to stick with this workaround since it required the user to apply terraform twice and goes against the principle of idempotence that Terraform is revolved around. Even the smallest bit of insight on how this process is reflected within the account-baseline-root module would be awesome to hear. Thanks!

UPDATE:

After doing more research, I've found that provisioning AWS Config at the organization level is possible without having to do the multi-step process of applying the org-level AWS config and then provisioning an AWS config recorder within each member account. Using the aws_config_organization_managed_rule resource did the trick.

worldofgeese commented 3 years ago

The patch command

terragrunt aws-provider-patch \
  --terragrunt-override-attr region="eu-west-1" \
  --terragrunt-override-attr assume_role.role_arn=""

needs to first auth against AWS else a user is likely to receive, ERRO[0008] Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?) as below:

 aws-vault exec root-iam-user -- terragrunt aws-provider-patch \
       --terragrunt-override-attr region="eu-west-1" \          
       --terragrunt-override-attr assume_role.role_arn=""       

In addition, the tutorial points to a deprecated repo since Terragrunt has moved to the service catalog for its modules and examples.

More generally, the examples are generally outdated: I frequently needed to reconcile its opinionated production-grade account examples with the more up to date https://github.com/gruntwork-io/terraform-aws-service-catalog/tree/master/examples/for-production/infrastructure-live that often uses quite divergent file paths from those in the documentation. I'd like to see the Reference Architecture reconciled with the documentation.

I really enjoy and appreciate the thoroughness of your tutorials, thank you!