Skip to main content
Knowledge Base

CIS Reference Architecture - GuardDuty being recreated with v0.38.0

Answer

I bumped my CIS Service Catalog version to v0.38.0 and have been presented with many recreations. The release notes have an example, but how does this look with the Reference Architecture? ```hcl // ... # module.security_baseline.module.guardduty[0].module.guardduty_sa_east_1.aws_guardduty_detector.guardduty[0] will be created + resource "aws_guardduty_detector" "guardduty" { + account_id = (known after apply) + arn = (known after apply) + enable = true + finding_publishing_frequency = (known after apply) + id = (known after apply) + tags_all = (known after apply) + datasources { + s3_logs { + enable = (known after apply) } } } # module.security_baseline.module.guardduty[0].module.guardduty_us_east_1.aws_guardduty_detector.guardduty[0] will be created + resource "aws_guardduty_detector" "guardduty" { + account_id = (known after apply) + arn = (known after apply) + enable = true + finding_publishing_frequency = (known after apply) + id = (known after apply) + tags_all = (known after apply) + datasources { + s3_logs { + enable = (known after apply) } } } # module.security_baseline.module.guardduty[0].module.guardduty_us_east_2.aws_guardduty_detector.guardduty[0] will be created + resource "aws_guardduty_detector" "guardduty" { + account_id = (known after apply) + arn = (known after apply) + enable = true + finding_publishing_frequency = (known after apply) + id = (known after apply) + tags_all = (known after apply) + datasources { + s3_logs { + enable = (known after apply) } } } # module.security_baseline.module.guardduty[0].module.guardduty_us_west_1.aws_guardduty_detector.guardduty[0] will be created + resource "aws_guardduty_detector" "guardduty" { + account_id = (known after apply) + arn = (known after apply) + enable = true + finding_publishing_frequency = (known after apply) + id = (known after apply) + tags_all = (known after apply) + datasources { + s3_logs { + enable = (known after apply) } } } # module.security_baseline.module.guardduty[0].module.guardduty_us_west_2.aws_guardduty_detector.guardduty[0] will be created + resource "aws_guardduty_detector" "guardduty" { + account_id = (known after apply) + arn = (known after apply) + enable = true + finding_publishing_frequency = (known after apply) + id = (known after apply) + tags_all = (known after apply) + datasources { + s3_logs { + enable = (known after apply) } } } // ... ``` --- <ins datetime="2023-05-19T12:35:04Z"> <p><a href="https://support.gruntwork.io/hc/requests/110188">Tracked in ticket #110188</a></p> </ins>

### Background If we check the release notes, https://github.com/gruntwork-io/terraform-aws-cis-service-catalog/releases/tag/v0.38.0, we see we need to do some `terraform state mv` work: >The Guardduty module call has been adjusted to be a count based module. This requires state migrations to avoid a recreation of the Guardduty resources. ... **account-baseline-security** >```hcl >terragrunt state mv module.security_baseline.module.guardduty 'module.security_baseline.module.guardduty[0]' >``` ## How to apply this to the Reference Architecture ### Generate a list of current resources represented in the remote state I took a list of all the resources to find out what the GuardDuty addresses looked like in the `terraform state` file: ```sh infrastructure-live-ian/security/_global/account-baseline $ aws-vault exec gruntwork-sales-security-02-admin -- terragrunt state list > 1.tmp ``` I see all my GuardDuty resources look something like this: ```hcl // ... module.security_baseline.module.guardduty.module.guardduty_eu_west_2.aws_guardduty_detector.guardduty[0] module.security_baseline.module.guardduty.module.guardduty_eu_west_3.aws_guardduty_detector.guardduty[0] module.security_baseline.module.guardduty.module.guardduty_sa_east_1.aws_guardduty_detector.guardduty[0] module.security_baseline.module.guardduty.module.guardduty_us_east_1.aws_guardduty_detector.guardduty[0] module.security_baseline.module.guardduty.module.guardduty_us_east_2.aws_guardduty_detector.guardduty[0] module.security_baseline.module.guardduty.module.guardduty_us_west_1.aws_guardduty_detector.guardduty[0] module.security_baseline.module.guardduty.module.guardduty_us_west_2.aws_guardduty_detector.guardduty[0] // ... ``` ### Note what needs to change The release notes imply this: ```hcl module.security_baseline.module.guardduty.module.guardduty_eu_west_2.aws_guardduty_detector.guardduty[0] ``` Should look like this (a `[0]` after the first mention of `guardduty`): ``` module.security_baseline.module.guardduty[0].module.guardduty_eu_west_2.aws_guardduty_detector.guardduty[0] ```` ### Note the total number of resources to be recreated In my case, it was `29` when I first ran my `terragrunt plan` after changing my CIS Service Catalog version to `v0.38.0`. ### Resolving the issue This is easy to write a small script for, but I picked the first region in the list I generated and did the `terragrunt state mv` manually to confirm it behaves as expected, and checked to see that my `terragrunt plan` once I've finished the `mv` shows only `28 to add`. The reason I want it to be `28` and not `29` is because that verifies I have successfully fixed the issue with GuardDuty detectors being needlessly recreated in every region I have listed in my `opt_in_regions` list, located here: https://github.com/gruntwork-io/terraform-aws-service-catalog/blob/master/examples/for-production/infrastructure-live/multi_region_common.hcl#L43. Here is the actual command I ran to do the `state mv` manually (note the quotes and needing to authenticate to AWS still): ``` (base) ~/tmp/infrastructure-live-ian/security/_global/account-baseline 127 $ aws-vault exec gruntwork-sales-security-02-admin -- terragrunt state mv 'module.security_baseline.module.guardduty.module.guardduty_ap_northeast_1.aws_guardduty_detector.guardduty[0]' 'module.security_baseline.module.guardduty[0].module.guardduty_ap_northeast_1.aws_guardduty_detector.guardduty[0]' ``` Once that is done, run a `terragrunt plan` and confirm the number of new resources to be created has decreased by one, and then double check the plan to ensure that the region you selected, `guardduty_ap_northeast_1`, in my case, does not show up. ### Additional If you're particularly paranoid, you could do a `terraform state pull` (which still requires authenticating to AWS) and point to a local copy first to test `plan` against, but that is probably overkill and would require more potentially dodgy hand-work.