diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory-async/control-tower-account-factory-async.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory-async/control-tower-account-factory-async.md new file mode 100644 index 0000000000..386967e560 --- /dev/null +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory-async/control-tower-account-factory-async.md @@ -0,0 +1,554 @@ +--- +title: "Control Tower Account Factory Async" +hide_title: true +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; +import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; +import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; + + + +# Control Tower Account Factory Async + +View Source + +Release Notes + +This is a OpenTofu/Terraform module that will trigger the creation of a new AWS account by using Control Tower. This module differs from [control-tower-account-factory](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.8/modules/control-tower-account-factory) by introducing an [asynchrous pattern](#asynchrous-pattern) to help better handle certain types of drift. + +Under the hood, this module uses AWS Service Catalog to trigger Control Tower, as Control Tower does not currently expose any APIs to trigger it directly. + +## Asynchrous Pattern + +To support this asynchronous pattern, this module uses a lifecycle block to ignore changes to the `provisioning_artifact_id` attribute of the underlying Service Catalog `aws_servicecatalog_provisioned_product` resource. This prevents OpenTofu/Terraform from trying to update the resource directly, which would otherwise result in a long-running operation or potential failure. + +This separation of detection and execution ensures better resilience, speed, and scalability. + +## Control Tower Service Catalog YAML + +The below YAML is copied from the Control Tower product in AWS Service Catalog. It is useful in knowing what parameters to pass to this Service Catalog product: + +*Note: some of the data below (e.g., the `AllowedValues` for `ManagedOrganizationalUnit`) is auto-generated for each AWS organization, so it will vary from org to org.* + +```yaml +AWSTemplateFormatVersion: 2010-09-09 +Description: AWS Control Tower Account Factory Template (DO NOT DELETE) +Parameters: + AccountName: + Description: "Account name, the new managed Account will be created with this name." + Type: String + AllowedPattern : ".+" + AccountEmail: + Description: "Account email, must be unique for each AWS Account." + Type: String + AllowedPattern : "[^\\s@]+@[^\\s@]+\\.[^\\s@]+" + SSOUserFirstName: + Description: "SSO user first name." + Type: String + AllowedPattern : ".+" + SSOUserLastName: + Description: "SSO user last name." + Type: String + AllowedPattern : ".+" + SSOUserEmail: + Description: "SSO user email. A new SSO user will be created for this email, if it does not exist. This SSO user will be associated with the new managed Account." + Type: String + AllowedPattern : "[^\\s@]+@[^\\s@]+\\.[^\\s@]+" + ManagedOrganizationalUnit: + Description: "Your account will be added to this registered organizational unit. The list includes top-level and nested OUs registered with AWS Control Tower. You can search for an OU by name or ID. To manage these OUs, go to AWS Control Tower." + Type: String + AllowedValues: + - XXX (ou-abcd-12345678) + - YYY (ou-abcd-91011121) + - ZZZ (ou-abcd-34151617) +Resources: + WaitCondition: + Type: AWS::CloudFormation::WaitCondition + Properties: + Handle: WaitHandle + Timeout: 1 + WaitHandle: + Type: AWS::CloudFormation::WaitConditionHandle +``` + +## Troubleshooting Tips + +### `ResourceInUseException` + +If you attempt to create/update/remove too many accounts from ControlTower at once, you may encounter an error in Service Catalog that looks like this: + +```log +ResourceInUseException: Account Factory cannot complete an operation on this account, because the allowed maximum of 5 concurrent account operations is exceeded. Try again later. +``` + +This is usually accompanied by this module returning outputs that look like the following: + +```text +"account_email" = "(could not get email associated with account)" +``` + +Unfortunately, this is an unrecoverable error from an AWS Provider perspective, as the provider has no insight into the fact that Service Catalog is in a bad state when it fails in this fashion, and retries will not help. + +The easiest way to recover from this error is to make a small update to one of the variables that are passed into this module. For example, if you are integrating with this module via the [../control-tower-multi-account-factory](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.8/modules/control-tower-multi-account-factory) module, you could change the value of something in the relevant file in the directory referenced by the `account_requests_folder`, then revert your change. + +e.g. + +```yml +sso_user_first_name: "John" +sso_user_last_name: "Doe" +``` + +to + +```yml +sso_user_first_name: "Jane" +sso_user_last_name: "Doe" +``` + +Perform an apply, then revert the change for another apply. + +This workaround should only be done to correct up to five Service Catalog provisioned products at a time. + +## Sample Usage + + + + +```hcl title="main.tf" + +# ------------------------------------------------------------------------------------------------------ +# DEPLOY GRUNTWORK'S CONTROL-TOWER-ACCOUNT-FACTORY-ASYNC MODULE +# ------------------------------------------------------------------------------------------------------ + +module "control_tower_account_factory_async" { + + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-factory-async?ref=v0.8.8" + + # ---------------------------------------------------------------------------------------------------- + # REQUIRED VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # Account email, must be globally unique across all AWS Accounts. + account_email = + + # The name to use for the new AWS account + account_name = + + # The name of the organizational unit (OU) in which this account should be + # created. Must be one of the OUs in your Control Tower dashboard. + organizational_unit_name = + + # The list of organizational units (OUs) in which to look for the specified + # organizational_unit_name. The module will look for the OU with the specified + # name in this list. + ous = + + # The email address of the user who will be granted admin access to this new + # account through AWS SSO. + sso_user_email = + + # The first name of the user who will be granted admin access to this new + # account through AWS SSO. + sso_user_first_name = + + # The last name of the user who will be granted admin access to this new + # account through AWS SSO. + sso_user_last_name = + + # ---------------------------------------------------------------------------------------------------- + # OPTIONAL VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # If specified, this is assumed to be the file path of a YAML file where the + # details of the new account created by this module will be written (if the + # file already exists, the module will merge its data into the file). The + # expected format of this YAML file is that the keys are the account names and + # the values are objects with the following keys: id (the account ID), email + # (the root user email address for the account). + accounts_yaml_path = null + + # The amount of time allowed for the create operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + create_operation_timeout = "60m" + + # The amount of time allowed for the delete operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + delete_operation_timeout = "60m" + + # The amount of time allowed for the read operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + read_operation_timeout = "20m" + + # A map of tags to apply to the new account. + tags = {} + + # The amount of time allowed for the update operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + update_operation_timeout = "60m" + +} + + +``` + + + + +```hcl title="terragrunt.hcl" + +# ------------------------------------------------------------------------------------------------------ +# DEPLOY GRUNTWORK'S CONTROL-TOWER-ACCOUNT-FACTORY-ASYNC MODULE +# ------------------------------------------------------------------------------------------------------ + +terraform { + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-factory-async?ref=v0.8.8" +} + +inputs = { + + # ---------------------------------------------------------------------------------------------------- + # REQUIRED VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # Account email, must be globally unique across all AWS Accounts. + account_email = + + # The name to use for the new AWS account + account_name = + + # The name of the organizational unit (OU) in which this account should be + # created. Must be one of the OUs in your Control Tower dashboard. + organizational_unit_name = + + # The list of organizational units (OUs) in which to look for the specified + # organizational_unit_name. The module will look for the OU with the specified + # name in this list. + ous = + + # The email address of the user who will be granted admin access to this new + # account through AWS SSO. + sso_user_email = + + # The first name of the user who will be granted admin access to this new + # account through AWS SSO. + sso_user_first_name = + + # The last name of the user who will be granted admin access to this new + # account through AWS SSO. + sso_user_last_name = + + # ---------------------------------------------------------------------------------------------------- + # OPTIONAL VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # If specified, this is assumed to be the file path of a YAML file where the + # details of the new account created by this module will be written (if the + # file already exists, the module will merge its data into the file). The + # expected format of this YAML file is that the keys are the account names and + # the values are objects with the following keys: id (the account ID), email + # (the root user email address for the account). + accounts_yaml_path = null + + # The amount of time allowed for the create operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + create_operation_timeout = "60m" + + # The amount of time allowed for the delete operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + delete_operation_timeout = "60m" + + # The amount of time allowed for the read operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + read_operation_timeout = "20m" + + # A map of tags to apply to the new account. + tags = {} + + # The amount of time allowed for the update operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + update_operation_timeout = "60m" + +} + + +``` + + + + + + + +## Reference + + + + +### Required + + + + +Account email, must be globally unique across all AWS Accounts. + + + +
+ + +```hcl + + AWS requires that the account email is less than or equal to 64 characters + +``` +
+ +
+
+ + + + +The name to use for the new AWS account + + + +
+ + +```hcl + + AWS requires the account name to be at most 50 characters: https://docs.aws.amazon.com/organizations/latest/APIReference/API_Account.htmlorganizations-Type-Account-Name + However, we use the account name as part of an S3 bucket name, along with a --tf-state suffix, which adds up to ~25 characters. + S3 bucket names are limited to 63 characters: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html + So, 63 - 25 = 38, so to be on the safe side, that's the limit we enforce here. + +``` +
+ +
+
+ + + + +The name of the organizational unit (OU) in which this account should be created. Must be one of the OUs in your Control Tower dashboard. + + + + + + + +The list of organizational units (OUs) in which to look for the specified organizational_unit_name. The module will look for the OU with the specified name in this list. + + + + +```hcl +list(object({ + id = string + name = string + })) +``` + + + + + + + +The email address of the user who will be granted admin access to this new account through AWS SSO. + + + + + + + +The first name of the user who will be granted admin access to this new account through AWS SSO. + + + + + + + +The last name of the user who will be granted admin access to this new account through AWS SSO. + + + + +### Optional + + + + +If specified, this is assumed to be the file path of a YAML file where the details of the new account created by this module will be written (if the file already exists, the module will merge its data into the file). The expected format of this YAML file is that the keys are the account names and the values are objects with the following keys: id (the account ID), email (the root user email address for the account). + + + + + + + + +The amount of time allowed for the create operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + +The amount of time allowed for the delete operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + +The amount of time allowed for the read operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + +A map of tags to apply to the new account. + + + + + + + + +The amount of time allowed for the update operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + +
+ + + + + +The email address of the newly created account + + + + + + + +The ID of the newly created account + + + + + + + +Current provisioning_artifact_id + + + + + + + +Detected provisioning_artifact_id + + + + + + + +The ID of the Organizational Unit (OU) this account was created in. + + + + + + + + + + +The ARN of the Service Catalog product that was provisioned to trigger Control Tower + + + + + + + +The ID of the Service Catalog product that was provisioned to trigger Control Tower + + + + + + + +The outputs of the Service Catalog product that was provisioned to trigger Control Tower + + + + + + + +The email address of the user that has been granted admin access via AWS SSO in this account + + + + + + + +The URL of the AWS SSO login page for this account + + + + + +
+ + diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory/control-tower-account-factory.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory/control-tower-account-factory.md index 6227d703de..6555d959af 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory/control-tower-account-factory.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-account-factory/control-tower-account-factory.md @@ -9,13 +9,13 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Control Tower Account Factory -View Source +View Source -Release Notes +Release Notes This is a Terraform module that will trigger the creation of a new AWS account by using Control Tower. @@ -89,7 +89,7 @@ This is usually accompanied by this module returning outputs that look like the Unfortunately, this is an unrecoverable error from an AWS Provider perspective, as the provider has no insight into the fact that Service Catalog is in a bad state when it fails in this fashion, and retries will not help. -The easiest way to recover from this error is to make a small update to one of the variables that are passed into this module. For example, if you are integrating with this module via the [../control-tower-multi-account-factory](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.7/modules/control-tower-multi-account-factory) module, you could change the value of something in the relevant file in the directory referenced by the `account_requests_folder`, then revert your change. +The easiest way to recover from this error is to make a small update to one of the variables that are passed into this module. For example, if you are integrating with this module via the [../control-tower-multi-account-factory](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.8/modules/control-tower-multi-account-factory) module, you could change the value of something in the relevant file in the directory referenced by the `account_requests_folder`, then revert your change. e.g. @@ -122,7 +122,7 @@ This workaround should only be done to correct up to five Service Catalog provis module "control_tower_account_factory" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-factory?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-factory?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -233,7 +233,7 @@ module "control_tower_account_factory" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-factory?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-factory?ref=v0.8.8" } inputs = { @@ -590,11 +590,11 @@ The URL of the AWS SSO login page for this account diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-account-tagger/control-tower-account-tagger.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-account-tagger/control-tower-account-tagger.md index f8675f6ce0..7b1f90a3dd 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-account-tagger/control-tower-account-tagger.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-account-tagger/control-tower-account-tagger.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Control Tower Account Tagger -View Source +View Source Release Notes @@ -62,7 +62,7 @@ This module assume that the account is managed by AWS Control Tower and has two module "control_tower_account_tagger" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-tagger?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-tagger?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -103,7 +103,7 @@ module "control_tower_account_tagger" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-tagger?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-account-tagger?ref=v0.8.8" } inputs = { @@ -143,11 +143,11 @@ inputs = { diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-app-account-baseline/control-tower-app-account-baseline.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-app-account-baseline/control-tower-app-account-baseline.md index 814198b3b1..f7bf088dde 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-app-account-baseline/control-tower-app-account-baseline.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-app-account-baseline/control-tower-app-account-baseline.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Account Baseline App with Control Tower Integration -View Source +View Source Release Notes @@ -40,7 +40,7 @@ Once you assume the `AWSControlTowerExecution` role, you should be able to compl module "control_tower_app_account_baseline" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-app-account-baseline?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-app-account-baseline?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -694,7 +694,7 @@ module "control_tower_app_account_baseline" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-app-account-baseline?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-app-account-baseline?ref=v0.8.8" } inputs = { @@ -2903,11 +2903,11 @@ A map of ARNs of the service linked roles created from diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-controls/control-tower-controls.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-controls/control-tower-controls.md index 6ee232fdb9..3b01cf1f95 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-controls/control-tower-controls.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-controls/control-tower-controls.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Control Tower Controls -View Source +View Source Release Notes @@ -36,7 +36,7 @@ For a full list of preventive, detective and proactive controls, see the [AWS Co module "control_tower_controls" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-controls?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-controls?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -72,7 +72,7 @@ module "control_tower_controls" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-controls?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-controls?ref=v0.8.8" } inputs = { @@ -107,11 +107,11 @@ inputs = { diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-execution-role/control-tower-execution-role.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-execution-role/control-tower-execution-role.md index 009b704dc9..298f0422fc 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-execution-role/control-tower-execution-role.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-execution-role/control-tower-execution-role.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Control Tower Execution Role -View Source +View Source Release Notes @@ -36,7 +36,7 @@ https://docs.aws.amazon.com/controltower/latest/userguide/enroll-account.html module "control_tower_execution_role" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-execution-role?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-execution-role?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -62,7 +62,7 @@ module "control_tower_execution_role" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-execution-role?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-execution-role?ref=v0.8.8" } inputs = { @@ -119,11 +119,11 @@ The ARN of the Control Tower Execution Role diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-landing-zone/control-tower-landing-zone.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-landing-zone/control-tower-landing-zone.md index 1a680d0d55..fd49380f6a 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-landing-zone/control-tower-landing-zone.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-landing-zone/control-tower-landing-zone.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Control Tower Landing Zone -View Source +View Source Release Notes @@ -117,7 +117,7 @@ The goal of the import is to have a plan with no operations to be performed. If module "control_tower_landing_zone" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-landing-zone?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-landing-zone?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -218,7 +218,7 @@ module "control_tower_landing_zone" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-landing-zone?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-landing-zone?ref=v0.8.8" } inputs = { @@ -544,11 +544,11 @@ The amount of time allowed for the update operation to take before being conside diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory-async/control-tower-multi-account-factory-async.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory-async/control-tower-multi-account-factory-async.md new file mode 100644 index 0000000000..0fc4bd6f80 --- /dev/null +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory-async/control-tower-multi-account-factory-async.md @@ -0,0 +1,515 @@ +--- +title: "Control Tower Multi-Account Factory Async" +hide_title: true +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; +import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; +import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; + + + +# Control Tower Multi-Account Factory Async + +View Source + +Release Notes + +This OpenTofu/Terraform module provisions multiple AWS accounts using AWS Control Tower Account Factory. Under the hood, it leverages the [control-tower-account-factory-async](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.8/modules/control-tower-account-factory-async) module for account creation. It also includes a separate mechanism to detect and remediate drifted or outdated AWS Service Catalog products asynchronously, outside of OpenTofu/Terraform, using an EventBridge rule, SQS, Lambda, and AWS Step Functions. + +## Background and Justification + +The standard synchronous approach to provisioning or updating AWS accounts via Control Tower can lead to lengthy OpenTofu/Terraform runs, especially when Control Tower APIs are slow or when updating a large number of accounts. More importantly, certain types of "drift" caused by Control Tower changes are difficult to reconcile using OpenTofu/Terraform alone. + +This module takes an asynchronous approach by deploying infrastructure (EventBridge, SQS, Lambda, and AWS Step Functions) that monitors for certain API calls. When relevant API calls are made (`UpdateProvisioningArtifact` and `UpgradeProduct`), the Lambda is triggered to complete the update process independently of OpenTofu/Terraform. + +This leads to: + +* Faster OpenTofu/Terraform applies +* More scalable update workflows +* Improved handling of state drift + +## Why remediate provisioned_product_id drift? + +In AWS Control Tower, certain changes made via the AWS Console or APIs result in drift from the OpenTofu/Terraform state. For example: + +* Moving an account to a new Organizational Unit (OU) +* Updating the Account Factory product version +* Modifying Service Catalog configurations + +These actions change the `provisioned_product_id`, which causes OpenTofu/Terraform to report drift. Left unresolved, this will make your infrastructure state inconsistent. Since the AWS Provider drives all changes to your Service Catalog provisioned products via updates to the `provisioned_product_id`, the value needs to be up to date to continue making changes to it. + +By queuing and applying these updates asynchronously: + +* The drift is remediated safely and automatically +* The Control Tower changes are reflected in your environment +* You avoid the overhead and risk of long-running OpenTofu/Terraform changes + +## How It Works + +* EventBridge Rule: Listens via CloudTrail for UpdateProvisioningArtifact or UpgradeProduct API calls. +* Ingest Lambda: Triggered by the EventBridge rule, it finds all provisioned products that need an update and queues them in an SQS FIFO queue. This ensures order and prevents race conditions. +* SQS Queue: Serves as a reliable, asynchronous work queue. It is configured as a FIFO queue with content-based deduplication and a Dead-Letter Queue (DLQ). +* Worker Lambda: Triggered by messages from the SQS queue, it applies the necessary provisioned_product_id updates by calling UpdateProvisionedProduct. It then initiates an AWS Step Functions state machine to track the update. +* AWS Step Functions state machine: Periodically checks the status of the Service Catalog update record to verify that it has succeeded or failed, ensuring the update is fully completed. + +### Controlling Concurrency + +AWS Service Catalog currently enforces a [hard limit of 5 account-related operations concurrently](https://docs.aws.amazon.com/controltower/latest/userguide/provision-and-manage-accounts.html#:~:text=You%20can%20perform%20up%20to%20five%20\(5\)%20account%2Drelated%20operations%20concurrently%2C%20including%20provisioning%2C%20updating%2C%20and%20enrolling.) that includes provisioning, updating, and enrolling. Exceeding this limit may result in throttling errors or failed updates. + +To respect this limitation and offer flexibility, this module provides a configurable variable `lambda_worker_max_concurrent_operations` that governs how many updates will be performed in parallel. While the upper limit is 5 (per AWS constraints), setting it lower may be preferred in environments where other Service Catalog actions must occur concurrently (such as provisioning new accounts). This ensures that background remediation work does not block critical operations or trigger rate limiting. + +## Sample Usage + + + + +```hcl title="main.tf" + +# ------------------------------------------------------------------------------------------------------ +# DEPLOY GRUNTWORK'S CONTROL-TOWER-MULTI-ACCOUNT-FACTORY-ASYNC MODULE +# ------------------------------------------------------------------------------------------------------ + +module "control_tower_multi_account_factory_async" { + + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-multi-account-factory-async?ref=v0.8.8" + + # ---------------------------------------------------------------------------------------------------- + # REQUIRED VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # The absolute path to the folder to look for new account request files. Each + # file should be named account-.yml, where NAME is the name of an + # account to create. Within the YAML file, you must define the following + # fields: account_email (Account email, must be globally unique across all AWS + # Accounts), sso_user_first_name (The first name of the user who will be + # granted admin access to this new account through AWS SSO), + # sso_user_last_name (The last name of the user who will be granted admin + # access to this new account through AWS SSO), sso_user_email (The email + # address of the user who will be granted admin access to this new account + # through AWS SSO), organizational_unit_name (The name of the organizational + # unit or OU in which this account should be created—must be one of the OUs + # enrolled in Control Tower). + account_requests_folder = + + # ---------------------------------------------------------------------------------------------------- + # OPTIONAL VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # If specified, this is assumed to be the absolute file path of a YAML file + # where the details of the new accounts created by this module will be written + # (if the file already exists, the module will merge its data into the file). + # The expected format of this YAML file is that the keys are the account names + # and the values are objects with the following keys: id (the account ID), + # email (the root user email address for the account). + accounts_yaml_path = null + + # The amount of time allowed for the create operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + create_operation_timeout = "60m" + + # The amount of time allowed for the delete operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + delete_operation_timeout = "60m" + + # If set to true, this module will look for the specified organizational unit + # (OU) recursively under the root of the organization. If set to false, it + # will only look for the OU directly under the root. This is useful if you + # have nested OUs and want to create accounts in a child OU. + discover_ous_recursively = false + + # KMS key for encrypting ingest lambda log group + lambda_ingest_kms_key_id = null + + # Number of days to retain logs for ingest lambda functions + lambda_ingest_log_retention_in_days = 30 + + # Sets the memory_size in MB for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_memory_size = 256 + + # Sets the timeout in seconds for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_timeout = 900 + + # KMS key for encrypting worker lambda log group + lambda_worker_kms_key_id = null + + # Number of days to retain logs for worker lambda functions + lambda_worker_log_retention_in_days = 30 + + # Service Catalog supports a maximum of 5 account updates currently. This + # variable controls the maximum concurrent operations that the worker lambda + # can initiate. It should not exceed 5 due to AWS Service Catalog limits, but + # some users may want to set it lower than 5 to provide enough overhead for + # other actions such as new account creation. Default value is 4. + lambda_worker_max_concurrent_operations = 4 + + # Sets the memory_size in MB for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_memory_size = 256 + + # Sets the timeout in seconds for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_timeout = 900 + + # The name of your AWS Control Tower Account Factory Portfolio + portfolio_name = "AWS Control Tower Account Factory Portfolio" + + # The amount of time allowed for the read operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + read_operation_timeout = "20m" + + # The number of seconds for the Step Function 'Wait' state. + sfn_wait_time_seconds = 30 + + # Sets the number of times a consumer (worker lambda) can receive a message + # from SQS before it is moved to a dead-letter queue + sqs_max_receive_count = 5 + + # The amount of time allowed for the update operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + update_operation_timeout = "60m" + +} + + +``` + + + + +```hcl title="terragrunt.hcl" + +# ------------------------------------------------------------------------------------------------------ +# DEPLOY GRUNTWORK'S CONTROL-TOWER-MULTI-ACCOUNT-FACTORY-ASYNC MODULE +# ------------------------------------------------------------------------------------------------------ + +terraform { + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-multi-account-factory-async?ref=v0.8.8" +} + +inputs = { + + # ---------------------------------------------------------------------------------------------------- + # REQUIRED VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # The absolute path to the folder to look for new account request files. Each + # file should be named account-.yml, where NAME is the name of an + # account to create. Within the YAML file, you must define the following + # fields: account_email (Account email, must be globally unique across all AWS + # Accounts), sso_user_first_name (The first name of the user who will be + # granted admin access to this new account through AWS SSO), + # sso_user_last_name (The last name of the user who will be granted admin + # access to this new account through AWS SSO), sso_user_email (The email + # address of the user who will be granted admin access to this new account + # through AWS SSO), organizational_unit_name (The name of the organizational + # unit or OU in which this account should be created—must be one of the OUs + # enrolled in Control Tower). + account_requests_folder = + + # ---------------------------------------------------------------------------------------------------- + # OPTIONAL VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # If specified, this is assumed to be the absolute file path of a YAML file + # where the details of the new accounts created by this module will be written + # (if the file already exists, the module will merge its data into the file). + # The expected format of this YAML file is that the keys are the account names + # and the values are objects with the following keys: id (the account ID), + # email (the root user email address for the account). + accounts_yaml_path = null + + # The amount of time allowed for the create operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + create_operation_timeout = "60m" + + # The amount of time allowed for the delete operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + delete_operation_timeout = "60m" + + # If set to true, this module will look for the specified organizational unit + # (OU) recursively under the root of the organization. If set to false, it + # will only look for the OU directly under the root. This is useful if you + # have nested OUs and want to create accounts in a child OU. + discover_ous_recursively = false + + # KMS key for encrypting ingest lambda log group + lambda_ingest_kms_key_id = null + + # Number of days to retain logs for ingest lambda functions + lambda_ingest_log_retention_in_days = 30 + + # Sets the memory_size in MB for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_memory_size = 256 + + # Sets the timeout in seconds for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_timeout = 900 + + # KMS key for encrypting worker lambda log group + lambda_worker_kms_key_id = null + + # Number of days to retain logs for worker lambda functions + lambda_worker_log_retention_in_days = 30 + + # Service Catalog supports a maximum of 5 account updates currently. This + # variable controls the maximum concurrent operations that the worker lambda + # can initiate. It should not exceed 5 due to AWS Service Catalog limits, but + # some users may want to set it lower than 5 to provide enough overhead for + # other actions such as new account creation. Default value is 4. + lambda_worker_max_concurrent_operations = 4 + + # Sets the memory_size in MB for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_memory_size = 256 + + # Sets the timeout in seconds for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_timeout = 900 + + # The name of your AWS Control Tower Account Factory Portfolio + portfolio_name = "AWS Control Tower Account Factory Portfolio" + + # The amount of time allowed for the read operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + read_operation_timeout = "20m" + + # The number of seconds for the Step Function 'Wait' state. + sfn_wait_time_seconds = 30 + + # Sets the number of times a consumer (worker lambda) can receive a message + # from SQS before it is moved to a dead-letter queue + sqs_max_receive_count = 5 + + # The amount of time allowed for the update operation to take before being + # considered to have failed. + # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + update_operation_timeout = "60m" + +} + + +``` + + + + + + + +## Reference + + + + +### Required + + + + +The absolute path to the folder to look for new account request files. Each file should be named account-<NAME>.yml, where NAME is the name of an account to create. Within the YAML file, you must define the following fields: account_email (Account email, must be globally unique across all AWS Accounts), sso_user_first_name (The first name of the user who will be granted admin access to this new account through AWS SSO), sso_user_last_name (The last name of the user who will be granted admin access to this new account through AWS SSO), sso_user_email (The email address of the user who will be granted admin access to this new account through AWS SSO), organizational_unit_name (The name of the organizational unit or OU in which this account should be created—must be one of the OUs enrolled in Control Tower). + + + + +### Optional + + + + +If specified, this is assumed to be the absolute file path of a YAML file where the details of the new accounts created by this module will be written (if the file already exists, the module will merge its data into the file). The expected format of this YAML file is that the keys are the account names and the values are objects with the following keys: id (the account ID), email (the root user email address for the account). + + + + + + + + +The amount of time allowed for the create operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + +The amount of time allowed for the delete operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + +If set to true, this module will look for the specified organizational unit (OU) recursively under the root of the organization. If set to false, it will only look for the OU directly under the root. This is useful if you have nested OUs and want to create accounts in a child OU. + + + + + + + + +KMS key for encrypting ingest lambda log group + + + + + + + + +Number of days to retain logs for ingest lambda functions + + + + + + + + +Sets the memory_size in MB for the ingest lambda function used for async provisioning_artifact_id updates. + + + + + + + + +Sets the timeout in seconds for the ingest lambda function used for async provisioning_artifact_id updates. + + + + + + + + +KMS key for encrypting worker lambda log group + + + + + + + + +Number of days to retain logs for worker lambda functions + + + + + + + + +Service Catalog supports a maximum of 5 account updates currently. This variable controls the maximum concurrent operations that the worker lambda can initiate. It should not exceed 5 due to AWS Service Catalog limits, but some users may want to set it lower than 5 to provide enough overhead for other actions such as new account creation. Default value is 4. + + + + + + + + +Sets the memory_size in MB for the worker lambda function used for async provisioning_artifact_id updates. + + + + + + + + +Sets the timeout in seconds for the worker lambda function used for async provisioning_artifact_id updates. + + + + + + + + +The name of your AWS Control Tower Account Factory Portfolio + + + + + + + + +The amount of time allowed for the read operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + +The number of seconds for the Step Function 'Wait' state. + + + + + + + + +Sets the number of times a consumer (worker lambda) can receive a message from SQS before it is moved to a dead-letter queue + + + + + + + + +The amount of time allowed for the update operation to take before being considered to have failed. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/servicecatalog_provisioned_product#timeouts + + + + + + + + + + + +The data from all the AWS accounts created. + + + + + + + + diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory/control-tower-multi-account-factory.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory/control-tower-multi-account-factory.md index bb80091b72..a28c65f5c1 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory/control-tower-multi-account-factory.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-multi-account-factory/control-tower-multi-account-factory.md @@ -9,16 +9,16 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Control Tower Multi-Account Factory -View Source +View Source -Release Notes +Release Notes This is a Terraform module that will trigger the creation of multiple new AWS accounts by using Control Tower. Under -the hood, this module uses the [control-tower-account-factory](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.7/modules/control-tower-account-factory) module. +the hood, this module uses the [control-tower-account-factory](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.8/modules/control-tower-account-factory) module. ## Sample Usage @@ -33,7 +33,7 @@ the hood, this module uses the [control-tower-account-factory](https://github.co module "control_tower_multi_account_factory" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-multi-account-factory?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-multi-account-factory?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -131,7 +131,7 @@ module "control_tower_multi_account_factory" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-multi-account-factory?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-multi-account-factory?ref=v0.8.8" } inputs = { @@ -334,11 +334,11 @@ The data from all the AWS accounts created. diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-provisioned-product-artifact-updater/control-tower-provisioned-product-artifact-updater.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-provisioned-product-artifact-updater/control-tower-provisioned-product-artifact-updater.md new file mode 100644 index 0000000000..a6120c3abd --- /dev/null +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-provisioned-product-artifact-updater/control-tower-provisioned-product-artifact-updater.md @@ -0,0 +1,230 @@ +--- +title: "Control Tower Provisioned Product Artifact Updater" +hide_title: true +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; +import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; +import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; + + + +# Control Tower Provisioned Product Artifact Updater + +View Source + +Release Notes + +This OpenTofu/Terraform module automates the detection and update of AWS Service Catalog provisioned products in response to [UpdateProvisioningArtifact](https://docs.aws.amazon.com/servicecatalog/latest/dg/API_UpdateProvisioningArtifact.html) or [UpdateProvisionedProduct](https://docs.aws.amazon.com/servicecatalog/latest/dg/API_UpgradeProduct.html) API calls. AWS EventBridge, SQS, Lambda, and AWS Step Functions to create a scalable, asynchronous update mechanism that safely propagates new artifact versions to affected accounts. + +## Use Cases + +When a new Provisioning Artifact is published in AWS Service Catalog, any accounts using an outdated artifact are automatically queued for an update. This module: + +* Detects UpdateProvisioningArtifact or UpgradeProduct events via EventBridge. +* Finds impacted provisioned products across your organization. +* Queues update jobs in SQS with deduplication and a dead-letter queue. +* Applies the new provisioning artifact via a worker Lambda. +* Verifies and tracks the update status using an AWS Step Functions state machine. + +## Components + +### Lambda Functions + +* ingest_lambda: Triggered by Service Catalog update events from EventBridge. It finds provisioned products that need an update and queues them in an SQS FIFO queue. +* worker_lambda: Triggered by messages from the SQS queue. It applies the update using UpdateProvisionedProduct and then initiates an AWS Step Functions state machine to track the update's progress. + +### SQS Queue + +* Used as a work queue. +* Configured as a FIFO queue to ensure ordered processing and prevent race conditions for a single provisioned product. +* Content-based deduplication is enabled. +* A Dead-Letter Queue (DLQ) is configured for failed messages. + +### AWS Step Functions state machine + +* A state machine that tracks the status of the Service Catalog update record. +* It uses a Wait state and a loop to periodically check the status of the update until it is SUCCEEDED or FAILED. + +### EventBridge + +* Captures UpdateProvisioningArtifact and UpgradeProduct API calls. +* Filters out self-executed calls (originating from the ingest_lambda role) to avoid feedback loops. + +### IAM Roles & Policies + +* Lambda roles with policies allowing access to: + * SQS (send messages for ingest_lambda, receive/delete messages for worker_lambda) + * Service Catalog (search/describe provisioned products, update products, describe records) + * Identity Store (list/describe users) + * Organizations (list parents/describe OUs) + * AWS Step Functions state machine (start execution) + * CloudWatch Logs +* Associated with the AWS Control Tower Account Factory Portfolio for Service Catalog access. + +## Sample Usage + + + + +```hcl title="main.tf" + +# ------------------------------------------------------------------------------------------------------ +# DEPLOY GRUNTWORK'S CONTROL-TOWER-PROVISIONED-PRODUCT-ARTIFACT-UPDATER MODULE +# ------------------------------------------------------------------------------------------------------ + +module "control_tower_provisioned_product_artifact_updater" { + + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-provisioned-product-artifact-updater?ref=v0.8.8" + + # ---------------------------------------------------------------------------------------------------- + # OPTIONAL VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # KMS key for encrypting ingest lambda log group + lambda_ingest_kms_key_id = null + + # Number of days to retain logs for ingest lambda functions + lambda_ingest_log_retention_in_days = 30 + + # Sets the memory_size in MB for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_memory_size = 256 + + # The runtime for the lambda ingest function + lambda_ingest_runtime = "python3.12" + + # Sets the timeout in seconds for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_timeout = 900 + + # KMS key for encrypting worker lambda log group + lambda_worker_kms_key_id = null + + # Number of days to retain logs for worker lambda functions + lambda_worker_log_retention_in_days = 30 + + # Service Catalog supports a maximum of 5 account updates currently. This + # variable controls the maximum concurrent operations that the worker lambda + # can initiate. It should not exceed 5 due to AWS Service Catalog limits, but + # some users may want to set it lower than 5 to provide enough overhead for + # other actions such as new account creation. Default value is 4. + lambda_worker_max_concurrent_operations = 4 + + # Sets the memory_size in MB for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_memory_size = 256 + + # The runtime for the lambda worker function + lambda_worker_runtime = "python3.12" + + # Sets the timeout in seconds for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_timeout = 900 + + # The name of your AWS Control Tower Account Factory Portfolio + portfolio_name = "AWS Control Tower Account Factory Portfolio" + + # The number of seconds for the Step Function 'Wait' state. + sfn_wait_time_seconds = 30 + + # Sets the number of times a consumer (worker lambda) can receive a message + # from SQS before it is moved to a dead-letter queue + sqs_max_receive_count = 5 + +} + + +``` + + + + +```hcl title="terragrunt.hcl" + +# ------------------------------------------------------------------------------------------------------ +# DEPLOY GRUNTWORK'S CONTROL-TOWER-PROVISIONED-PRODUCT-ARTIFACT-UPDATER MODULE +# ------------------------------------------------------------------------------------------------------ + +terraform { + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-provisioned-product-artifact-updater?ref=v0.8.8" +} + +inputs = { + + # ---------------------------------------------------------------------------------------------------- + # OPTIONAL VARIABLES + # ---------------------------------------------------------------------------------------------------- + + # KMS key for encrypting ingest lambda log group + lambda_ingest_kms_key_id = null + + # Number of days to retain logs for ingest lambda functions + lambda_ingest_log_retention_in_days = 30 + + # Sets the memory_size in MB for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_memory_size = 256 + + # The runtime for the lambda ingest function + lambda_ingest_runtime = "python3.12" + + # Sets the timeout in seconds for the ingest lambda function used for async + # provisioning_artifact_id updates. + lambda_ingest_timeout = 900 + + # KMS key for encrypting worker lambda log group + lambda_worker_kms_key_id = null + + # Number of days to retain logs for worker lambda functions + lambda_worker_log_retention_in_days = 30 + + # Service Catalog supports a maximum of 5 account updates currently. This + # variable controls the maximum concurrent operations that the worker lambda + # can initiate. It should not exceed 5 due to AWS Service Catalog limits, but + # some users may want to set it lower than 5 to provide enough overhead for + # other actions such as new account creation. Default value is 4. + lambda_worker_max_concurrent_operations = 4 + + # Sets the memory_size in MB for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_memory_size = 256 + + # The runtime for the lambda worker function + lambda_worker_runtime = "python3.12" + + # Sets the timeout in seconds for the worker lambda function used for async + # provisioning_artifact_id updates. + lambda_worker_timeout = 900 + + # The name of your AWS Control Tower Account Factory Portfolio + portfolio_name = "AWS Control Tower Account Factory Portfolio" + + # The number of seconds for the Step Function 'Wait' state. + sfn_wait_time_seconds = 30 + + # Sets the number of times a consumer (worker lambda) can receive a message + # from SQS before it is moved to a dead-letter queue + sqs_max_receive_count = 5 + +} + + +``` + + + + + diff --git a/docs/reference/modules/terraform-aws-control-tower/control-tower-security-account-baseline/control-tower-security-account-baseline.md b/docs/reference/modules/terraform-aws-control-tower/control-tower-security-account-baseline/control-tower-security-account-baseline.md index a5738bea81..a9ac72d2f7 100644 --- a/docs/reference/modules/terraform-aws-control-tower/control-tower-security-account-baseline/control-tower-security-account-baseline.md +++ b/docs/reference/modules/terraform-aws-control-tower/control-tower-security-account-baseline/control-tower-security-account-baseline.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Account Baseline Security with Control Tower Integration -View Source +View Source Release Notes @@ -34,7 +34,7 @@ by Control Tower, including setting up Amazon Guard Duty, Macie, IAM users, IAM module "control_tower_security_account_baseline" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-security-account-baseline?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-security-account-baseline?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -774,7 +774,7 @@ module "control_tower_security_account_baseline" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-security-account-baseline?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/control-tower-security-account-baseline?ref=v0.8.8" } inputs = { @@ -3473,11 +3473,11 @@ A map of usernames to that user's AWS Web Console password, encrypted with that diff --git a/docs/reference/modules/terraform-aws-control-tower/organizational-units/organizational-units.md b/docs/reference/modules/terraform-aws-control-tower/organizational-units/organizational-units.md index 61338fa033..8e43b213db 100644 --- a/docs/reference/modules/terraform-aws-control-tower/organizational-units/organizational-units.md +++ b/docs/reference/modules/terraform-aws-control-tower/organizational-units/organizational-units.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # Organizational Units Data Source -View Source +View Source Release Notes @@ -44,7 +44,7 @@ The output `ous` returns a list of organizational units, which have the followin module "organizational_units" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/organizational-units?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/organizational-units?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # OPTIONAL VARIABLES @@ -70,7 +70,7 @@ module "organizational_units" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/organizational-units?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/landingzone/organizational-units?ref=v0.8.8" } inputs = { @@ -123,11 +123,11 @@ If set to true, this module will look for the specified organizational unit (OU) diff --git a/docs/reference/modules/terraform-aws-control-tower/sso-groups/sso-groups.md b/docs/reference/modules/terraform-aws-control-tower/sso-groups/sso-groups.md index 91f8463cc9..b9c49ac6eb 100644 --- a/docs/reference/modules/terraform-aws-control-tower/sso-groups/sso-groups.md +++ b/docs/reference/modules/terraform-aws-control-tower/sso-groups/sso-groups.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # SSO Groups -View Source +View Source Release Notes @@ -74,7 +74,7 @@ inputs = { module "sso_groups" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-groups?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-groups?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -114,7 +114,7 @@ module "sso_groups" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-groups?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-groups?ref=v0.8.8" } inputs = { @@ -210,11 +210,11 @@ ARN of the SSO Admin instance where the Permission Set should be provisioned. Th diff --git a/docs/reference/modules/terraform-aws-control-tower/sso-permission-sets/sso-permission-sets.md b/docs/reference/modules/terraform-aws-control-tower/sso-permission-sets/sso-permission-sets.md index 0b9f772a71..18e85ae41e 100644 --- a/docs/reference/modules/terraform-aws-control-tower/sso-permission-sets/sso-permission-sets.md +++ b/docs/reference/modules/terraform-aws-control-tower/sso-permission-sets/sso-permission-sets.md @@ -9,11 +9,11 @@ import VersionBadge from '../../../../../src/components/VersionBadge.tsx'; import { HclListItem, HclListItemDescription, HclListItemTypeDetails, HclListItemDefaultValue, HclGeneralListItem } from '../../../../../src/components/HclListItem.tsx'; import { ModuleUsage } from "../../../../../src/components/ModuleUsage"; - + # SSO Permission Sets -View Source +View Source Release Notes @@ -79,7 +79,7 @@ access to the AWS Account with the IAM permissions defined on the Permission Set Permission sets are normally bound to groups using your IDP. -For an example of a manual binding see the [sso-groups module](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.7/modules/aws-sso/sso-groups). +For an example of a manual binding see the [sso-groups module](https://github.com/gruntwork-io/terraform-aws-control-tower/tree/v0.8.8/modules/aws-sso/sso-groups). ### What are permission boundaries? @@ -113,7 +113,7 @@ For more information on permission boundaries, see the [official documentation]( module "sso_permission_sets" { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-permission-sets?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-permission-sets?ref=v0.8.8" # ---------------------------------------------------------------------------------------------------- # REQUIRED VARIABLES @@ -168,7 +168,7 @@ module "sso_permission_sets" { # ------------------------------------------------------------------------------------------------------ terraform { - source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-permission-sets?ref=v0.8.7" + source = "git::git@github.com:gruntwork-io/terraform-aws-control-tower.git//modules/aws-sso/sso-permission-sets?ref=v0.8.8" } inputs = { @@ -335,11 +335,11 @@ The name of the permission set that was created.