From b502e97c148fbf0a3f09cd28a3ff80ccd1587991 Mon Sep 17 00:00:00 2001 From: rho song Date: Wed, 16 Jun 2021 15:43:36 -0700 Subject: [PATCH 1/7] have users prepare their live repo --- ...w-to-achieve-cis-benchmark-compliance.adoc | 79 ++++++------------- 1 file changed, 25 insertions(+), 54 deletions(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index 8ad4d1644..e2b0d4bc5 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -846,6 +846,13 @@ If you need to brush up on how the IaC Library works, read the link:https://gruntwork.io/guides/foundations/how-to-use-gruntwork-infrastructure-as-code-library/[How to use the Gruntwork Infrastructure as Code Library] guide. + +=== Prepare your `infrastructure-live` repository + +We've previously described exactly how to prepare your repository in the +link:https://gruntwork.io/guides/foundations/how-to-configure-production-grade-aws-account-structure/#prepare-your-infrastructure-live-repository[Gruntwork Landing Zone guide]. +Follow the steps in that section to get your `infrastructure-live` repository set up for the next steps. + === Create the root account The first step is to create your root account. This account will be the parent of all of your other AWS accounts and @@ -960,7 +967,7 @@ structure to deploy Terraform modules. Please note that *Terragrunt is NOT requi for instructions on alternative options, such as how to link:/guides/foundations/how-to-use-gruntwork-infrastructure-as-code-library#deploy_using_plain_terraform[deploying how to use plain terraform]. -Next, create a `terragrunt.hcl` file in `infrastructure-live`. It should go under the file path `root/_global/account-baseline`: +Next, create a `terragrunt.hcl` file in `infrastructure-live`, under the file path `root/_global/account-baseline`: ---- infrastructure-live @@ -1198,7 +1205,7 @@ You should get JSON output with information about your IAM user: You're now almost ready to deploy the `account-baseline` module in the root account. But first, you may need to import some existing resources. -=== Import existing resources from the root account +=== Import existing resources from the root account into Terraform state Before applying the security baseline to the root account, we need to import any existing resources—including the IAM user you created manually earlier—into Terraform state, so that Terraform manages those existing resources instead of @@ -1214,7 +1221,7 @@ Where `
` is the https://www.terraform.io/docs/internals/resource-addres resource you're importing and `` is a resource-specific identifier (e.g., for `aws_instance`, it's the instance ID, whereas for `aws_lb`, it's the load balancer's name—check the docs for the resource to find out what to use). -As a first example, let's import the IAM user you created manually in the root account. IAM users are managed using the +Let's import the IAM user you created manually in the root account. IAM users are managed using the `aws_iam_user` resource, and the https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user#import[documentation for that resource] tells us to use the user's `name` as the ``; we'll assume for this example that your IAM user's name was @@ -1386,9 +1393,12 @@ cloudtrail_s3_bucket_name = "" config_s3_bucket_name = "" ---- -Take note of all of this data, as you'll need it again shortly! +If you followed the http://gruntwork.io/guides/foundations/how-to-configure-production-grade-aws-account-structure/#prepare-your-infrastructure-live-repository[steps for preparing your `infrastructure-live` repo], +now you can update the `accounts.json` file with the account IDs from the Terraform output! Also `account.hcl` files +located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), with the +appropriate account ID shown in the Terraform output. -One other useful output will be the encrypted passwords for any IAM users you created: +One other useful output are the encrypted passwords for IAM users you created: [source,hcl] ---- @@ -1466,17 +1476,8 @@ Set the variables for the `account-baseline-app` module in this environment in t [source,hcl] ---- locals { - aws_region = "us-east-1" - - accounts = { - logs = "409800740445" - security = "673123100581" - shared = "384759303421" - dev = "293847503945" - stage = "384924092834" - prod = "784260063686" - root = "216044045972" - } + # A local for more convenient access to the accounts map. + accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root config_s3_bucket_name = "acme-config-bucket-logs" @@ -1490,12 +1491,9 @@ locals { } inputs = { - # Fill in the region you want to use (only used for API calls) and the IDs of your AWS accounts (see the locals above) - aws_region = local.aws_region - aws_account_id = local.accounts.logs - # Prefix all resources with this name - name_prefix = "acme-logs" + name_prefix = "-logs" + ################################ # Parameters for AWS Config ################################ @@ -1732,17 +1730,7 @@ Set the variables for the `account-baseline-security` module in this environment [source,hcl] ---- locals { - aws_region = "us-east-1" - - accounts = { - logs = "409800740445" - security = "673123100581" - shared = "384759303421" - dev = "293847503945" - stage = "384924092834" - prod = "784260063686" - root = "216044045972" - } + accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root config_s3_bucket_name = "acme-config-bucket-logs" @@ -1755,12 +1743,8 @@ locals { security_account_root_arn = "arn:aws:iam::${local.accounts.security}:root" } input = { - # Fill in the region you want to use (only used for API calls) and the IDs of your AWS accounts (see the locals above) - aws_region = local.aws_region - aws_account_id = local.accounts.security - # Prefix all resources with this name - name_prefix = "acme-security" + name_prefix = "-security" ################################ # Parameters for AWS Config @@ -1813,7 +1797,7 @@ input = { # Allow these accounts to have read access to IAM groups and the public SSH keys of users in the group. allow_ssh_grunt_access_from_other_account_arns = [ for name, id in local.accounts : - "arn:aws:iam::${id}:root" if name != "security" + "arn:aws:iam::${id}:root" if name != "security" ] # A list of account root ARNs that should be able to assume the auto deploy role. @@ -2004,17 +1988,7 @@ Set the variables for the `account-baseline-app` module in this environment in t [source,hcl] ---- locals { - aws_region = "us-east-1" - - accounts = { - logs = "409800740445" - security = "673123100581" - shared = "384759303421" - dev = "293847503945" - stage = "384924092834" - prod = "784260063686" - root = "216044045972" - } + accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root config_s3_bucket_name = "acme-config-bucket-logs" @@ -2028,12 +2002,9 @@ locals { } inputs = { - # Fill in the region you want to use (only used for API calls) and the IDs of your AWS accounts (see the locals above) - aws_region = local.aws_region - aws_account_id = local.accounts.stage - # Prefix all resources with this name - name_prefix = "stage-logs" + name_prefix = "-logs" + ################################ # Parameters for AWS Config ################################ From 227fa040677d8fb985c7a49356bcaad9564b2561 Mon Sep 17 00:00:00 2001 From: rho song Date: Wed, 16 Jun 2021 15:50:41 -0700 Subject: [PATCH 2/7] More updates to references to accounts. --- ...how-to-achieve-cis-benchmark-compliance.adoc | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index e2b0d4bc5..907facde2 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -1004,24 +1004,17 @@ Set the variables for the `account-baseline-root` module in this environment in [source,hcl] ---- locals { - aws_region = "us-east-1" - - accounts = { - root = "216044045972" - } + # A local for more convenient access to the accounts map. + accounts = local.common_vars.locals.accounts - # Both buckets will created in the logs account by account-baseline-root + # Both buckets will be created in the logs account by account-baseline-root config_s3_bucket_name = "acme-config-bucket-logs" cloudtrail_s3_bucket_name = "acme-cloudtrail-logs" } inputs = { - # Fill in the region you want to use (only used for API calls) and the ID of your root AWS account (see the locals above) - aws_region = local.aws_region - aws_account_id = local.accounts.root - # Prefix all resources with this name - name_prefix = "acme-root" + name_prefix = "-root" # If you've already created an AWS Organization in your root account, set this to false create_organization = false @@ -1730,6 +1723,7 @@ Set the variables for the `account-baseline-security` module in this environment [source,hcl] ---- locals { + # A local for more convenient access to the accounts map. accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root @@ -1988,6 +1982,7 @@ Set the variables for the `account-baseline-app` module in this environment in t [source,hcl] ---- locals { + # A local for more convenient access to the accounts map. accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root From a02441524c2fd9094df541b96db36eec4273d341 Mon Sep 17 00:00:00 2001 From: rho song Date: Wed, 16 Jun 2021 16:05:02 -0700 Subject: [PATCH 3/7] Put more stuff in common.hcl --- ...w-to-achieve-cis-benchmark-compliance.adoc | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index 907facde2..fed98e426 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -1391,6 +1391,9 @@ now you can update the `accounts.json` file with the account IDs from the Terraf located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), with the appropriate account ID shown in the Terraform output. +Also add entries for `cloudtrail_kms_key_arn`, `cloudtrail_s3_bucket_name`, and `config_s3_bucket_name` into your +`infrastructure-live/common.hcl` file, because you'll need these values for every account in the steps below. + One other useful output are the encrypted passwords for IAM users you created: [source,hcl] @@ -1473,11 +1476,11 @@ locals { accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root - config_s3_bucket_name = "acme-config-bucket-logs" - cloudtrail_s3_bucket_name = "acme-cloudtrail-logs" + config_s3_bucket_name = local.common_vars.locals.config_s3_bucket_name + cloudtrail_s3_bucket_name = local.common_vars.locals.cloudtrail_s3_bucket_name # The Cloudtrail KMS Key is deployed at the logs account but it's value is an output from the root account. - cloudtrail_kms_key_arn = "arn:aws:kms:us-east-1:409800740445:alias/cloudtrail-acme" + cloudtrail_kms_key_arn = local.common_vars.locals.cloudtrail_kms_key_arn # A local for convenient access to the security account root ARN. security_account_root_arn = "arn:aws:iam::${local.accounts.security}:root" @@ -1727,11 +1730,11 @@ locals { accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root - config_s3_bucket_name = "acme-config-bucket-logs" - cloudtrail_s3_bucket_name = "acme-cloudtrail-logs" + config_s3_bucket_name = local.common_vars.locals.config_s3_bucket_name + cloudtrail_s3_bucket_name = local.common_vars.locals.cloudtrail_s3_bucket_name # The Cloudtrail KMS Key is deployed at the logs account but it's value is an output from the root account. - cloudtrail_kms_key_arn = "arn:aws:kms:us-east-1:216044045972:alias/cloudtrail-acme" + cloudtrail_kms_key_arn = local.common_vars.locals.cloudtrail_kms_key_arn # A local for convenient access to the security account root ARN. security_account_root_arn = "arn:aws:iam::${local.accounts.security}:root" @@ -1986,11 +1989,11 @@ locals { accounts = local.common_vars.locals.accounts # Both buckets are created in the logs account by account-baseline-root - config_s3_bucket_name = "acme-config-bucket-logs" - cloudtrail_s3_bucket_name = "acme-cloudtrail-logs" + config_s3_bucket_name = local.common_vars.locals.config_s3_bucket_name + cloudtrail_s3_bucket_name = local.common_vars.locals.cloudtrail_s3_bucket_name # The Cloudtrail KMS Key is deployed at the logs account but it's value is an output from the root account. - cloudtrail_kms_key_arn = "arn:aws:kms:us-east-1:409800740445:alias/cloudtrail-acme" + cloudtrail_kms_key_arn = local.common_vars.locals.cloudtrail_kms_key_arn # A local for convenient access to the security account root ARN. security_account_root_arn = "arn:aws:iam::${local.accounts.security}:root" From bf076ffc36e890b91255fa33f55cd601297b6a4f Mon Sep 17 00:00:00 2001 From: rho song Date: Wed, 16 Jun 2021 16:12:38 -0700 Subject: [PATCH 4/7] Wording. --- _posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index fed98e426..314f1b8e8 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -1391,7 +1391,7 @@ now you can update the `accounts.json` file with the account IDs from the Terraf located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), with the appropriate account ID shown in the Terraform output. -Also add entries for `cloudtrail_kms_key_arn`, `cloudtrail_s3_bucket_name`, and `config_s3_bucket_name` into your +Also update the entries for `cloudtrail_kms_key_arn`, `cloudtrail_s3_bucket_name`, and `config_s3_bucket_name` into your `infrastructure-live/common.hcl` file, because you'll need these values for every account in the steps below. One other useful output are the encrypted passwords for IAM users you created: From 05a8f0040405e034cc98e6488e4279d76dc6a069 Mon Sep 17 00:00:00 2001 From: rho song Date: Wed, 16 Jun 2021 16:18:15 -0700 Subject: [PATCH 5/7] Update one reference to infra-modules. --- .../2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index 314f1b8e8..7abf70a8b 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -1937,9 +1937,9 @@ Now that your security account is fully configured, you need to apply the securi accounts (e.g., dev, stage, prod, shared-services). Feel free to adjust this as necessary based on the accounts your company needs. -You can re-use the `account-baseline-app` module you created earlier in your `infrastructure-modules` repo for all of -these child accounts; this module can be used interchangeably between app accounts and log accounts as they deploy most -of the same resources. +The `account-baseline-app` module in the Service Catalog can be used interchangeably between app accounts and log +accounts as they deploy most of the same resources. That means this module can be re-used for all of the child +accounts. Create `terragrunt.hcl` files in `infrastructure-live` under the file paths `/_global/account-baseline`, where `` is one of these other child accounts, such as dev, stage, prod, and shared-services. In the rest of From a332164d047505ef74d7f1e623b34e2f6c274e2f Mon Sep 17 00:00:00 2001 From: Ina Date: Tue, 29 Jun 2021 18:51:46 +0100 Subject: [PATCH 6/7] Feedback from PR --- ...w-to-achieve-cis-benchmark-compliance.adoc | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index 7abf70a8b..5f449e621 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -1004,6 +1004,9 @@ Set the variables for the `account-baseline-root` module in this environment in [source,hcl] ---- locals { + + common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl")) + # A local for more convenient access to the accounts map. accounts = local.common_vars.locals.accounts @@ -1387,9 +1390,23 @@ config_s3_bucket_name = "" ---- If you followed the http://gruntwork.io/guides/foundations/how-to-configure-production-grade-aws-account-structure/#prepare-your-infrastructure-live-repository[steps for preparing your `infrastructure-live` repo], -now you can update the `accounts.json` file with the account IDs from the Terraform output! Also `account.hcl` files -located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), with the -appropriate account ID shown in the Terraform output. +now you can update the `accounts.json` file with the account IDs from the Terraform output! If you are instead making use of `account.hcl` files (located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), update them too with the +appropriate account ID shown in the Terraform output, so they look like: +[source,hcl] +---- +locals { + account_name = "" + account_id = "" +} + +---- + +[source,json] +---- +{ + "account_name": "" +} +---- Also update the entries for `cloudtrail_kms_key_arn`, `cloudtrail_s3_bucket_name`, and `config_s3_bucket_name` into your `infrastructure-live/common.hcl` file, because you'll need these values for every account in the steps below. From 68e8449a259d74392ae9e3b9dc3085d84a2c0c20 Mon Sep 17 00:00:00 2001 From: Ina Date: Wed, 30 Jun 2021 17:19:59 +0100 Subject: [PATCH 7/7] Feedback --- ...w-to-achieve-cis-benchmark-compliance.adoc | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc index 5f449e621..d365d1cbc 100644 --- a/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc +++ b/_posts/2019-10-17-how-to-achieve-cis-benchmark-compliance.adoc @@ -1384,13 +1384,12 @@ child_accounts = { # (...) } } -cloudtrail_kms_key_arn = "" + cloudtrail_s3_bucket_name = "" config_s3_bucket_name = "" ---- -If you followed the http://gruntwork.io/guides/foundations/how-to-configure-production-grade-aws-account-structure/#prepare-your-infrastructure-live-repository[steps for preparing your `infrastructure-live` repo], -now you can update the `accounts.json` file with the account IDs from the Terraform output! If you are instead making use of `account.hcl` files (located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), update them too with the +If you followed the http://gruntwork.io/guides/foundations/how-to-configure-production-grade-aws-account-structure/#prepare-your-infrastructure-live-repository[steps for preparing your `infrastructure-live` repo], now you can update the `account.hcl` with the account IDs from the Terraform output! If you are instead making use of `account.hcl` files (located in each account folder (e.g., `infrastructure-live/dev`, `infrastructure-live/shared`, etc.), update them too with the appropriate account ID shown in the Terraform output, so they look like: [source,hcl] ---- @@ -1408,10 +1407,34 @@ locals { } ---- -Also update the entries for `cloudtrail_kms_key_arn`, `cloudtrail_s3_bucket_name`, and `config_s3_bucket_name` into your +Note that we haven't specified any region here so far. If you're following the guide on how to prepare your `infrastructure-live` repo, you might have created previously files called `region.hcl` like below: + +[source, hcl] +---- +# Common variables for this region +locals { + # Automatically load common variables shared across all accounts + common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl")) + + # Automatically load account-level variables + account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl")) + + aws_region = "us-west-2" + state_bucket = "${local.common_vars.locals.name_prefix}-${local.account_vars.locals.account_name}-${local.aws_region}-tf-state" +} +---- + +Alternatively, you can add to your locals where necessary the following line, containing your choice of AWS regions: + +[source, hcl] +---- + aws_region = "us-west-2" +---- + +Now, that you have values for `cloudtrail_s3_bucket_name`, and `config_s3_bucket_name`, add them to your `infrastructure-live/common.hcl` file, because you'll need these values for every account in the steps below. -One other useful output are the encrypted passwords for IAM users you created: +Some of the terraform outputs to pay attention to, and maybe even store in a common configuration (like the `common.hcl` file), that you'll need later are: `cloudtrail_kms_key_arn` & the encrypted passwords for IAM users you created: [source,hcl] ----