diff --git a/CHANGELOG.md b/CHANGELOG.md index 44fe773fc..be1ba354c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.10.1] - 11-18-2024 + +### Fixed + +- fix(metadata): accelerator metadata lambda times out without error +- fix(docs): resolve broken links in mkdocs +- fix(route53): fix hosted zone DNS for Sagemaker VPC Endpoints +- fix(route53): fix hosted zone DNS for EKS-Auth VPC Endpoints +- fix(pipeline): bootstrap stage failed silently +- fix(organizations): fix enabled controls cfn throttling + ## [1.10.0] - 10-16-2024 ### Added @@ -23,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - fix(bootstrap): batched bootstrap checks +- fix(control-tower): skip existing ct identifier check when ct is not enabled - fix(control-tower): updated boolean logic to get LZ identifier - fix(custom-stacks): loaded replacement values during custom stack deployment - fix(diff): parse error during diff diff --git a/source/mkdocs/docs/user-guide/config.md b/source/mkdocs/docs/user-guide/config.md index 4d0a6b6cd..c81efdf47 100644 --- a/source/mkdocs/docs/user-guide/config.md +++ b/source/mkdocs/docs/user-guide/config.md @@ -13,7 +13,7 @@ Used to manage all of the AWS accounts within the AWS Organization. Adding a new | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ----------------- | -------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | -| AWS Accounts | Account | [AccountsConfig](../typedocs/latest/classes/_aws_accelerator_config.AccountsConfig.html) | [AccountConfig](../typedocs/latest/classes/_aws_accelerator_config.AccountConfig.html) / [GovCloudAccountConfig](../typedocs/latest/classes/_aws_accelerator_config.GovCloudAccountConfig.html) | Define commercial or GovCloud (US) accounts to be deployed by the accelerator. | +| AWS Accounts | Account | [AccountsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_accounts_config.IAccountConfig.html) | [AccountConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_accounts_config.IAccountConfig.html) / [GovCloudAccountConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_accounts_config.IGovCloudAccountConfig.html) | Define commercial or GovCloud (US) accounts to be deployed by the accelerator. | ## Global Configuration @@ -21,20 +21,20 @@ Used to manage all of the global properties that can be inherited across the AWS | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ----------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| AWS Backup | Backup Vaults | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) | [BackupConfig](../typedocs/latest/classes/_aws_accelerator_config.BackupConfig.html) | Define AWS Backup Vaults that can be used to store backups in accounts across the AWS Organization. | -| AWS Budgets | Budget Reports | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [ReportConfig](../typedocs/latest/classes/_aws_accelerator_config.ReportConfig.html) | [BudgetReportConfig](../typedocs/latest/classes/_aws_accelerator_config.BudgetReportConfig.html) | Define Budget report configurations for account(s) and/or organizational unit(s). | -| AWS CloudTrail | Organization and Account Trails | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [LoggingConfig](../typedocs/latest/classes/_aws_accelerator_config.LoggingConfig.html) | [CloudTrailConfig](../typedocs/latest/classes/_aws_accelerator_config.CloudTrailConfig.html) | When specified, Organization and/or account-level trails are deployed. | -| Amazon CloudWatch | Log Group Dynamic Partitioning | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [LoggingConfig](../typedocs/latest/classes/_aws_accelerator_config.LoggingConfig.html) | [CloudWatchLogsConfig](../typedocs/latest/classes/_aws_accelerator_config.CloudWatchLogsConfig.html) | Custom partition values for CloudWatch Log Groups sent to centralized logging S3 bucket. | -| AWS Control Tower | Control Tower | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) | [ControlTowerConfig](../typedocs/latest/classes/_aws_accelerator_config.ControlTowerConfig.html) | It is recommended that AWS Control Tower is enabled. When enabled, the accelerator will deploy AWS Control Tower in the desired home region for your environment. If AWS Control Tower is already available in the home region of your environment prior to installing the accelerator, the accelerator will integrate with resources and guardrails deployed by AWS Control Tower. | -| AWS Control Tower | Control Tower | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [ControlTowerConfig](../typedocs/latest/classes/_aws_accelerator_config.ControlTowerConfig.html) | [ControlTowerLandingZoneConfig](../typedocs/latest/classes/_aws_accelerator_config.ControlTowerLandingZoneConfig.html) | Define AWS Control Tower LandingZone configuration. When defined, the accelerator will manage AWS Control Tower LandingZone. | -| AWS Control Tower | Control Tower Controls | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [ControlTowerConfig](../typedocs/latest/classes/_aws_accelerator_config.ControlTowerConfig.html) | [ControlTowerControlConfig](../typedocs/latest/classes/_aws_accelerator_config.ControlTowerControlConfig.html) | Define AWS Control Tower controls to be deployed into organizational unit(s). | -| AWS Cost and Usage | Cost and Usage Report | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [ReportConfig](../typedocs/latest/classes/_aws_accelerator_config.ReportConfig.html) | [CostAndUsageReportConfig](../typedocs/latest/classes/_aws_accelerator_config.CostAndUsageReportConfig.html) | Define a global Cost and Usage report configuration for the AWS Organization. | -| AWS Regions | Enabled Regions | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) | [GlobalConfig.enabledRegions](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html#enabledRegions) | Define one or more AWS Regions for the solution to manage. | -| Amazon S3 | Lifecycle Rules | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [LoggingConfig](../typedocs/latest/classes/_aws_accelerator_config.LoggingConfig.html) | [AccessLogBucketConfig](../typedocs/latest/classes/_aws_accelerator_config.AccessLogBucketConfig.html) / [CentralLogBucketConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralLogBucketConfig.html) | Define global lifecycle rules for S3 access log buckets and the central log bucket deployed by the accelerator. | -| AWS Systems Manager Session Manager | Session Manager logging configuration | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) / [LoggingConfig](../typedocs/latest/classes/_aws_accelerator_config.LoggingConfig.html) | [SessionManagerConfig](../typedocs/latest/classes/_aws_accelerator_config.SessionManagerConfig.html) | Define global logging configuration settings for Session Manager. | -| AWS Systems Manager | Parameter Store | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) | [SsmParametersConfig](../typedocs/latest/classes/_aws_accelerator_config.SsmParametersConfig.html) | Define parameters to be stored in SSM Parameter Store. | -| AWS SNS Topics | SNS Topics Configuration | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) | [SnsTopicConfig](../typedocs/latest/classes/_aws_accelerator_config.SnsTopicConfig.html) | Define SNS topics for notifications. | -| AWS Tags | Tags Configuration | [GlobalConfig](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html) | [GlobalConfig.tags](../typedocs/latest/classes/_aws_accelerator_config.GlobalConfig.html#tags) | Define tags to apply to Landing Zone Accelerator created resources. | +| AWS Backup | Backup Vaults | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) | [BackupConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IBackupConfig.html) | Define AWS Backup Vaults that can be used to store backups in accounts across the AWS Organization. | +| AWS Budgets | Budget Reports | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [ReportConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IReportConfig.html) | [BudgetReportConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IBudgetReportConfig.html) | Define Budget report configurations for account(s) and/or organizational unit(s). | +| AWS CloudTrail | Organization and Account Trails | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [LoggingConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ILoggingConfig.html) | [CloudTrailConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ICloudTrailConfig.html) | When specified, Organization and/or account-level trails are deployed. | +| Amazon CloudWatch | Log Group Dynamic Partitioning | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [LoggingConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ILoggingConfig.html) | [CloudWatchLogsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ICloudWatchLogsConfig.html) | Custom partition values for CloudWatch Log Groups sent to centralized logging S3 bucket. | +| AWS Control Tower | Control Tower | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) | [ControlTowerConfig]../typedocs/latest//___packages__aws_accelerator_config_lib_models_global_config.IControlTowerConfig.html) | It is recommended that AWS Control Tower is enabled. When enabled, the accelerator will deploy AWS Control Tower in the desired home region for your environment. If AWS Control Tower is already available in the home region of your environment prior to installing the accelerator, the accelerator will integrate with resources and guardrails deployed by AWS Control Tower. | +| AWS Control Tower | Control Tower | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [ControlTowerConfig]../typedocs/latest//___packages__aws_accelerator_config_lib_models_global_config.IControlTowerConfig.html) | [ControlTowerLandingZoneConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IControlTowerLandingZoneConfig.html) | Define AWS Control Tower LandingZone configuration. When defined, the accelerator will manage AWS Control Tower LandingZone. | +| AWS Control Tower | Control Tower Controls | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [ControlTowerConfig]../typedocs/latest//___packages__aws_accelerator_config_lib_models_global_config.IControlTowerConfig.html) | [ControlTowerControlConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IControlTowerControlConfig.html) | Define AWS Control Tower controls to be deployed into organizational unit(s). | +| AWS Cost and Usage | Cost and Usage Report | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [ReportConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IReportConfig.html) | [CostAndUsageReportConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ICostAndUsageReportConfig.html) | Define a global Cost and Usage report configuration for the AWS Organization. | +| AWS Regions | Enabled Regions | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) | [GlobalConfig.enabledRegions](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html#enabledRegions) | Define one or more AWS Regions for the solution to manage. | +| Amazon S3 | Lifecycle Rules | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [LoggingConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ILoggingConfig.html) | [AccessLogBucketConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IAccessLogBucketConfig.html) / [CentralLogBucketConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ICentralLogBucketConfig.html) | Define global lifecycle rules for S3 access log buckets and the central log bucket deployed by the accelerator. | +| AWS Systems Manager Session Manager | Session Manager logging configuration | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) / [LoggingConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ILoggingConfig.html) | [SessionManagerConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ISessionManagerConfig.html) | Define global logging configuration settings for Session Manager. | +| AWS Systems Manager | Parameter Store | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) | [SsmParametersConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ISsmParametersConfig.html) | Define parameters to be stored in SSM Parameter Store. | +| AWS SNS Topics | SNS Topics Configuration | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) | [SnsTopicConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.ISnsTopicConfig.html) | Define SNS topics for notifications. | +| AWS Tags | Tags Configuration | [GlobalConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html) | [GlobalConfig.tags](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_global_config.IGlobalConfig.html#tags) | Define tags to apply to Landing Zone Accelerator created resources. | ## Identity and Access Management (IAM) Configuration @@ -42,13 +42,13 @@ Used to manage all of the IAM resources across the AWS Organization. Defined in | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ------------------------ | ----------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| AWS IAM | Users | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [UserSetConfig](../typedocs/latest/classes/_aws_accelerator_config.UserSetConfig.html) | Define IAM users to be deployed to specified account(s) and/or organizational unit(s). | -| AWS IAM | Groups | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [GroupSetConfig](../typedocs/latest/classes/_aws_accelerator_config.GroupSetConfig.html) | Define IAM groups to be deployed to specified account(s) and/or organizational unit(s). | -| AWS IAM | Policies | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [PolicySetConfig](../typedocs/latest/classes/_aws_accelerator_config.PolicySetConfig.html) | Define customer-managed IAM policies to be deployed to specified account(s) and/or organizational unit(s). | -| AWS IAM | Roles | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [RoleSetConfig](../typedocs/latest/classes/_aws_accelerator_config.RoleSetConfig.html) | Define customer-managed IAM roles to be deployed to specified account(s) and/or organizational unit(s). | -| AWS IAM | SAML identity providers | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [SamlProviderConfig](../typedocs/latest/classes/_aws_accelerator_config.SamlProviderConfig.html) | Define a SAML identity provider to allow federated IAM access to the AWS Organization. | -| AWS IAM Identity Center | Permission sets | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [IdentityCenterConfig](../typedocs/latest/classes/_aws_accelerator_config.IdentityCenterConfig.html) | Define IAM Identity Center (formerly AWS SSO) permission sets and assignments. | -| AWS Managed Microsoft AD | Managed directory | [IamConfig](../typedocs/latest/classes/_aws_accelerator_config.IamConfig.html) | [ManagedActiveDirectoryConfig](../typedocs/latest/classes/_aws_accelerator_config.ManagedActiveDirectoryConfig.html) | Define a Managed Microsoft AD directory. | +| AWS IAM | Users | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [UserSetConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IUserSetConfig.html) | Define IAM users to be deployed to specified account(s) and/or organizational unit(s). | +| AWS IAM | Groups | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [GroupSetConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IGroupSetConfig.html) | Define IAM groups to be deployed to specified account(s) and/or organizational unit(s). | +| AWS IAM | Policies | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [PolicySetConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IPolicySetConfig.html) | Define customer-managed IAM policies to be deployed to specified account(s) and/or organizational unit(s). | +| AWS IAM | Roles | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [RoleSetConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IRoleSetConfig.html) | Define customer-managed IAM roles to be deployed to specified account(s) and/or organizational unit(s). | +| AWS IAM | SAML identity providers | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [SamlProviderConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.ISamlProviderConfig.html) | Define a SAML identity provider to allow federated IAM access to the AWS Organization. | +| AWS IAM Identity Center | Permission sets | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [IdentityCenterConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIdentityCenterConfig.html) | Define IAM Identity Center (formerly AWS SSO) permission sets and assignments. | +| AWS Managed Microsoft AD | Managed directory | [IamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IIamConfig.html) | [ManagedActiveDirectoryConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_iam_config.IManagedActiveDirectoryConfig.html) | Define a Managed Microsoft AD directory. | ## Network Configuration @@ -56,22 +56,22 @@ Used to manage and implement network resources to establish a WAN/LAN architectu | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ------------------------------------ | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Delete Default Amazon VPC | Default VPC | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [DefaultVpcsConfig](../typedocs/latest/classes/_aws_accelerator_config.DefaultVpcsConfig.html) | If enabled, deletes the default VPC in each account and region managed by the accelerator. | -| AWS Direct Connect | Gateways, virtual interfaces, and gateway associations | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [DxGatewayConfig](../typedocs/latest/classes/_aws_accelerator_config.DxGatewayConfig.html) | Define Direct Connect gateways, virtual interfaces, and Direct Connect Gateway associations. | -| Amazon Elastic Load Balancing | Gateway Load Balancers, endpoint services, and endpoints | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralNetworkServicesConfig.html) | [GwlbConfig](../typedocs/latest/classes/_aws_accelerator_config.GwlbConfig.html) | Define a centrally-managed Gateway Load Balancer with an associated VPC endpoint service. Define Gateway Load Balancer endpoints that consume the service, allowing for deep packet inspection of workloads. | -| AWS Network Firewall | Network Firewalls, policies, and rule groups | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralNetworkServicesConfig.html) | [NfwConfig](../typedocs/latest/classes/_aws_accelerator_config.NfwConfig.html) | Define centrally-managed firewall rule groups and policies. Define Network Firewall endpoints that consume the policies, allowing for deep packet inspection of workloads. | -| Amazon Route 53 Resolver | Resolver endpoints, rules, DNS firewall rule groups, and query logging configurations | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralNetworkServicesConfig.html) | [ResolverConfig](../typedocs/latest/classes/_aws_accelerator_config.ResolverConfig.html) | Define centrally-managed Resolver endpoints, Resolver rules, DNS firewall rule groups, and query logging configurations. DNS firewall rule groups, Resolver rules, and query logging configurations can be associated to VPCs defined in [VpcConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcTemplatesConfig.html). | -| AWS Site-to-Site VPN | Customer gateways and VPN connections | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [CustomerGatewayConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomerGatewayConfig.html) | Define Customer gateways and VPN connections that terminate on Transit Gateways or Virtual Private Gateways. | -| AWS Transit Gateway | Transit Gateways and Transit Gateway route tables | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [TransitGatewayConfig](../typedocs/latest/classes/_aws_accelerator_config.TransitGatewayConfig.html) | Define Transit Gateways to deploy to a specified account and region in the AWS Organization. | -| AWS Transit Gateway | Transit Gateway peering connections | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [TransitGatewayPeeringConfig](../typedocs/latest/classes/_aws_accelerator_config.TransitGatewayPeeringConfig.html) | Create Transit Gateway peering connections between two Transit Gateways defined in [TransitGatewayConfig](../typedocs/latest/classes/_aws_accelerator_config.TransitGatewayConfig.html). | -| Amazon VPC | Customer-managed prefix lists | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [PrefixListConfig](../typedocs/latest/classes/_aws_accelerator_config.PrefixListConfig.html) | Define customer-managed prefix lists to deploy to account(s) and region(s) in the AWS Organization. Prefix lists can be referenced in place of CIDR ranges in subnet route tables, security groups, and Transit Gateway route tables. | -| Amazon VPC | DHCP options sets | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [DhcpOptsConfig](../typedocs/latest/classes/_aws_accelerator_config.DhcpOptsConfig.html) | Define custom DHCP options sets to deploy to account(s) and region(s) in the AWS Organization. DHCP options sets can be used by VPCs defined in [VpcConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcTemplatesConfig.html). | -| Amazon VPC | Flow Logs (global) | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [VpcFlowLogsConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcFlowLogsConfig.html) | Define a global VPC flow log configuration for VPCs deployed by the accelerator. VPC-specific flow logs can also be created in [VpcConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcTemplatesConfig.html). | -| Amazon VPC | VPCs, subnets, security groups, NACLs, route tables, NAT Gateways, and VPC endpoints | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [VpcConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcConfig.html) | Define VPCs to deploy to a specified account and region in the AWS Organization. | -| Amazon VPC | VPC endpoint policies | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [EndpointPolicyConfig](../typedocs/latest/classes/_aws_accelerator_config.EndpointPolicyConfig.html) | Define custom VPC endpoint policies to deploy to account(s) and region(s) in the AWS Organization. Endpoint policies can be used by interface endpoints and/or gateway endpoints defined in [VpcConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcTemplatesConfig.html). | -| Amazon VPC | VPC peering connections | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [VpcPeeringConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcPeeringConfig.html) | Create a peering connection between two VPCs defined in [VpcConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcConfig.html). **NOTE:** Not supported with VPCs deployed using [VpcTemplatesConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcTemplatesConfig.html). | -| Amazon VPC IP Address Manager (IPAM) | IPAM pools and scopes | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralNetworkServicesConfig.html) | [IpamConfig](../typedocs/latest/classes/_aws_accelerator_config.IpamConfig.html) | Enable IPAM delegated administrator and configuration settings for IPAM pools and scopes. **NOTE:** IPAM is required for VPCs and subnets configured to use dynamic IPAM CIDR allocations. | -| Amazon VPC Templates | VPCs, subnets, security groups, NACLs, route tables, NAT Gateways, and VPC endpoints | [NetworkConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkConfig.html) | [VpcTemplatesConfig](../typedocs/latest/classes/_aws_accelerator_config.VpcTemplatesConfig.html) | Deploys a standard-sized VPC to multiple defined account(s) and/or organizational unit(s). | +| Delete Default Amazon VPC | Default VPC | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [DefaultVpcsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IDefaultVpcsConfig.html) | If enabled, deletes the default VPC in each account and region managed by the accelerator. | +| AWS Direct Connect | Gateways, virtual interfaces, and gateway associations | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [DxGatewayConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IDxGatewayConfig.html) | Define Direct Connect gateways, virtual interfaces, and Direct Connect Gateway associations. | +| Amazon Elastic Load Balancing | Gateway Load Balancers, endpoint services, and endpoints | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ICentralNetworkServicesConfig.html) | [GwlbConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IGwlbConfig.html) | Define a centrally-managed Gateway Load Balancer with an associated VPC endpoint service. Define Gateway Load Balancer endpoints that consume the service, allowing for deep packet inspection of workloads. | +| AWS Network Firewall | Network Firewalls, policies, and rule groups | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ICentralNetworkServicesConfig.html) | [NfwConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INfwConfig.html) | Define centrally-managed firewall rule groups and policies. Define Network Firewall endpoints that consume the policies, allowing for deep packet inspection of workloads. | +| Amazon Route 53 Resolver | Resolver endpoints, rules, DNS firewall rule groups, and query logging configurations | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ICentralNetworkServicesConfig.html) | [ResolverConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IResolverConfig.html) | Define centrally-managed Resolver endpoints, Resolver rules, DNS firewall rule groups, and query logging configurations. DNS firewall rule groups, Resolver rules, and query logging configurations can be associated to VPCs defined in [VpcConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcTemplatesConfig.html). | +| AWS Site-to-Site VPN | Customer gateways and VPN connections | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [CustomerGatewayConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ICustomerGatewayConfig.html) | Define Customer gateways and VPN connections that terminate on Transit Gateways or Virtual Private Gateways. | +| AWS Transit Gateway | Transit Gateways and Transit Gateway route tables | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [TransitGatewayConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ITransitGatewayConfig.html) | Define Transit Gateways to deploy to a specified account and region in the AWS Organization. | +| AWS Transit Gateway | Transit Gateway peering connections | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [TransitGatewayPeeringConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ITransitGatewayPeeringConfig.html) | Create Transit Gateway peering connections between two Transit Gateways defined in [TransitGatewayConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ITransitGatewayConfig.html). | +| Amazon VPC | Customer-managed prefix lists | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [PrefixListConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IPrefixListConfig.html) | Define customer-managed prefix lists to deploy to account(s) and region(s) in the AWS Organization. Prefix lists can be referenced in place of CIDR ranges in subnet route tables, security groups, and Transit Gateway route tables. | +| Amazon VPC | DHCP options sets | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [DhcpOptsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IDhcpOptsConfig.html) | Define custom DHCP options sets to deploy to account(s) and region(s) in the AWS Organization. DHCP options sets can be used by VPCs defined in [VpcConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcTemplatesConfig.html). | +| Amazon VPC | Flow Logs (global) | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [VpcFlowLogsConfig](../typedocs/latest/classes/___packages__aws_accelerator_config_lib_common_types.VpcFlowLogsConfig.html) | Define a global VPC flow log configuration for VPCs deployed by the accelerator. VPC-specific flow logs can also be created in [VpcConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcTemplatesConfig.html). | +| Amazon VPC | VPCs, subnets, security groups, NACLs, route tables, NAT Gateways, and VPC endpoints | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [VpcConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcConfig.html) | Define VPCs to deploy to a specified account and region in the AWS Organization. | +| Amazon VPC | VPC endpoint policies | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [EndpointPolicyConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IEndpointPolicyConfig.html) | Define custom VPC endpoint policies to deploy to account(s) and region(s) in the AWS Organization. Endpoint policies can be used by interface endpoints and/or gateway endpoints defined in [VpcConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcConfig.html) / [VpcTemplatesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcTemplatesConfig.html). | +| Amazon VPC | VPC peering connections | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [VpcPeeringConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcPeeringConfig.html) | Create a peering connection between two VPCs defined in [VpcConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcConfig.html). **NOTE:** Not supported with VPCs deployed using [VpcTemplatesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcTemplatesConfig.html). | +| Amazon VPC IP Address Manager (IPAM) | IPAM pools and scopes | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) / [CentralNetworkServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.ICentralNetworkServicesConfig.html) | [IpamConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IIpamConfig.html) | Enable IPAM delegated administrator and configuration settings for IPAM pools and scopes. **NOTE:** IPAM is required for VPCs and subnets configured to use dynamic IPAM CIDR allocations. | +| Amazon VPC Templates | VPCs, subnets, security groups, NACLs, route tables, NAT Gateways, and VPC endpoints | [NetworkConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.INetworkConfig.html) | [VpcTemplatesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_network_config.IVpcTemplatesConfig.html) | Deploys a standard-sized VPC to multiple defined account(s) and/or organizational unit(s). | ## AWS Organizations Configuration @@ -79,11 +79,11 @@ Used to manage organizational units and policies in the AWS Organization. Define | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ---------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| AWS Account Quarantine | Quarantine | [OrganizationConfig](../typedocs/latest/classes/_aws_accelerator_config.OrganizationConfig.html) | [QuarantineNewAccountsConfig](../typedocs/latest/classes/_aws_accelerator_config.QuarantineNewAccountsConfig.html) | If enabled, a Service Control Policy (SCP) is applied to newly-created accounts that denies all API actions from principles outside of the accelerator. This SCP is stripped from the new account when the accelerator completes resource provisioning for the new account. | -| AWS Organizations | Backup Policies | [OrganizationConfig](../typedocs/latest/classes/_aws_accelerator_config.OrganizationConfig.html) | [BackupPolicyConfig](../typedocs/latest/classes/_aws_accelerator_config.BackupPolicyConfig.html) | Define organizational backup policies to be deployed to account(s) and/or organizational unit(s). | -| AWS Organizations | Organizational Units | [OrganizationConfig](../typedocs/latest/classes/_aws_accelerator_config.OrganizationConfig.html) | [OrganizationalUnitConfig](../typedocs/latest/classes/_aws_accelerator_config.OrganizationalUnitConfig.html) | Define organizational units (OUs) for the AWS Organization. | -| AWS Organizations | Service Control Policies (SCPs) | [OrganizationConfig](../typedocs/latest/classes/_aws_accelerator_config.OrganizationConfig.html) | [ServiceControlPolicyConfig](../typedocs/latest/classes/_aws_accelerator_config.ServiceControlPolicyConfig.html) | Define organizational service control policies to be deployed to account(s) and/or organizational unit(s). | -| AWS Organizations | Tag Policies | [OrganizationConfig](../typedocs/latest/classes/_aws_accelerator_config.OrganizationConfig.html) | [TaggingPolicyConfig](../typedocs/latest/classes/_aws_accelerator_config.TaggingPolicyConfig.html) | Define organizational tag policies to be deployed to account(s) and/or organizational unit(s). | +| AWS Account Quarantine | Quarantine | [OrganizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IOrganizationConfig.html) | [QuarantineNewAccountsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IQuarantineNewAccountsConfig.html) | If enabled, a Service Control Policy (SCP) is applied to newly-created accounts that denies all API actions from principles outside of the accelerator. This SCP is stripped from the new account when the accelerator completes resource provisioning for the new account. | +| AWS Organizations | Backup Policies | [OrganizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IOrganizationConfig.html) | [BackupPolicyConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IBackupPolicyConfig.html) | Define organizational backup policies to be deployed to account(s) and/or organizational unit(s). | +| AWS Organizations | Organizational Units | [OrganizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IOrganizationConfig.html) | [OrganizationalUnitConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IOrganizationalUnitConfig.html) | Define organizational units (OUs) for the AWS Organization. | +| AWS Organizations | Service Control Policies (SCPs) | [OrganizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IOrganizationConfig.html) | [ServiceControlPolicyConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IServiceControlPolicyConfig.html) | Define organizational service control policies to be deployed to account(s) and/or organizational unit(s). | +| AWS Organizations | Tag Policies | [OrganizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.IOrganizationConfig.html) | [TaggingPolicyConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_organization_config.ITaggingPolicyConfig.html) | Define organizational tag policies to be deployed to account(s) and/or organizational unit(s). | ## Security Configuration @@ -91,21 +91,21 @@ Used to manage configuration of AWS security services. Defined in **security-con | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ------------------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| AWS Audit Manager | Audit Manager | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [AuditManagerConfig](../typedocs/latest/classes/_aws_accelerator_config.AuditManagerConfig.html) | Enable Audit Manager delegated administrator and configuration settings. | -| Amazon CloudWatch | Metrics, Alarms, and Log Groups | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) | [CloudWatchConfig](../typedocs/latest/classes/_aws_accelerator_config.CloudWatchConfig.html) | Define CloudWatch metrics, alarms, and log groups to deploy into account(s) and/or organizational unit(s). You can also import existing log groups into your configuration. | -| AWS Config | Config Recorder, Delivery Channel, Rules, and Remediations | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) | [AwsConfig](../typedocs/latest/classes/_aws_accelerator_config.AwsConfig.html) | Define an AWS Config Recorder, Delivery Channel, and custom and/or managed rule sets to deploy across the AWS Organization. | -| Amazon Detective | Detective | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [DetectiveConfig](../typedocs/latest/classes/_aws_accelerator_config.DetectiveConfig.html) | Enable Detective delegated administrator and configuration settings. **Note:** Requires Amazon GuardDuty to be enabled for at least 48 hours. | -| Amazon EBS | Default Volume Encryption | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [EbsDefaultVolumeEncryptionConfig](../typedocs/latest/classes/_aws_accelerator_config.EbsDefaultVolumeEncryptionConfig.html) | Enable EBS default volume encryption across the AWS Organization. | -| Amazon GuardDuty | GuardDuty | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [GuardDutyConfig](../typedocs/latest/classes/_aws_accelerator_config.GuardDutyConfig.html) | Enable GuardDuty delegated administrator and configuration settings. | -| AWS IAM | Access Analyzer | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) | [AccessAnalyzerConfig](../typedocs/latest/classes/_aws_accelerator_config.AccessAnalyzerConfig.html) | If enabled, IAM Access Analyzer analyzes policies and reports a list of findings for resources that grant public or cross-account access from outside your AWS Organizations in the IAM console and through APIs. | -| AWS IAM | Password Policy | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) | [IamPasswordPolicyConfig](../typedocs/latest/classes/_aws_accelerator_config.IamPasswordPolicyConfig.html) | Define a password policy for IAM users in the AWS Organization. | -| AWS KMS | Customer-Managed Keys | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) | [KeyManagementServiceConfig](../typedocs/latest/classes/_aws_accelerator_config.KeyManagementServiceConfig.html) | Define customer-managed KMS keys to be deployed to account(s) and/or organizational unit(s). | -| Amazon Macie | Macie | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [MacieConfig](../typedocs/latest/classes/_aws_accelerator_config.MacieConfig.html) | Enable Macie delegated administrator and configuration settings. | -| Amazon S3 | S3 Public Access Block | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [S3PublicAccessBlockConfig](../typedocs/latest/classes/_aws_accelerator_config.S3PublicAccessBlockConfig.html) | Enable S3 public access block setting across the AWS Organization. | -| AWS Security Hub | Security Hub | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [SecurityHubConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityHubConfig.html) | Enable Security Hub delegated administrator and configuration settings. | -| Amazon SNS | Subscriptions | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [SnsSubscriptionConfig](../typedocs/latest/classes/_aws_accelerator_config.SnsSubscriptionConfig.html) | Configure email subscriptions for security-related SNS notifications. **NOTE:** **DEPRECATED** Use SnsTopicConfig in the global configuration instead. | -| AWS Systems Manager Automation | Automation Documents | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/classes/_aws_accelerator_config.CentralSecurityServicesConfig.html) | [SsmAutomationConfig](../typedocs/latest/classes/_aws_accelerator_config.SsmAutomationConfig.html) | Define SSM Automation Documents to be deployed to account(s) and/or organizational unit(s). | -| Resource Policy Enforcement | Resource Policy Enforcement Config | [SecurityConfig](../typedocs/latest/classes/_aws_accelerator_config.SecurityConfig.html) | [ResourcePolicyEnforcementConfig](../typedocs/latest/classes/_aws_accelerator_config.ResourcePolicyEnforcementConfig.html) | Define compliance check and remediation for resource-based policy to be deployed to account(s) and/or organization unit, which will enforce resource policy for all applicable resources in the account and/or OU. | +| AWS Audit Manager | Audit Manager | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [AuditManagerConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IAuditManagerConfig.html) | Enable Audit Manager delegated administrator and configuration settings. | +| Amazon CloudWatch | Metrics, Alarms, and Log Groups | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) | [CloudWatchConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICloudWatchConfig.html) | Define CloudWatch metrics, alarms, and log groups to deploy into account(s) and/or organizational unit(s). You can also import existing log groups into your configuration. | +| AWS Config | Config Recorder, Delivery Channel, Rules, and Remediations | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) | [AwsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IAwsConfig.html) | Define an AWS Config Recorder, Delivery Channel, and custom and/or managed rule sets to deploy across the AWS Organization. | +| Amazon Detective | Detective | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [DetectiveConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IDetectiveConfig.html) | Enable Detective delegated administrator and configuration settings. **Note:** Requires Amazon GuardDuty to be enabled for at least 48 hours. | +| Amazon EBS | Default Volume Encryption | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [EbsDefaultVolumeEncryptionConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IEbsDefaultVolumeEncryptionConfig.html) | Enable EBS default volume encryption across the AWS Organization. | +| Amazon GuardDuty | GuardDuty | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [GuardDutyConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IGuardDutyConfig.html) | Enable GuardDuty delegated administrator and configuration settings. | +| AWS IAM | Access Analyzer | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) | [AccessAnalyzerConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IAccessAnalyzerConfig.html) | If enabled, IAM Access Analyzer analyzes policies and reports a list of findings for resources that grant public or cross-account access from outside your AWS Organizations in the IAM console and through APIs. | +| AWS IAM | Password Policy | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) | [IamPasswordPolicyConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IIamPasswordPolicyConfig.html) | Define a password policy for IAM users in the AWS Organization. | +| AWS KMS | Customer-Managed Keys | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) | [KeyManagementServiceConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IKeyManagementServiceConfig.html) | Define customer-managed KMS keys to be deployed to account(s) and/or organizational unit(s). | +| Amazon Macie | Macie | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [MacieConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IMacieConfig.html) | Enable Macie delegated administrator and configuration settings. | +| Amazon S3 | S3 Public Access Block | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [S3PublicAccessBlockConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IS3PublicAccessBlockConfig.html) | Enable S3 public access block setting across the AWS Organization. | +| AWS Security Hub | Security Hub | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [SecurityHubConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityHubConfig.html) | Enable Security Hub delegated administrator and configuration settings. | +| Amazon SNS | Subscriptions | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [SnsSubscriptionConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISnsSubscriptionConfig.html) | Configure email subscriptions for security-related SNS notifications. **NOTE:** **DEPRECATED** Use SnsTopicConfig in the global configuration instead. | +| AWS Systems Manager Automation | Automation Documents | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) / [CentralSecurityServicesConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ICentralSecurityServicesConfig.html) | [SsmAutomationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISsmAutomationConfig.html) | Define SSM Automation Documents to be deployed to account(s) and/or organizational unit(s). | +| Resource Policy Enforcement | Resource Policy Enforcement Config | [SecurityConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.ISecurityConfig.html) | [ResourcePolicyEnforcementConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_security_config.IResourcePolicyEnforcementConfig.html) | Define compliance check and remediation for resource-based policy to be deployed to account(s) and/or organization unit, which will enforce resource policy for all applicable resources in the account and/or OU. | ## Customization Configuration @@ -113,15 +113,15 @@ Used to manage configuration of custom applications and CloudFormation stacks. D | Service / Feature | Resource | Base Configuration | Service / Feature Configuration | Details | | ----------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| AWS CloudFormation | Stacks | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [CustomizationConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationConfig.html) | [CloudFormationStackConfig](../typedocs/latest/classes/_aws_accelerator_config.CloudFormationStackConfig.html) | Define custom CloudFormation Stacks. | -| AWS CloudFormation | StackSets | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [CustomizationConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationConfig.html) | [CloudFormationStackSetConfig](../typedocs/latest/classes/_aws_accelerator_config.CloudFormationStackSetConfig.html) | Define custom CloudFormation Stacksets. | -| Amazon Elastic Load Balancing | Application Load Balancers | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/classes/_aws_accelerator_config.AppConfigItem.html) | [ApplicationLoadBalancerConfig](../typedocs/latest/classes/_aws_accelerator_config.ApplicationLoadBalancerConfig.html) | Define an Application Load Balancer to be used for a custom application. | -| Amazon Elastic Load Balancing | Network Load Balancers | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/classes/_aws_accelerator_config.AppConfigItem.html) | [NetworkLoadBalancerConfig](../typedocs/latest/classes/_aws_accelerator_config.NetworkLoadBalancerConfig.html) | Define a Network Load Balancer to be used for a custom application. | -| Amazon Elastic Load Balancing | Target Groups | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/classes/_aws_accelerator_config.AppConfigItem.html) | [TargetGroupItemConfig](../typedocs/latest/classes/_aws_accelerator_config.TargetGroupItemConfig.html) | Define a Target Group to be used with an Elastic Load Balancer. | -| Amazon EC2 | Autoscaling Groups | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/classes/_aws_accelerator_config.AppConfigItem.html) | [AutoScalingConfig](../typedocs/latest/classes/_aws_accelerator_config.AutoScalingConfig.html) | Define an autoscaling group to be used for a custom application. | -| Amazon EC2 | Launch Template | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/classes/_aws_accelerator_config.AppConfigItem.html) | [LaunchTemplateConfig](../typedocs/latest/classes/_aws_accelerator_config.LaunchTemplateConfig.html) | Define a launch template to be used for a custom application. | -| Amazon EC2 | Next-generation firewalls (standalone or autoscaling) and firewall management appliances | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) | [Ec2FirewallConfig](../typedocs/latest/classes/_aws_accelerator_config.Ec2FirewallConfig.html) | Define third-party EC2-based firewall appliances. | -| AWS Service Catalog | Portfolios, products, and shares | [CustomizationsConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationsConfig.html) / [CustomizationConfig](../typedocs/latest/classes/_aws_accelerator_config.CustomizationConfig.html) | [PortfolioConfig](../typedocs/latest/classes/_aws_accelerator_config.PortfolioConfig.html) | Define Service Catalog portfolios, products, and grant access permissions. You may also share portfolios to other accounts and OUs. | +| AWS CloudFormation | Stacks | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [CustomizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationConfig.html) | [CloudFormationStackConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICloudFormationStack.html) | Define custom CloudFormation Stacks. | +| AWS CloudFormation | StackSets | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [CustomizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationConfig.html) | [CloudFormationStackSetConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICloudFormationStackSet.html) | Define custom CloudFormation Stacksets. | +| Amazon Elastic Load Balancing | Application Load Balancers | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IAppConfigItem.html) | [ApplicationLoadBalancerConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IApplicationLoadBalancerConfig.html) | Define an Application Load Balancer to be used for a custom application. | +| Amazon Elastic Load Balancing | Network Load Balancers | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IAppConfigItem.html) | [NetworkLoadBalancerConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.INetworkLoadBalancerConfig.html) | Define a Network Load Balancer to be used for a custom application. | +| Amazon Elastic Load Balancing | Target Groups | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IAppConfigItem.html) | [TargetGroupItemConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ITargetGroupItem.html) | Define a Target Group to be used with an Elastic Load Balancer. | +| Amazon EC2 | Autoscaling Groups | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IAppConfigItem.html) | [AutoScalingConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IAutoScalingConfig.html) | Define an autoscaling group to be used for a custom application. | +| Amazon EC2 | Launch Template | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [AppConfigItem](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IAppConfigItem.html) | [LaunchTemplateConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ILaunchTemplateConfig.html) | Define a launch template to be used for a custom application. | +| Amazon EC2 | Next-generation firewalls (standalone or autoscaling) and firewall management appliances | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) | [Ec2FirewallConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IEc2FirewallConfig.html) | Define third-party EC2-based firewall appliances. | +| AWS Service Catalog | Portfolios, products, and shares | [CustomizationsConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationsConfig.html) / [CustomizationConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.ICustomizationConfig.html) | [PortfolioConfig](../typedocs/latest/interfaces/___packages__aws_accelerator_config_lib_models_customizations_config.IPortfolioConfig.html) | Define Service Catalog portfolios, products, and grant access permissions. You may also share portfolios to other accounts and OUs. | ## Other Services and Features diff --git a/source/mkdocs/mkdocs.yml b/source/mkdocs/mkdocs.yml index 592048dc5..53c22e920 100644 --- a/source/mkdocs/mkdocs.yml +++ b/source/mkdocs/mkdocs.yml @@ -20,6 +20,7 @@ nav: - Architecture and Design Philosophy: developer-guide/design.md - Feature Development: developer-guide/features.md - Documentation Guidelines: developer-guide/doc-guidelines.md + - JSON Schema: developer-guide/json-schema.md - Sample Configurations: - sample-configurations/index.md - Standard: diff --git a/source/package.json b/source/package.json index 49f5261b9..24e17ddfe 100644 --- a/source/package.json +++ b/source/package.json @@ -1,6 +1,6 @@ { "name": "landing-zone-accelerator-on-aws", - "version": "1.10.0", + "version": "1.10.1", "private": true, "description": "Landing Zone Accelerator on AWS", "license": "Apache-2.0", diff --git a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/firewall-resources.ts b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/firewall-resources.ts index 13c68bf61..2b6e58362 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/firewall-resources.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/firewall-resources.ts @@ -56,7 +56,15 @@ export class FirewallResources extends AseaResource { const firewallInstance = this.stack.getResource( existingFirewallInstance.logicalResourceId, ) as cdk.aws_ec2.CfnInstance; + const enis = firewallInstance.networkInterfaces as cdk.aws_ec2.CfnInstance.NetworkInterfaceProperty[]; + for (const eni of enis ?? []) { + this.scope.addSsmParameter({ + logicalId: pascalCase(`SsmParam${pascalCase(firewallInstanceName)}Eni${eni.deviceIndex}`), + parameterName: this.scope.getSsmPath(SsmResourceType.FIREWALL_ENI, [firewallInstanceName, eni.deviceIndex]), + stringValue: eni.networkInterfaceId!, + }); + } //Leaving as temporary placeholder for deletion handler firewallInstanceConfig; firewallInstance; diff --git a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/iam-roles.ts b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/iam-roles.ts index a509bbb0a..c14232ce3 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/iam-roles.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/iam-roles.ts @@ -15,6 +15,7 @@ import * as cdk from 'aws-cdk-lib'; import { AccountPrincipal, + ArnPrincipal, CfnInstanceProfile, CfnManagedPolicy, Effect, @@ -83,7 +84,7 @@ export class Roles extends AseaResource { private getAssumeRolePolicy(roleItem: RoleConfig) { const statements: PolicyStatement[] = []; for (const assumedByItem of roleItem.assumedBy ?? []) { - if (assumedByItem.type === 'service') { + if (assumedByItem.type === 'service' || assumedByItem.type === 'account') { statements.push( new PolicyStatement({ actions: ['sts:AssumeRole'], @@ -92,7 +93,16 @@ export class Roles extends AseaResource { }), ); } - if (assumedByItem.type === 'account') { + if (assumedByItem.type === 'principalArn') { + statements.push( + new PolicyStatement({ + actions: ['sts:AssumeRole'], + effect: Effect.ALLOW, + principals: [new ArnPrincipal(assumedByItem.principal)], + }), + ); + } + if (assumedByItem.type === 'account' && assumedByItem.principal) { const partition = this.props.partition; const accountIdRegex = /^\d{12}$/; const accountArnRegex = new RegExp('^arn:' + partition + ':iam::(\\d{12}):root$'); diff --git a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/route-53-query-logging-association.ts b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/route-53-query-logging-association.ts index f1823ee29..8a8a1146c 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/route-53-query-logging-association.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/route-53-query-logging-association.ts @@ -37,7 +37,9 @@ export class Route53ResolverQueryLoggingAssociation extends AseaResource { if (!vpcItem.vpcRoute53Resolver?.queryLogs) { continue; } - const associationLogicalId = `RqlAssoc${vpcItem.name}`.replace('_vpc', ''); + const associationLogicalIdWithReplacedVpc = `RqlAssoc${vpcItem.name}`.replace('_vpc', ''); + const associationLogicalId = `${associationLogicalIdWithReplacedVpc}`.replace(/-/g, ''); + const importResource = this.scope.importStackResources.getResourceByLogicalId(associationLogicalId); const cfnResolverQueryLoggingAssociation = this.scope.getResource( associationLogicalId, diff --git a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/shared-security-groups.ts b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/shared-security-groups.ts index 8bf0293a3..03e843d3b 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/shared-security-groups.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/shared-security-groups.ts @@ -2,10 +2,13 @@ import { AseaResourceType, VpcConfig, VpcTemplatesConfig } from '@aws-accelerato import { SsmResourceType } from '@aws-accelerator/utils/lib/ssm-parameter-path'; import { AseaResource, AseaResourceProps } from './resource'; import { ImportAseaResourcesStack, LogLevel } from '../stacks/import-asea-resources-stack'; +import { AcceleratorStage } from '../accelerator-stage'; import { pascalCase } from 'pascal-case'; const enum RESOURCE_TYPE { SECURITY_GROUP = 'AWS::EC2::SecurityGroup', + SECURITY_GROUP_EGRESS = 'AWS::EC2::SecurityGroupEgress', + SECURITY_GROUP_INGRESS = 'AWS::EC2::SecurityGroupIngress', } const ASEA_PHASE_NUMBER = '2'; @@ -22,6 +25,9 @@ export class SharedSecurityGroups extends AseaResource { } const vpcsInScope = this.scope.sharedVpcs; this.updateSecurityGroups(vpcsInScope); + if (this.props.stage === AcceleratorStage.POST_IMPORT_ASEA_RESOURCES) { + this.deleteSharedSecurityGroups(vpcsInScope); + } } private updateSecurityGroups(vpcItems: (VpcConfig | VpcTemplatesConfig)[]) { if (vpcItems.length === 0) { @@ -65,4 +71,124 @@ export class SharedSecurityGroups extends AseaResource { } return; } + + private deleteSharedSecurityGroups(vpcItems: (VpcConfig | VpcTemplatesConfig)[]) { + if (vpcItems.length === 0) { + return; + } + for (const vpcItem of vpcItems) { + const vpcStackInfo = this.getSecurityGroupResourceByVpc(vpcItem.name); + if (!vpcStackInfo) { + continue; + } + const existingSecurityGroups = vpcStackInfo.nestedStackResources.getResourcesByType(RESOURCE_TYPE.SECURITY_GROUP); + + const existingSecurityGroupIngressRules = vpcStackInfo.nestedStackResources.getResourcesByType( + RESOURCE_TYPE.SECURITY_GROUP_INGRESS, + ); + const existingSecurityGroupEgressRules = vpcStackInfo.nestedStackResources.getResourcesByType( + RESOURCE_TYPE.SECURITY_GROUP_EGRESS, + ); + + for (const existingSecurityGroup of existingSecurityGroups) { + const existingSecurityGroupName = existingSecurityGroup.resourceMetadata['Properties']['GroupName']; + const securityGroupConfig = vpcItem.securityGroups?.find( + (securityGroupItem: { name: string }) => securityGroupItem.name === existingSecurityGroupName, + ); + // if the security group is still configured skip + if (securityGroupConfig) continue; + + // lookup security group by tag name + // if unable to locate, warn and then skip + const securityGroupResource = vpcStackInfo.nestedStackResources.getResourceByTag(existingSecurityGroupName); + if (!securityGroupResource) { + this.scope.addLogs( + LogLevel.WARN, + `Could not locate shared security group resouce by tag name : ${existingSecurityGroupName}, for vpc ${vpcItem.name}`, + ); + continue; + } + + // remove security group from template + this.scope.addLogs(LogLevel.WARN, `Deleting Shared Security Group: ${existingSecurityGroup.logicalResourceId}`); + this.scope.addDeleteFlagForNestedResource( + vpcStackInfo.nestedStackResources.getStackKey(), + securityGroupResource.logicalResourceId, + ); + + const ssmResource = vpcStackInfo.nestedStackResources.getSSMParameterByName( + this.scope.getSsmPath(SsmResourceType.SECURITY_GROUP, [ + vpcItem.name, + existingSecurityGroup.resourceMetadata['Properties'].GroupName, + ]), + ); + if (ssmResource) { + this.scope.addLogs(LogLevel.WARN, `Deleting SSM Parameter: ${ssmResource.logicalResourceId}`); + this.scope.addDeleteFlagForNestedResource( + vpcStackInfo.nestedStackResources.getStackKey(), + ssmResource.logicalResourceId, + ); + } + + for (const ingressRule of existingSecurityGroupIngressRules) { + try { + if (ingressRule.resourceMetadata['Properties'].GroupId['Ref'] === existingSecurityGroup.logicalResourceId) { + this.scope.addLogs(LogLevel.WARN, `Deleting Ingress Rule: ${ingressRule.logicalResourceId}`); + this.scope.addDeleteFlagForNestedResource( + vpcStackInfo.nestedStackResources.getStackKey(), + ingressRule.logicalResourceId, + ); + } + } catch (error) { + // continue the ref may not exits + } + + try { + if ( + ingressRule.resourceMetadata['Properties'].SourceSecurityGroupId['Ref'] === + existingSecurityGroup.logicalResourceId + ) { + this.scope.addLogs(LogLevel.WARN, `Deleting Ingress Rule: ${ingressRule.logicalResourceId}`); + this.scope.addDeleteFlagForNestedResource( + vpcStackInfo.nestedStackResources.getStackKey(), + ingressRule.logicalResourceId, + ); + } + } catch (error) { + // the ref may not exist + } + + for (const egressRule of existingSecurityGroupEgressRules) { + try { + if ( + egressRule.resourceMetadata['Properties'].GroupId['Ref'] === existingSecurityGroup.logicalResourceId + ) { + this.scope.addLogs(LogLevel.WARN, `Deleting Egress Rule: ${egressRule.logicalResourceId}`); + this.scope.addDeleteFlagForNestedResource( + vpcStackInfo.nestedStackResources.getStackKey(), + egressRule.logicalResourceId, + ); + } + } catch (error) { + // continue the ref may not exist + } + try { + if ( + egressRule.resourceMetadata['Properties'].DestinationSecurityGroupId['Ref'] === + existingSecurityGroup.logicalResourceId + ) { + this.scope.addLogs(LogLevel.WARN, `Deleting Egress Rule: ${egressRule.logicalResourceId}`); + this.scope.addDeleteFlagForNestedResource( + vpcStackInfo.nestedStackResources.getStackKey(), + egressRule.logicalResourceId, + ); + } + } catch (error) { + // continue the ref may not exist + } + } + } + } + } + } } diff --git a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/transit-gateway-routes.ts b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/transit-gateway-routes.ts index 1de86e919..5ac510312 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/transit-gateway-routes.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/transit-gateway-routes.ts @@ -3,6 +3,7 @@ import { AseaResourceType, CfnResourceType, TransitGatewayConfig, + TransitGatewayPeeringConfig, TransitGatewayRouteEntryConfig, TransitGatewayRouteTableConfig, TransitGatewayRouteTableDxGatewayEntryConfig, @@ -20,14 +21,19 @@ enum RESOURCE_TYPE { TGW_ROUTE_TABLE = 'AWS::EC2::TransitGatewayRouteTable', VPC = 'AWS::EC2::VPC', TGW_ATTACHMENT = 'AWS::EC2::TransitGatewayAttachment', + TGW_PEERING_ATTACHMENT = 'Custom::TGWCreatePeeringAttachment', } const ASEA_PHASE_NUMBERS = ['0', '1', '3']; export class TransitGatewayRoutes extends AseaResource { props: AseaResourceProps; private transitGatewayRouteTables: Map = new Map(); + private transitGatewayGlobalRouteTables: Map = new Map(); + private transitGatewayPeeringAttachments: Map = new Map(); private allRoutes!: CfnResourceType[]; private allRouteTables!: CfnResourceType[]; + private allGlobalRouteTables!: CfnResourceType[]; + private allGlobalTgwPeeringAttachments!: CfnResourceType[]; constructor(scope: ImportAseaResourcesStack, props: AseaResourceProps) { super(scope, props); this.props = props; @@ -36,7 +42,10 @@ export class TransitGatewayRoutes extends AseaResource { return; } const stackRoutes = this.scope.importStackResources.getResourcesByType(RESOURCE_TYPE.TGW_ROUTE); - const nestedStackRoutes = this.getTgwRoutesFromNestedStacks(); + const nestedstackResources = this.scope.nestedStackResources; + const nestedStackRoutes = this.getTgwRoutesFromNestedStacks(nestedstackResources); + this.allGlobalRouteTables = []; + this.allGlobalTgwPeeringAttachments = []; this.allRoutes = [...stackRoutes, ...nestedStackRoutes]; this.scope.addLogs(LogLevel.INFO, `All routes: ${JSON.stringify(this.allRoutes)}`); if (this.allRoutes.length === 0) return; @@ -55,10 +64,22 @@ export class TransitGatewayRoutes extends AseaResource { return; } const tgwStackMapping = mappings[tgwStackKey]; + + //If TGW Peering Exists Cross Region we need to create Cross Region Route Table Lookup + if (this.props.networkConfig.transitGatewayPeering) { + const tgwPeeringConfigs = this.props.networkConfig.transitGatewayPeering; + const aseaPrefix = this.props.globalConfig.externalLandingZoneResources?.acceleratorPrefix; + for (const tgwPeeringConfig of tgwPeeringConfigs) { + this.setGlobalTgwPeeringResourceMaps(tgwPeeringConfig, aseaPrefix!, mappings, props); + } + } + const tgwResources = ImportStackResources.initSync({ stackMapping: tgwStackMapping }); this.allRouteTables = tgwResources.getResourcesByType(RESOURCE_TYPE.TGW_ROUTE_TABLE); + this.scope.addLogs(LogLevel.INFO, `All route tables: ${JSON.stringify(this.allRouteTables)}`); + for (const tgwItem of props.networkConfig.transitGateways.filter( tgw => tgw.account === props.stackInfo.accountKey && tgw.region === props.stackInfo.region, ) ?? []) { @@ -78,6 +99,54 @@ export class TransitGatewayRoutes extends AseaResource { } } } + /** + * Sets Global TGW Peering Mapping Resource Maps for TGW Attachment Ids and Route Tables Ids + * @param tgwPeeringConfig + * @returns + */ + private setGlobalTgwPeeringResourceMaps( + tgwPeeringConfig: TransitGatewayPeeringConfig, + aseaPrefix: string, + mappings: ASEAMappings, + props: AseaResourceProps, + ) { + const tgwRequesterAccountId = this.props.accountsConfig.getAccountId(tgwPeeringConfig.requester.account); + const tgwRequesterStackMapping = `${tgwRequesterAccountId}|${tgwPeeringConfig.requester.region}|${aseaPrefix}-SharedNetwork-Phase0`; + const tgwPeeringAttachmentStackMapping = `${props.stackInfo.accountId}|${tgwPeeringConfig.requester.region}|${aseaPrefix}-SharedNetwork-Phase1`; + const tgwRequesterMapping = mappings[tgwRequesterStackMapping]; + const tgwPeeringAttachmentMapping = mappings[tgwPeeringAttachmentStackMapping]; + const tgwRequesterResources = ImportStackResources.initSync({ stackMapping: tgwRequesterMapping }); + const tgwPeeringAttachmentResources = ImportStackResources.initSync({ + stackMapping: tgwPeeringAttachmentMapping, + }); + const tgwRequesterRouteTables = tgwRequesterResources.getResourcesByType(RESOURCE_TYPE.TGW_ROUTE_TABLE); + const tgwPeeringAttachments = tgwPeeringAttachmentResources.getResourcesByType( + RESOURCE_TYPE.TGW_PEERING_ATTACHMENT, + ); + this.allGlobalRouteTables.push(...tgwRequesterRouteTables); + this.allGlobalTgwPeeringAttachments.push(...tgwPeeringAttachments); + + const tgwAccepterAccountId = this.props.accountsConfig.getAccountId(tgwPeeringConfig.accepter.account); + const tgwAccepterStackMapping = `${tgwAccepterAccountId}|${tgwPeeringConfig.accepter.region}|${aseaPrefix}-SharedNetwork-Phase0`; + const tgwAccepterMapping = mappings[tgwAccepterStackMapping]; + const tgwAccepterResources = ImportStackResources.initSync({ stackMapping: tgwAccepterMapping }); + const tgwAccepterRouteTables = tgwAccepterResources.getResourcesByType(RESOURCE_TYPE.TGW_ROUTE_TABLE); + this.allGlobalRouteTables.push(...tgwAccepterRouteTables); + + this.allGlobalRouteTables.map(allGlobalRouteTable => { + const tags = allGlobalRouteTable.resourceMetadata['Properties'].Tags; + const name = tags.find((tag: { Key: string; Value: string }) => tag.Key === 'Name').Value; + this.transitGatewayGlobalRouteTables.set(name, allGlobalRouteTable.physicalResourceId!); + }); + + this.allGlobalTgwPeeringAttachments.map(allGlobalTgwPeeringAttachment => { + const tgwAttachmentId = allGlobalTgwPeeringAttachment.physicalResourceId; + const tgwAttachmentName = allGlobalTgwPeeringAttachment.resourceMetadata['Properties'].tagValue; + if (tgwAttachmentId) { + this.transitGatewayPeeringAttachments.set(tgwAttachmentName, tgwAttachmentId); + } + }); + } /** * Sets Given TransitGatewayConfig into maps with physicalResourceId to avoid loading multiple times @@ -101,6 +170,17 @@ export class TransitGatewayRoutes extends AseaResource { } } + /** + * Retrieves TGW Attachment ID from Global TGW Peering Attachment Map + * @param attachment + * @returns + */ + private getTgwAttachmentIdForTgwPeer(attachment: TransitGatewayRouteTableTgwPeeringEntryConfig) { + const tgwAttachmentIdName = attachment?.transitGatewayPeeringName; + const tgwAttachmentId = this.transitGatewayPeeringAttachments.get(tgwAttachmentIdName); + return tgwAttachmentId; + } + /** * ASEA Creates TransitGatewayAttachment in Phase 1 VPC Stack and only one TGW Attachment is created * @param vpcName @@ -233,7 +313,8 @@ export class TransitGatewayRoutes extends AseaResource { LogLevel.INFO, `Adding route ${routeItem.destinationCidrBlock} to TGW route table ${routeTableItem.name} for TGW ${tgwItem.name} in account: ${tgwItem.account}`, ); - // routeId = `${routeTableItem.name}-${routeItem.destinationCidrBlock}-${routeItem.attachment.transitGatewayPeeringName}`; + transitGatewayAttachmentId = this.getTgwAttachmentIdForTgwPeer(routeItem.attachment); + routeId = `${routeTableItem.name}-${routeItem.destinationCidrBlock}-${routeItem.attachment.transitGatewayPeeringName}`; } } @@ -258,7 +339,12 @@ export class TransitGatewayRoutes extends AseaResource { ): void { // Get TGW route table ID const routeTableKey = `${tgwItem.name}_${routeTableItem.name}`; - const transitGatewayRouteTableId = this.transitGatewayRouteTables.get(routeTableKey); + // Here we need to lookup RouteTableId differently if its a TGW Peering Attachment so we look + // up in the transitGatewayGlobalRouteTables Map + const transitGatewayRouteTableId = + this.transitGatewayRouteTables.get(routeTableKey) ?? + this.transitGatewayGlobalRouteTables.get(routeTableItem.name); + if (!transitGatewayRouteTableId) { this.scope.addLogs(LogLevel.ERROR, `Transit Gateway route table ${routeTableKey} not found`); throw new Error(`Configuration validation failed at runtime.`); @@ -312,9 +398,9 @@ export class TransitGatewayRoutes extends AseaResource { return route?.physicalResourceId; } - private getTgwRoutesFromNestedStacks() { + private getTgwRoutesFromNestedStacks(nestedStackResourcesMap: { [key: string]: ImportStackResources } | undefined) { const nestedRoutes = []; - for (const [, nestedStackResources] of Object.entries(this.scope.nestedStackResources ?? {})) { + for (const [, nestedStackResources] of Object.entries(nestedStackResourcesMap ?? {})) { this.scope.addLogs( LogLevel.INFO, `Looking for TGW routes in nested stack ${nestedStackResources.stackMapping.stackName}`, diff --git a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/vpc-resources.ts b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/vpc-resources.ts index f8e73c571..de9e18442 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/asea-resources/vpc-resources.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/asea-resources/vpc-resources.ts @@ -513,7 +513,7 @@ export class VpcResources extends AseaResource { }); } if (isNetworkType('ISubnetSourceConfig', sourceItem)) { - const sourceVpcItem = getVpcConfig(this.scope.vpcsInScope, sourceItem.vpc); + const sourceVpcItem = getVpcConfig(this.scope.vpcResources, sourceItem.vpc); sourceItem.subnets.forEach(subnet => securityGroupRules.push({ ...ruleProps, diff --git a/source/packages/@aws-accelerator/accelerator/lib/stacks/import-asea-resources-stack.ts b/source/packages/@aws-accelerator/accelerator/lib/stacks/import-asea-resources-stack.ts index 38ae36ee0..601df60e6 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/stacks/import-asea-resources-stack.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/stacks/import-asea-resources-stack.ts @@ -135,7 +135,7 @@ export class ImportAseaResourcesStack extends NetworkStack { this.addSsmParameter({ logicalId: `SSMParamLZAUpgrade`, - parameterName: `/${this.acceleratorPrefix}/LZAUpgrade`, + parameterName: `/${this.acceleratorPrefix}/LZAUpgrade/${cdk.Stack.of(this).stackName}`, stringValue: 'true', }); diff --git a/source/packages/@aws-accelerator/accelerator/lib/stacks/network-stacks/network-associations-gwlb-stack/network-associations-gwlb-stack.ts b/source/packages/@aws-accelerator/accelerator/lib/stacks/network-stacks/network-associations-gwlb-stack/network-associations-gwlb-stack.ts index f88ce65da..58a27f95d 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/stacks/network-stacks/network-associations-gwlb-stack/network-associations-gwlb-stack.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/stacks/network-stacks/network-associations-gwlb-stack/network-associations-gwlb-stack.ts @@ -973,12 +973,33 @@ export class NetworkAssociationsGwlbStack extends NetworkStack { for (const route of this.networkInterfaceRouteArray) { if (route.vpcOwnedByAccount) { this.createNetworkInterfaceRouteForOwnedVpc(route); - } else if (route.firewallOwnedByAccount) { + } else if (route.firewallOwnedByAccount || this.isAseaFirewallOwnedByAccount(route)) { this.createNetworkInterfaceRouteForOwnedFirewall(route, crossAccountRouteTableMap); } } } + private isAseaFirewallOwnedByAccount(route: networkInterfaceRouteDetails) { + if (!route.firewallName) { + return false; + } + if (!this.isManagedByAsea(AseaResourceType.FIREWALL_INSTANCE, route.firewallName)) { + return false; + } + const firewallInstances = [ + ...(this.props.customizationsConfig.firewalls?.instances ?? []), + ...(this.props.customizationsConfig.firewalls?.managerInstances ?? []), + ]; + + const firewallInstance = firewallInstances.find(instance => instance.name === route.firewallName); + + if (!firewallInstance) { + return false; + } + + return route.vpcName === firewallInstance.vpc; + } + /** * Retrieves a map of cross-account route table IDs * @param routeDetailsArray networkInterfaceRouteDetails[] @@ -1014,10 +1035,7 @@ export class NetworkAssociationsGwlbStack extends NetworkStack { crossAccountRouteTableMap: Map, ): void { if (routeDetails.firewallName && routeDetails.eniIndex !== undefined) { - const networkInterfaceId = this.getNetworkInterfaceIdFromFirewall( - routeDetails.firewallName, - routeDetails.eniIndex!, - ); + const networkInterfaceId = this.getNetworkInterfaceIdFromFirewall(routeDetails); this.logger.info( `Creating cross-account route targeting ENI of firewall ${routeDetails.firewallName} owned by this account in VPC ${routeDetails.vpcName}`, ); @@ -1037,12 +1055,21 @@ export class NetworkAssociationsGwlbStack extends NetworkStack { */ private createNetworkInterfaceRouteForOwnedVpc(routeDetails: networkInterfaceRouteDetails): void { let networkInterfaceId: string; + const aseaFirewallOwnedByAccount = this.isAseaFirewallOwnedByAccount(routeDetails); if (routeDetails.firewallName && routeDetails.firewallOwnedByAccount) { this.logger.info( `Creating route targeting ENI of firewall ${routeDetails.firewallName} in VPC ${routeDetails.vpcName}`, ); - networkInterfaceId = this.getNetworkInterfaceIdFromFirewall(routeDetails.firewallName, routeDetails.eniIndex!); - } else if (routeDetails.firewallName && !routeDetails.firewallOwnedByAccount) { + networkInterfaceId = this.getNetworkInterfaceIdFromFirewall(routeDetails); + } else if (routeDetails.firewallName && aseaFirewallOwnedByAccount && routeDetails.eniIndex) { + this.logger.info( + `Creating route targeting ENI of firewall ${routeDetails.firewallName} in VPC ${routeDetails.vpcName}`, + ); + networkInterfaceId = cdk.aws_ssm.StringParameter.valueForStringParameter( + this, + this.getSsmPath(SsmResourceType.FIREWALL_ENI, [routeDetails.firewallName, routeDetails.eniIndex.toString()]), + ); + } else if (routeDetails.firewallName && !routeDetails.firewallOwnedByAccount && !aseaFirewallOwnedByAccount) { this.logger.debug( `Skipping route targeting ENI of firewall ${routeDetails.firewallName} owned by different account in VPC ${routeDetails.vpcName}`, ); @@ -1147,17 +1174,36 @@ export class NetworkAssociationsGwlbStack extends NetworkStack { * @param firewallName * @param deviceIndex */ - private getNetworkInterfaceIdFromFirewall(firewallName: string, deviceIndex: number): string { - const firewall = this.instanceMap.get(firewallName); - const eni = firewall!.getNetworkInterface(deviceIndex); - - if (!eni.networkInterfaceId) { + private getNetworkInterfaceIdFromFirewall(routeDetails: networkInterfaceRouteDetails): string { + if (!routeDetails.firewallName) { + this.logger.error(`Firewall name is not defined for route ${routeDetails.routeEntry.name}`); + throw new Error(`Configuration validation failed at runtime.`); + } + if (routeDetails.eniIndex === undefined) { + this.logger.error(`ENI index for firewall ${routeDetails.firewallName} is not defined`); + throw new Error(`Configuration validation failed at runtime.`); + } + let eni; + const firewall = this.instanceMap.get(routeDetails.firewallName); + const aseaFirewallOwnedByAccount = this.isAseaFirewallOwnedByAccount(routeDetails); + if (firewall) { + eni = firewall.getNetworkInterface(routeDetails.eniIndex).networkInterfaceId; + } + if (aseaFirewallOwnedByAccount) { + eni = this.getSsmPath(SsmResourceType.FIREWALL_ENI, [ + routeDetails.firewallName, + routeDetails.eniIndex.toString(), + ]); + } + if (!eni) { this.logger.error( - `Could not retrieve network interface id for eni at index ${deviceIndex.toString()} from firewall ${firewallName}`, + `Could not retrieve network interface id for eni at index ${routeDetails.eniIndex.toString()} from firewall ${ + routeDetails.firewallName + }`, ); throw new Error(`Configuration validation failed at runtime.`); } - return eni.networkInterfaceId; + return eni; } /** diff --git a/source/packages/@aws-accelerator/accelerator/lib/stacks/organizations-stack.ts b/source/packages/@aws-accelerator/accelerator/lib/stacks/organizations-stack.ts index fcd4ebba7..470f2ca82 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/stacks/organizations-stack.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/stacks/organizations-stack.ts @@ -18,6 +18,7 @@ import * as path from 'path'; import { CentralSecurityServicesConfig, + ControlTowerConfig, GuardDutyConfig, IdentityCenterAssignmentConfig, IdentityCenterPermissionSetConfig, @@ -28,6 +29,7 @@ import { Bucket, BucketEncryptionType, BucketReplicationProps, + CreateControlTowerEnabledControls, DetectiveOrganizationAdminAccount, EnableAwsServiceAccess, EnablePolicyType, @@ -163,7 +165,7 @@ export class OrganizationsStack extends AcceleratorStack { this.enableConfigRecorderDelegatedAdminAccount(); // Enable Control Tower controls - this.enableControlTowerControls(); + this.enableControlTowerControls(this.props.globalConfig.controlTower); } // Macie Configuration @@ -199,28 +201,63 @@ export class OrganizationsStack extends AcceleratorStack { } /** - * Function to enable Control Tower Controls + * Enables Control Tower controls based on the provided configuration. + * This method filters enabled controls, creates them, and sets up their dependencies. * Only optional controls are supported (both Strongly Recommended and Elective) * https://docs.aws.amazon.com/controltower/latest/userguide/optional-controls.html + * + * @param controlTowerConfig - The Control Tower configuration object containing control settings + * @returns void + * @private */ - private enableControlTowerControls() { - if (this.stackProperties.globalConfig.controlTower.enable) { - for (const control of this.stackProperties.globalConfig.controlTower.controls ?? []) { - this.logger.info(`Control ${control.identifier} status: ${control.enable}`); - - if (control.enable) { - for (const orgUnit of control.deploymentTargets.organizationalUnits) { - const orgUnitArn = this.stackProperties.organizationConfig.getOrganizationalUnitArn(orgUnit); - const controlArn = `arn:${this.props.partition}:controltower:${this.region}::control/${control.identifier}`; - - new cdk.aws_controltower.CfnEnabledControl(this, pascalCase(`${control.identifier}-${orgUnit}`), { - controlIdentifier: controlArn, - targetIdentifier: orgUnitArn, - }); - } - } - } + + private enableControlTowerControls(controlTowerConfig: ControlTowerConfig) { + if (!controlTowerConfig.enable) { + return; + } + if (!controlTowerConfig.controls) { + return; + } + const controlsToEnable = controlTowerConfig.controls.filter(control => control.enable); + if (controlsToEnable.length === 0) { + return; + } + // Creates a flat array of control targets mapped to their organizational units. + const enabledControlsTargets = controlsToEnable + .map(control => { + const ous = control.deploymentTargets.organizationalUnits; + return this.getEnabledControlTargetsFromOUs({ ouNames: ous, enabledControlIdentifier: control.identifier }); + }) + .flat(); + + new CreateControlTowerEnabledControls(this, 'CTEnabledControls', { controls: enabledControlsTargets }); + } + + /** + * Sets enabled control targets for specified organizational units. + * + * @param props - Configuration object for enabled control targets + * @param props.ouNames - Array of organizational unit names to process + * @param props.enabledControlIdentifier - The identifier of the control to be enabled + * @returns Array of objects containing OU details and control identifier mapping + * @private + */ + + private getEnabledControlTargetsFromOUs(props: { ouNames: string[]; enabledControlIdentifier: string }): { + ouName: string; + ouArn: string; + enabledControlIdentifier: string; + }[] { + const enabledControlTargets = []; + for (const ouName of props.ouNames) { + const ouArn = this.stackProperties.organizationConfig.getOrganizationalUnitArn(ouName); + enabledControlTargets.push({ + ouName, + ouArn, + enabledControlIdentifier: props.enabledControlIdentifier, + }); } + return enabledControlTargets; } /** @@ -688,9 +725,9 @@ export class OrganizationsStack extends AcceleratorStack { let assignmentList: { [x: string]: string[] }[] = []; let delegatedAdminAccountId = adminAccountId; - const identityCenterDelgatedAdminOverrideId = this.props.iamConfig.identityCenter?.delegatedAdminAccount; - if (identityCenterDelgatedAdminOverrideId) { - delegatedAdminAccountId = this.props.accountsConfig.getAccountId(identityCenterDelgatedAdminOverrideId); + const identityCenterDelegatedAdminOverrideId = this.props.iamConfig.identityCenter?.delegatedAdminAccount; + if (identityCenterDelegatedAdminOverrideId) { + delegatedAdminAccountId = this.props.accountsConfig.getAccountId(identityCenterDelegatedAdminOverrideId); } if (this.props.iamConfig.identityCenter?.identityCenterPermissionSets) { diff --git a/source/packages/@aws-accelerator/accelerator/lib/toolkit.ts b/source/packages/@aws-accelerator/accelerator/lib/toolkit.ts index f65d9aa72..d2f98e105 100644 --- a/source/packages/@aws-accelerator/accelerator/lib/toolkit.ts +++ b/source/packages/@aws-accelerator/accelerator/lib/toolkit.ts @@ -383,6 +383,7 @@ export class AcceleratorToolkit { `Credentials expired for account ${options.accountId} in region ${options.region} running command ${options.command}`, ); } + throw new Error(`Bootstrap for account ${options.accountId} in region ${options.region} failed.`); } } diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/accounts-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/accounts-stack.test.ts.snap index a3005aefd..f489e0177 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/accounts-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/accounts-stack.test.ts.snap @@ -2893,7 +2893,7 @@ exports[`AccountsStack us-east-1 Construct(AccountsStack): Snapshot Test 1`] = "Properties": { "Name": "/accelerator/AWSAccelerator-AccountsStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -3902,7 +3902,7 @@ exports[`AccountsStack us-west-2 Construct(AccountsStackUsWest2): Snapshot Test "Properties": { "Name": "/accelerator/AWSAccelerator-AccountsStack-111111111111-us-west-2/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/applications-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/applications-stack.test.ts.snap index 04d6c8f68..c0fcf0f86 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/applications-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/applications-stack.test.ts.snap @@ -440,7 +440,7 @@ exports[`ApplicationsStack Construct(ApplicationsStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-CustomizationsStack-444444444444-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/bootstrap-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/bootstrap-stack.test.ts.snap index 4d8199110..076ddbdd6 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/bootstrap-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/bootstrap-stack.test.ts.snap @@ -948,7 +948,7 @@ exports[`BootstrapStack Construct(BootstrapStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-BootstrapStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/customizations-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/customizations-stack.test.ts.snap index 87e4c1bef..500874a1b 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/customizations-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/customizations-stack.test.ts.snap @@ -656,7 +656,7 @@ exports[`CustomizationsStack Construct(CustomizationsStack): Snapshot Test 1`] "Properties": { "Name": "/accelerator/AWSAccelerator-CustomizationsStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -1114,7 +1114,7 @@ exports[`CustomizationsStack Construct(CustomizationsStack): Snapshot Test 2`] "Properties": { "Name": "/accelerator/AWSAccelerator-CustomizationsStack-444444444444-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/dependencies-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/dependencies-stack.test.ts.snap index e951c4e7c..596b87fd0 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/dependencies-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/dependencies-stack.test.ts.snap @@ -201,7 +201,7 @@ exports[`DependenciesStack Construct(DependenciesStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-DependenciesStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/finalize-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/finalize-stack.test.ts.snap index b47a05f17..aa1c6e360 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/finalize-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/finalize-stack.test.ts.snap @@ -951,7 +951,7 @@ exports[`FinalizeStack Construct(FinalizeStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-FinalizeStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/identity-center-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/identity-center-stack.test.ts.snap index f6cfe3b76..da98ec012 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/identity-center-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/identity-center-stack.test.ts.snap @@ -695,7 +695,7 @@ exports[`IdentityCenterStack Construct(IdentityCenterStack): Snapshot Test 1`] "Properties": { "Name": "/accelerator/AWSAccelerator-IdentityCenterStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/key-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/key-stack.test.ts.snap index e99162c12..6ad49ef5f 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/key-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/key-stack.test.ts.snap @@ -392,7 +392,7 @@ exports[`KeyStack Construct(KeyStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-KeyStack-222222222222-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/logging-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/logging-stack.test.ts.snap index 0e3267377..3767b71ba 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/logging-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/logging-stack.test.ts.snap @@ -4012,7 +4012,7 @@ exports[`LoggingStack Construct(LoggingStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-LoggingStack-333333333333-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -8396,7 +8396,7 @@ exports[`LoggingStack Construct(LoggingStack): Snapshot Test 2`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-LoggingStack-333333333333-us-west-2/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -12871,7 +12871,7 @@ exports[`LoggingStackOuTargets Construct(LoggingStackOuTargets): Snapshot Test "Properties": { "Name": "/accelerator/AWSAccelerator-LoggingStack-333333333333-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-gwlb-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-gwlb-stack.test.ts.snap index 559f63d86..11d5025bb 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-gwlb-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-gwlb-stack.test.ts.snap @@ -2861,7 +2861,7 @@ exports[`NetworkAssociationsGwlbStack Construct(NetworkAssociationsGwlbStack): "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkAssociationsGwlbStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-stack.test.ts.snap index 1f8f0c5cb..20a60105c 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-associations-stack.test.ts.snap @@ -2996,7 +2996,7 @@ exports[`NetworkAssociationsStack Construct(NetworkAssociationsStack): Snapshot "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkAssociationsStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -5293,7 +5293,7 @@ exports[`NoVpcFlowLogStack Construct(NetworkAssociationsStack): Snapshot Test 1 "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkAssociationsStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-prep-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-prep-stack.test.ts.snap index a63200b34..8ae27f3d5 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-prep-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-prep-stack.test.ts.snap @@ -2262,7 +2262,7 @@ drop http $HOME_NET any -> $EXTERNAL_NET any (http.host; content:"example.com"; "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkPrepStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-dns-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-dns-stack.test.ts.snap index 7069b500d..99b223cbf 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-dns-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-dns-stack.test.ts.snap @@ -1101,7 +1101,7 @@ exports[`NetworkVpcDnsStack Construct(NetworkVpcDnsStack): Snapshot Test 1`] = "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkVpcDnsStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-endpoints-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-endpoints-stack.test.ts.snap index 985c178c9..db580c011 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-endpoints-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-endpoints-stack.test.ts.snap @@ -2153,7 +2153,7 @@ exports[`NetworkVpcEndpointsStack Construct(NetworkVpcEndpointsStack): Snapshot "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkVpcEndpointsStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-stack.test.ts.snap index c70b08a1e..c9f71baa5 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/network-vpc-stack.test.ts.snap @@ -4396,7 +4396,7 @@ exports[`NetworkVpcStack Construct(NetworkVpcStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkVpcStack-555555555555-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -5852,7 +5852,7 @@ exports[`NoVpcFlowLogStack Construct(NetworkVpcStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-NetworkVpcStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/operations-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/operations-stack.test.ts.snap index 2701d020f..4df112b21 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/operations-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/operations-stack.test.ts.snap @@ -1120,7 +1120,7 @@ exports[`OperationsStack Construct(OperationsStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-OperationsStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/organizations-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/organizations-stack.test.ts.snap index 162c64f14..8d707f7fa 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/organizations-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/organizations-stack.test.ts.snap @@ -3202,7 +3202,7 @@ exports[`MultiOuOrganizationsStack Construct(OrganizationsStack): Snapshot Test "Properties": { "Name": "/accelerator/AWSAccelerator-OrganizationsStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -3466,15 +3466,40 @@ exports[`OrganizationsStack Construct(OrganizationsStack): Snapshot Test 1`] = "UpdateReplacePolicy": "Delete", }, "AwsGrEbsOptimizedInstanceSecureWorkloads": { + "DependsOn": [ + "AwsGrRestrictRootUserAccessKeysSecureWorkloads", + ], "Properties": { - "ControlIdentifier": "arn:aws:controltower:us-east-1::control/AWS-GR_EBS_OPTIMIZED_INSTANCE", + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_EBS_OPTIMIZED_INSTANCE", + ], + ], + }, "TargetIdentifier": "arn:aws:organizations::111111111111:ou/o-asdf123456/ou-asdf-33333333", }, "Type": "AWS::ControlTower::EnabledControl", }, "AwsGrRestrictRootUserAccessKeysSecureWorkloads": { "Properties": { - "ControlIdentifier": "arn:aws:controltower:us-east-1::control/AWS-GR_RESTRICT_ROOT_USER_ACCESS_KEYS", + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_RESTRICT_ROOT_USER_ACCESS_KEYS", + ], + ], + }, "TargetIdentifier": "arn:aws:organizations::111111111111:ou/o-asdf123456/ou-asdf-33333333", }, "Type": "AWS::ControlTower::EnabledControl", @@ -6572,7 +6597,7 @@ exports[`OrganizationsStack Construct(OrganizationsStack): Snapshot Test 1`] = "Properties": { "Name": "/accelerator/AWSAccelerator-OrganizationsStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -9846,7 +9871,7 @@ exports[`delegatedAdminStack Construct(OrganizationsStack): Snapshot Test 1`] = "Properties": { "Name": "/accelerator/AWSAccelerator-OrganizationsStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/pipeline-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/pipeline-stack.test.ts.snap index 26c76fcd1..8f086441b 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/pipeline-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/pipeline-stack.test.ts.snap @@ -2597,7 +2597,7 @@ exports[`PipelineStack Construct(PipelineStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/PipelineStack/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/prepare-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/prepare-stack.test.ts.snap index a5f2faaf0..cad073f3f 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/prepare-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/prepare-stack.test.ts.snap @@ -4595,7 +4595,7 @@ exports[`PrepareStack Construct(PrepareStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-PrepareStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/resource-policy-enforcement-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/resource-policy-enforcement-stack.test.ts.snap index 00adf41fa..ed705ec51 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/resource-policy-enforcement-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/resource-policy-enforcement-stack.test.ts.snap @@ -874,7 +874,7 @@ exports[`ResourcePolicyEnforcementStack Construct(ResourcePolicyEnforcementStack "Properties": { "Name": "/accelerator/AWSAccelerator-ResourcePolicyEnforcementStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-audit-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-audit-stack.test.ts.snap index 18bb655ee..33fe9ea36 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-audit-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-audit-stack.test.ts.snap @@ -2705,7 +2705,7 @@ def script_handler(events, context): "Properties": { "Name": "/accelerator/AWSAccelerator-SecurityAuditStack-222222222222-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -5069,7 +5069,7 @@ def script_handler(events, context): "Properties": { "Name": "/accelerator/AWSAccelerator-SecurityAuditStack-222222222222-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-resources-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-resources-stack.test.ts.snap index 000bf5716..4f1bcbbff 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-resources-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-resources-stack.test.ts.snap @@ -4591,7 +4591,7 @@ exports[`SecurityResourcesStack Construct(SecurityResourcesStack): Snapshot Tes "Properties": { "Name": "/accelerator/AWSAccelerator-SecurityResourcesStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -7829,7 +7829,7 @@ exports[`delegatedAdminStack Construct(SecurityResourcesStack): Snapshot Test 1 "Properties": { "Name": "/accelerator/AWSAccelerator-SecurityResourcesStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-stack.test.ts.snap b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-stack.test.ts.snap index 5953ab270..773ea010d 100644 --- a/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-stack.test.ts.snap +++ b/source/packages/@aws-accelerator/accelerator/test/__snapshots__/security-stack.test.ts.snap @@ -1274,7 +1274,7 @@ exports[`SecurityStack Construct(SecurityStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-SecurityStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -2386,7 +2386,7 @@ exports[`delegatedAdminStack Construct(SecurityStack): Snapshot Test 1`] = ` "Properties": { "Name": "/accelerator/AWSAccelerator-SecurityStack-111111111111-us-east-1/version", "Type": "String", - "Value": "1.10.0", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/accelerator/test/configs/all-enabled/global-config.yaml b/source/packages/@aws-accelerator/accelerator/test/configs/all-enabled/global-config.yaml index 9417c0ffc..da53ef714 100644 --- a/source/packages/@aws-accelerator/accelerator/test/configs/all-enabled/global-config.yaml +++ b/source/packages/@aws-accelerator/accelerator/test/configs/all-enabled/global-config.yaml @@ -68,16 +68,60 @@ controlTower: security: enableIdentityCenterAccess: true controls: + - identifier: AWS-GR_RDS_INSTANCE_PUBLIC_ACCESS_CHECK + enable: true + deploymentTargets: + organizationalUnits: + - SecureWorkloads + - Devops + - Infrastructure + - Security + - Level1 + - identifier: AWS-GR_ELASTICSEARCH_IN_VPC_ONLY + enable: true + deploymentTargets: + organizationalUnits: + - SecureWorkloads + - Devops + - Infrastructure + - Security + - Level1 + - identifier: AWS-GR_EC2_VOLUME_INUSE_CHECK + enable: true + deploymentTargets: + organizationalUnits: + - SecureWorkloads + - Devops + - Infrastructure + - Security + - Level1 + - identifier: AWS-GR_EBS_SNAPSHOT_PUBLIC_RESTORABLE_CHECK + enable: true + deploymentTargets: + organizationalUnits: + - SecureWorkloads + - Devops + - Infrastructure + - Security + - Level1 - identifier: AWS-GR_RESTRICT_ROOT_USER_ACCESS_KEYS enable: true deploymentTargets: organizationalUnits: - SecureWorkloads + - Devops + - Infrastructure + - Security + - Level1 - identifier: AWS-GR_EBS_OPTIMIZED_INSTANCE enable: true deploymentTargets: organizationalUnits: - SecureWorkloads + - Devops + - Infrastructure + - Security + - Level1 - identifier: AWS-GR_RESTRICTED_COMMON_PORTS enable: false deploymentTargets: diff --git a/source/packages/@aws-accelerator/accelerator/test/stacks/organizations-stack.test.ts b/source/packages/@aws-accelerator/accelerator/test/stacks/organizations-stack.test.ts new file mode 100644 index 000000000..ea4764112 --- /dev/null +++ b/source/packages/@aws-accelerator/accelerator/test/stacks/organizations-stack.test.ts @@ -0,0 +1,227 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import { + AccountsConfig, + ControlTowerConfig, + CustomizationsConfig, + GlobalConfig, + GroupSetConfig, + IamConfig, + LoggingConfig, + NetworkConfig, + OrganizationConfig, + ReplacementsConfig, + SecurityConfig, + UserSetConfig, +} from '@aws-accelerator/config'; +import { afterEach, beforeEach, describe, expect, jest, test } from '@jest/globals'; +import * as cdk from 'aws-cdk-lib'; +import { Capture, Template } from 'aws-cdk-lib/assertions'; +import { OrganizationsStack, OrganizationsStackProps } from '../../lib/stacks/organizations-stack'; +import { AcceleratorResourcePrefixes } from '../../utils/app-utils'; +import { IKey } from 'aws-cdk-lib/aws-kms'; + +let app: cdk.App; +let organizationsStackDefault: OrganizationsStack; +let organizationsStackCT: OrganizationsStack; + +beforeEach(() => { + jest.spyOn(OrganizationsStack.prototype, 'getCentralLogBucketName').mockImplementation(() => 'unitTestLogBucket'); + jest.spyOn(OrganizationsStack.prototype, 'getSsmPath').mockImplementation(() => '/test/ssm-path/'); + jest.spyOn(OrganizationsStack.prototype, 'getAcceleratorKey').mockReturnValue({} as IKey); + jest.spyOn(OrganizationsStack.prototype, 'isIncluded').mockImplementation(() => true); + + app = new cdk.App(); + organizationsStackDefault = new OrganizationsStack(app, 'unit-test-Organizations-stack', createProps('us-east-1')); + organizationsStackCT = createStackWithControlTower(); +}); + +afterEach(() => { + jest.resetAllMocks(); +}); + +describe('OrganizationsStack cdk assert tests', () => { + test('Default stack has no AWS Control Tower Enabled Controls', () => { + const template = Template.fromStack(organizationsStackDefault); + template.resourceCountIs('AWS::ControlTower::EnabledControl', 0); + }); + + test('Stack contains 6 Control Tower enabled controls', () => { + const template = Template.fromStack(organizationsStackCT); + template.resourceCountIs('AWS::ControlTower::EnabledControl', 6); + }); + + test('Stack contains 5 dependsOn properties for AWS::ControlTower::EnabledControl', () => { + const template = Template.fromStack(organizationsStackCT); + const dependsOnCapture = new Capture(); + template.findResources('AWS::ControlTower::EnabledControl', { + DependsOn: dependsOnCapture, + }); + let dependsOnCount = 0; + do { + dependsOnCount++; + } while (dependsOnCapture.next()); + expect(dependsOnCount).toBe(5); + }); +}); + +function createProps(homeRegion: string, controlTowerConfig?: ControlTowerConfig): OrganizationsStackProps { + const mockOrganizationConfig = { + getOrganizationId: jest.fn().mockImplementation(() => '1234567890'), + getOrganizationalUnitArn: jest + .fn() + .mockImplementation(ouName => `arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/${ouName}`), + enable: true, + backupPolicies: [], + taggingPolicies: [], + } as unknown as OrganizationConfig; + const mockAccountsConfig = { + getAccountId: jest.fn().mockImplementation(() => '100000'), + getAccountIds: jest.fn().mockImplementation(() => ['100000']), + getManagementAccountId: jest.fn().mockImplementation(() => '200000'), + getLogArchiveAccountId: jest.fn().mockImplementation(() => '300000'), + mandatoryAccounts: [], + workloadAccounts: [], + } as unknown as AccountsConfig; + const mockLoggingConfig = { + cloudwatchLogs: undefined, + sessionManager: { + sendToCloudWatchLogs: false, + sendToS3: false, + }, + cloudtrail: { + enable: false, + }, + } as LoggingConfig; + const mockNetworkConfig = { + vpcs: [], + } as unknown as NetworkConfig; + + const props: OrganizationsStackProps = { + accountsConfig: mockAccountsConfig, + configDirPath: '../configs', + globalConfig: { + logging: mockLoggingConfig, + homeRegion: homeRegion, + controlTower: controlTowerConfig ?? new ControlTowerConfig(), + } as GlobalConfig, + iamConfig: { + userSets: [new UserSetConfig()], + groupSets: [new GroupSetConfig()], + } as IamConfig, + networkConfig: mockNetworkConfig, + organizationConfig: mockOrganizationConfig, + securityConfig: { + centralSecurityServices: { + delegatedAdminAccount: 'account1', + auditManager: {}, + detective: {}, + macie: { + enable: false, + }, + guardduty: { + enable: false, + }, + securityHub: { + enable: false, + }, + }, + accessAnalyzer: { + enable: false, + }, + awsConfig: { + aggregation: { + enable: false, + }, + }, + } as unknown as SecurityConfig, + customizationsConfig: {} as CustomizationsConfig, + replacementsConfig: {} as ReplacementsConfig, + partition: 'unit-test', + configRepositoryName: 'unit-test', + configRepositoryLocation: 's3', + globalRegion: 'us-east-1', + centralizedLoggingRegion: 'us-east-1', + prefixes: {} as AcceleratorResourcePrefixes, + enableSingleAccountMode: true, + useExistingRoles: false, + isDiagnosticsPackEnabled: 'false', + pipelineAccountId: '1234567890', + env: { + region: 'us-east-1', + account: '100000', + }, + }; + + return props; +} + +function createStackWithControlTower() { + const controlTowerConfig: ControlTowerConfig = { + enable: true, + landingZone: undefined, + controls: [ + { + deploymentTargets: { + organizationalUnits: ['OU1', 'OU2'], + accounts: [], + + excludedRegions: [], + excludedAccounts: [], + }, + identifier: 'AWS-GR_1', + enable: true, + regions: [], + }, + { + deploymentTargets: { + organizationalUnits: ['OU1', 'OU2'], + accounts: [], + + excludedRegions: [], + excludedAccounts: [], + }, + identifier: 'AWS-GR_2', + enable: true, + regions: [], + }, + { + deploymentTargets: { + organizationalUnits: ['OU1', 'OU2'], + accounts: [], + + excludedRegions: [], + excludedAccounts: [], + }, + identifier: 'AWS-GR_3', + enable: true, + regions: [], + }, + { + deploymentTargets: { + organizationalUnits: ['OU1'], + accounts: [], + + excludedRegions: [], + excludedAccounts: [], + }, + identifier: 'AWS-GR_5', + enable: false, + regions: [], + }, + ], + }; + + return new OrganizationsStack(app, 'unit-test-Organizations-stack-CT', createProps('us-east-1', controlTowerConfig)); +} diff --git a/source/packages/@aws-accelerator/config/package.json b/source/packages/@aws-accelerator/config/package.json index f87b2f80d..530a609b9 100644 --- a/source/packages/@aws-accelerator/config/package.json +++ b/source/packages/@aws-accelerator/config/package.json @@ -8,7 +8,6 @@ "name": "Amazon Web Services", "url": "https://aws.amazon.com/solutions" }, - "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "yarn schema:accounts && yarn schema:global && yarn schema:iam && yarn schema:organization && yarn schema:security && yarn schema:replacements && yarn schema:customizations && yarn schema:network && tsc", @@ -61,4 +60,4 @@ "reportFile": "test-report.xml", "indent": 4 } -} \ No newline at end of file +} diff --git a/source/packages/@aws-accelerator/constructs/index.ts b/source/packages/@aws-accelerator/constructs/index.ts index c0ac176bf..cdb009a28 100644 --- a/source/packages/@aws-accelerator/constructs/index.ts +++ b/source/packages/@aws-accelerator/constructs/index.ts @@ -25,6 +25,7 @@ export * from './lib/data-perimeter/detect-resource-policy'; export * from './lib/data-perimeter/remediate-resource-policy'; export * from './lib/data-perimeter/remediation-ssm-document'; export * from './lib/aws-controltower/create-accounts'; +export * from './lib/aws-controltower/create-enabled-controls'; export * from './lib/aws-cur/report-definition'; export * from './lib/aws-detective/detective-graph-config'; export * from './lib/aws-detective/detective-members'; diff --git a/source/packages/@aws-accelerator/constructs/lib/aws-accelerator/get-accelerator-metadata/index.ts b/source/packages/@aws-accelerator/constructs/lib/aws-accelerator/get-accelerator-metadata/index.ts index 2c970e26b..5cec9eb7f 100644 --- a/source/packages/@aws-accelerator/constructs/lib/aws-accelerator/get-accelerator-metadata/index.ts +++ b/source/packages/@aws-accelerator/constructs/lib/aws-accelerator/get-accelerator-metadata/index.ts @@ -23,10 +23,10 @@ import { } from '@aws-sdk/client-codecommit'; import { CodePipelineClient, - ListPipelineExecutionsCommand, GetPipelineExecutionCommand, ListPipelineExecutionsCommandOutput, PipelineExecutionSummary, + paginateListPipelineExecutions, } from '@aws-sdk/client-codepipeline'; import { ListObjectsV2Command, @@ -513,15 +513,12 @@ function findSuccessfulPipelineExecution( } async function getLastSuccessfulPipelineExecution(codePipelineClient: CodePipelineClient, pipelineName: string) { - let nextToken: string | undefined; let lastSuccessfulExecution: PipelineExecutionSummary | undefined; - do { - const executions = await throttlingBackOff(() => - codePipelineClient.send(new ListPipelineExecutionsCommand({ pipelineName, nextToken })), - ); - lastSuccessfulExecution = findSuccessfulPipelineExecution(executions); - nextToken = executions.nextToken; - } while (nextToken || !lastSuccessfulExecution); + const paginator = paginateListPipelineExecutions({ client: codePipelineClient }, { pipelineName }); + + for await (const page of paginator) { + lastSuccessfulExecution = findSuccessfulPipelineExecution(page) ?? lastSuccessfulExecution; + } return lastSuccessfulExecution; } diff --git a/source/packages/@aws-accelerator/constructs/lib/aws-controltower/create-enabled-controls.ts b/source/packages/@aws-accelerator/constructs/lib/aws-controltower/create-enabled-controls.ts new file mode 100644 index 000000000..f01e84ca3 --- /dev/null +++ b/source/packages/@aws-accelerator/constructs/lib/aws-controltower/create-enabled-controls.ts @@ -0,0 +1,127 @@ +import * as cdk from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import { pascalCase } from 'pascal-case'; + +/** + * Interface representing the properties required to enable a Control Tower control. + * + * @interface EnabledControlProps + * + * @property ouName - The name of the organizational unit where the control will be enabled + * @property ouArn - The Amazon Resource Name (ARN) of the organizational unit + * @property enabledControlIdentifier - The unique identifier for the Control Tower control to be enabled + * + * @example + * const props: EnabledControlProps = { + * ouName: 'SecurityOU', + * ouArn: 'arn:aws:organizations::123456789012:ou/o-abcd1234/ou-abcd-12345678', + * enabledControlIdentifier: 'AWS-GR_ELASTICSEARCH_IN_VPC_ONLY' + * }; + * @link https://docs.aws.amazon.com/controltower/latest/controlreference/all-global-identifiers.html + */ +export interface EnabledControlProps { + ouName: string; + ouArn: string; + enabledControlIdentifier: string; +} + +/** + * Interface defining the configuration properties for creating enabled Control Tower controls. + * + * @interface CreateEnabledControlProps + * + * @property controls - Array of EnabledControlProps containing the configuration for each control to be enabled + * @property dependencyFrequency - Number that determines the frequency of creating dependency chains between controls + * + * @example + * const props: CreateEnabledControlProps = { + * controls: [{ + * ouName: 'SecurityOU', + * ouArn: 'arn:aws:organizations::123456789012:ou/o-abcd1234/ou-abcd-12345678', + * enabledControlIdentifier: 'AWS-GR_ELASTICSEARCH_IN_VPC_ONLY' + * }], + * dependencyFrequency: 3 + * }; + */ + +export interface CreateEnabledControlProps { + controls: EnabledControlProps[]; + dependencyFrequency?: number; +} + +/** + * Enables Control Tower controls based on the provided configuration. + * This class filters enabled controls, creates them, and sets up their dependencies. + * Only optional controls are supported (both Strongly Recommended and Elective) + * https://docs.aws.amazon.com/controltower/latest/userguide/optional-controls.html + **/ + +export class CreateControlTowerEnabledControls extends Construct { + readonly controlTowerControls: cdk.aws_controltower.CfnEnabledControl[]; + readonly dependencyFrequency: number; + constructor(scope: Construct, id: string, props: CreateEnabledControlProps) { + super(scope, id); + this.controlTowerControls = this.enableControlTowerControls(props.controls); + this.dependencyFrequency = props.dependencyFrequency ?? 2; + this.setEnabledControlDependencies(this.controlTowerControls, this.dependencyFrequency); + } + /* + + + * @param controlTowerConfig - The Control Tower configuration object containing control settings + * @returns void + * @private + */ + + private enableControlTowerControls(controls: EnabledControlProps[]) { + return controls.map(control => { + const enabledControlArn = `arn:${cdk.Stack.of(this).partition}:controltower:${ + cdk.Stack.of(this).region + }::control/${control.enabledControlIdentifier}`; + + return new cdk.aws_controltower.CfnEnabledControl( + // Scope is set to the parent stack to maintain logical IDs of already deployed resources. Do not change this value! + cdk.Stack.of(this), + pascalCase(`${control.enabledControlIdentifier}-${control.ouName}`), + { + controlIdentifier: enabledControlArn, + targetIdentifier: control.ouArn, + }, + ); + }); + } + + /** + * Sets up dependencies between Control Tower enabled controls. This is needed to prevent throttling errors when cloudformation deploys the resource + * + * @param enabledControls - Array of Control Tower enabled controls to configure dependencies for + * @param dependencyFrequency - Number that determines how often to create new dependency chains + * @private + **/ + + private setEnabledControlDependencies( + enabledControls: cdk.aws_controltower.CfnEnabledControl[], + dependencyFrequency: number, + ) { + if (enabledControls.length === 0) { + return; + } + + if (dependencyFrequency === 0) { + return; + } + + let dependency: cdk.aws_controltower.CfnEnabledControl = enabledControls[0]; + for (let i = 0; i < enabledControls.length; i++) { + if (i === 0) { + continue; + } + if (i % dependencyFrequency === 0) { + enabledControls[i].addDependency(dependency); + dependency = enabledControls[i]; + } else { + enabledControls[i].addDependency(dependency); + } + } + } +} diff --git a/source/packages/@aws-accelerator/constructs/lib/aws-route-53/hosted-zone.ts b/source/packages/@aws-accelerator/constructs/lib/aws-route-53/hosted-zone.ts index fcde90646..980ba893a 100644 --- a/source/packages/@aws-accelerator/constructs/lib/aws-route-53/hosted-zone.ts +++ b/source/packages/@aws-accelerator/constructs/lib/aws-route-53/hosted-zone.ts @@ -91,6 +91,9 @@ export class HostedZone extends cdk.Resource implements IHostedZone { case 'ecs-telemetry': hostedZoneName = `ecs-t.${region}.amazonaws.com`; break; + case 'eks-auth': + hostedZoneName = `eks-auth.${region}.api.aws`; + break; case 'codeartifact.api': hostedZoneName = `codeartifact.${region}.amazonaws.com`; break; @@ -103,6 +106,12 @@ export class HostedZone extends cdk.Resource implements IHostedZone { case 'studio': hostedZoneName = `${service}.${region}.sagemaker.aws`; break; + case 'sagemaker.api': + hostedZoneName = `api.sagemaker.${region}.sagemaker.aws`; + break; + case 'sagemaker.runtime': + hostedZoneName = `runtime.sagemaker.${region}.sagemaker.aws`; + break; } return hostedZoneName; } @@ -116,10 +125,13 @@ export class HostedZone extends cdk.Resource implements IHostedZone { 's3-global.accesspoint', 'ecs-agent', 'ecs-telemetry', + 'eks-auth', 'notebook', 'studio', 'codeartifact.api', 'codeartifact.repositories', + 'sagemaker.api', + 'sagemaker.runtime', ]; return ignoreServicesArray.includes(service); } diff --git a/source/packages/@aws-accelerator/constructs/test/aws-controltower/__snapshots__/create-enabled-controls.test.ts.snap b/source/packages/@aws-accelerator/constructs/test/aws-controltower/__snapshots__/create-enabled-controls.test.ts.snap new file mode 100644 index 000000000..65be29a9c --- /dev/null +++ b/source/packages/@aws-accelerator/constructs/test/aws-controltower/__snapshots__/create-enabled-controls.test.ts.snap @@ -0,0 +1,131 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TestCreateCTControls Construct(TestCreateCTControls): Snapshot Test 1`] = ` +{ + "Resources": { + "AwsGrAuditBucketPolicyChangesProhibitedExampleOu": { + "DependsOn": [ + "AwsGrCtAuditBucketPolicyChangesProhibitedExampleOu", + ], + "Properties": { + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_AUDIT_BUCKET_POLICY_CHANGES_PROHIBITED", + ], + ], + }, + "TargetIdentifier": "arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6", + }, + "Type": "AWS::ControlTower::EnabledControl", + }, + "AwsGrCloudtrailValidationEnabledExampleOu": { + "DependsOn": [ + "AwsGrDisallowCrossRegionNetworkingExampleOu", + ], + "Properties": { + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_CLOUDTRAIL_VALIDATION_ENABLED", + ], + ], + }, + "TargetIdentifier": "arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6", + }, + "Type": "AWS::ControlTower::EnabledControl", + }, + "AwsGrCtAuditBucketPolicyChangesProhibitedExampleOu": { + "Properties": { + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_CT_AUDIT_BUCKET_POLICY_CHANGES_PROHIBITED", + ], + ], + }, + "TargetIdentifier": "arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6", + }, + "Type": "AWS::ControlTower::EnabledControl", + }, + "AwsGrDisallowCrossRegionNetworkingExampleOu": { + "DependsOn": [ + "AwsGrAuditBucketPolicyChangesProhibitedExampleOu", + ], + "Properties": { + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_DISALLOW_CROSS_REGION_NETWORKING", + ], + ], + }, + "TargetIdentifier": "arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6", + }, + "Type": "AWS::ControlTower::EnabledControl", + }, + "AwsGrLambdaChangeProhibitedExampleOu": { + "DependsOn": [ + "AwsGrAuditBucketPolicyChangesProhibitedExampleOu", + ], + "Properties": { + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_LAMBDA_CHANGE_PROHIBITED", + ], + ], + }, + "TargetIdentifier": "arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6", + }, + "Type": "AWS::ControlTower::EnabledControl", + }, + "AwsGrSnsChangeProhibitedExampleOu": { + "DependsOn": [ + "AwsGrCtAuditBucketPolicyChangesProhibitedExampleOu", + ], + "Properties": { + "ControlIdentifier": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":controltower:us-east-1::control/AWS-GR_SNS_CHANGE_PROHIBITED", + ], + ], + }, + "TargetIdentifier": "arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6", + }, + "Type": "AWS::ControlTower::EnabledControl", + }, + }, +} +`; diff --git a/source/packages/@aws-accelerator/constructs/test/aws-controltower/create-enabled-controls.test.ts b/source/packages/@aws-accelerator/constructs/test/aws-controltower/create-enabled-controls.test.ts new file mode 100644 index 000000000..ee0a0409d --- /dev/null +++ b/source/packages/@aws-accelerator/constructs/test/aws-controltower/create-enabled-controls.test.ts @@ -0,0 +1,67 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +import * as cdk from 'aws-cdk-lib'; +import { + CreateControlTowerEnabledControls, + EnabledControlProps, +} from '../../lib/aws-controltower/create-enabled-controls'; +import { snapShotTest } from '../snapshot-test'; + +const testNamePrefix = 'Construct(TestCreateCTControls): '; + +const app = new cdk.App(); + +// Create stack for native Cfn construct +const env = { account: '333333333333', region: 'us-east-1' }; +const stack = new cdk.Stack(app, 'Stack', { env: env }); +const controls: EnabledControlProps[] = [ + { + enabledControlIdentifier: 'AWS-GR_CT_AUDIT_BUCKET_POLICY_CHANGES_PROHIBITED', + ouArn: 'arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6', + ouName: 'ExampleOU', + }, + { + enabledControlIdentifier: 'AWS-GR_SNS_CHANGE_PROHIBITED', + ouArn: 'arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6', + ouName: 'ExampleOU', + }, + { + enabledControlIdentifier: 'AWS-GR_AUDIT_BUCKET_POLICY_CHANGES_PROHIBITED', + ouArn: 'arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6', + ouName: 'ExampleOU', + }, + { + enabledControlIdentifier: 'AWS-GR_LAMBDA_CHANGE_PROHIBITED', + ouArn: 'arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6', + ouName: 'ExampleOU', + }, + { + enabledControlIdentifier: 'AWS-GR_DISALLOW_CROSS_REGION_NETWORKING', + ouArn: 'arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6', + ouName: 'ExampleOU', + }, + { + enabledControlIdentifier: 'AWS-GR_CLOUDTRAIL_VALIDATION_ENABLED', + ouArn: 'arn:aws:organizations::123456789012:ou/o-a1b2c3d4e5/ou-ab12-c3d4e5f6', + ouName: 'ExampleOU', + }, +]; +new CreateControlTowerEnabledControls(stack, 'TestCreateCTControls', { + dependencyFrequency: 2, + controls, +}); + +describe('TestCreateCTControls', () => { + snapShotTest(testNamePrefix, stack); +}); diff --git a/source/packages/@aws-accelerator/installer/lib/installer-stack.ts b/source/packages/@aws-accelerator/installer/lib/installer-stack.ts index a4fff4a3d..abe063b7d 100644 --- a/source/packages/@aws-accelerator/installer/lib/installer-stack.ts +++ b/source/packages/@aws-accelerator/installer/lib/installer-stack.ts @@ -864,9 +864,13 @@ export class InstallerStack extends cdk.Stack { `set -e && if [ "$BOOTSTRAPPED_HOME" = "no" ]; then yarn run cdk bootstrap --toolkitStackName ${acceleratorPrefix}-CDKToolkit aws://${cdk.Aws.ACCOUNT_ID}/${cdk.Aws.REGION} --qualifier accel; fi`, `set -e && if [ "$BOOTSTRAPPED_GLOBAL" = "no" ]; then yarn run cdk bootstrap --toolkitStackName ${acceleratorPrefix}-CDKToolkit aws://${cdk.Aws.ACCOUNT_ID}/${globalRegion} --qualifier accel; fi`, `set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:${ + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:${ cdk.Stack.of(this).partition - }:iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + }:iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ${acceleratorPrefix}-CDKToolkit --region ${ cdk.Aws.REGION }; then MGMT_BOOTSTRAPPED_HOME="no"; fi; diff --git a/source/packages/@aws-accelerator/installer/test/__snapshots__/installer.test.ts.snap b/source/packages/@aws-accelerator/installer/test/__snapshots__/installer.test.ts.snap index 4cc0c35b2..a1c250faa 100644 --- a/source/packages/@aws-accelerator/installer/test/__snapshots__/installer.test.ts.snap +++ b/source/packages/@aws-accelerator/installer/test/__snapshots__/installer.test.ts.snap @@ -274,7 +274,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 1`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.10.0", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -1912,11 +1912,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -2831,7 +2835,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -4006,7 +4010,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 2`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.9.1", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -5634,11 +5638,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -6553,7 +6561,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -7761,7 +7769,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 3`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.9.1", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -9414,11 +9422,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -10345,7 +10357,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -11536,7 +11548,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 4`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.9.1", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -13179,11 +13191,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -14110,7 +14126,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -15301,7 +15317,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 5`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.9.1", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -16949,11 +16965,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -17880,7 +17900,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -19050,7 +19070,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 6`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.9.1", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -20685,11 +20705,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -21604,7 +21628,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, @@ -22800,7 +22824,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 7`] = ` "RepositoryBranchName": { "AllowedPattern": ".+", "ConstraintDescription": "The repository branch name must not be empty", - "Default": "release/v1.9.1", + "Default": "release/v1.10.1", "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features.", "Type": "String", }, @@ -22814,7 +22838,7 @@ exports[`InstallerStack Stack(installer): Snapshot Test 7`] = ` "Type": "String", }, "RepositoryBucketObject": { - "Default": "release/v1.9.1.zip", + "Default": "release/v1.10.1.zip", "Description": "The full path to the accelerator code zip S3 Object. (S3 Only)", "Type": "String", }, @@ -24464,11 +24488,15 @@ phases: " --qualifier accel; fi - |- set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = "yes" ]; then - export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $(aws sts assume-role --role-arn arn:", + if ! MANAGEMENT_ACCOUNT_CREDENTIAL=$(aws sts assume-role --role-arn arn:", { "Ref": "AWS::Partition", }, - ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text)); + ":iam::"$MANAGEMENT_ACCOUNT_ID":role/"$MANAGEMENT_ACCOUNT_ROLE_NAME" --role-session-name acceleratorAssumeRoleSession --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text); then + echo "Failed to assume $MANAGEMENT_ACCOUNT_ROLE_NAME role in management account $MANAGEMENT_ACCOUNT_ID" + exit 1 + fi + export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $MANAGEMENT_ACCOUNT_CREDENTIAL); if ! aws cloudformation describe-stacks --stack-name ", { "Fn::GetAtt": [ @@ -25720,7 +25748,7 @@ phases: ], }, "Type": "String", - "Value": "1.9.1", + "Value": "1.10.1", }, "Type": "AWS::SSM::Parameter", }, diff --git a/source/packages/@aws-accelerator/tools/lib/classes/accelerator-tool.ts b/source/packages/@aws-accelerator/tools/lib/classes/accelerator-tool.ts index 71c3cefc2..a826c3e6a 100644 --- a/source/packages/@aws-accelerator/tools/lib/classes/accelerator-tool.ts +++ b/source/packages/@aws-accelerator/tools/lib/classes/accelerator-tool.ts @@ -364,6 +364,7 @@ export class AcceleratorTool { const installerPipeline = await AcceleratorTool.getPipelineNameFromCloudFormationStack(installerStackName); if (!installerPipeline.status) { this.debugLog(`${installerPipeline.pipelineName}`, 'info'); + this.logger.error(`${installerPipeline.pipelineName} doesn't exist, cannot continue`); return false; } const getPipelineNameResponse = await throttlingBackOff(() => diff --git a/source/packages/@aws-accelerator/utils/lib/ssm-parameter-path.ts b/source/packages/@aws-accelerator/utils/lib/ssm-parameter-path.ts index 2844370a5..553f4c724 100644 --- a/source/packages/@aws-accelerator/utils/lib/ssm-parameter-path.ts +++ b/source/packages/@aws-accelerator/utils/lib/ssm-parameter-path.ts @@ -421,6 +421,12 @@ export enum SsmResourceType { * `${0}` is replaced with the Firewall Instance Name */ FIREWALL_INSTANCE = '/network/ec2/firewall/instanceName/${0}/instanceId', + /** + * Firewall ENI + * `${0}` is replaced with the Firewall Instance Name + * ``${1}` is replaced with the Firewall ENI Index + */ + FIREWALL_ENI = '/network/ec2/firewall/instanceName/${0}/eni/${1}', /** * Managed AD Directory Id * `${0}` is replaced with the Directory Friendly Name