@@ -551,6 +551,34 @@ def create_event(event, context):
551551 DRY_RUN_DATA [f"{ filter } _CloudWatch" ] = "DRY_RUN: Filter deploy parameter is 'false'; Skip CloudWatch metric filter deployment"
552552
553553 # 5) Central CloudWatch Observability
554+ # TODO(liamschn): determine if we need the CloudWatch-CrossAccountListAccountsRole (needed for "Enable account selector"?).
555+ # TRUST
556+ # {
557+ # "Version": "2012-10-17",
558+ # "Statement": [
559+ # {
560+ # "Effect": "Allow",
561+ # "Principal": {
562+ # "AWS": "arn:aws:iam::533267199951:root"
563+ # },
564+ # "Action": "sts:AssumeRole"
565+ # }
566+ # ]
567+ # }
568+ # PERMISSIONS
569+ # {
570+ # "Version": "2012-10-17",
571+ # "Statement": [
572+ # {
573+ # "Action": [
574+ # "organizations:ListAccounts",
575+ # "organizations:ListAccountsForParent"
576+ # ],
577+ # "Resource": "*",
578+ # "Effect": "Allow"
579+ # }
580+ # ]
581+ # }
554582 central_observability_params = json .loads (event ["ResourceProperties" ]["SRA-BEDROCK-CENTRAL-OBSERVABILITY" ])
555583 # TODO(liamschn): create a parameter to choose to deploy central observability or not: deploy_central_observability = true/false
556584 # 5a) OAM Sink in security account
@@ -607,60 +635,63 @@ def create_event(event, context):
607635 LOGGER .info ("CloudWatch observability access manager sink policy is correct" )
608636
609637 # 5c) OAM CloudWatch-CrossAccountSharingRole IAM role
638+ # Add management account to the bedrock accounts list
639+ central_observability_params ["bedrock_accounts" ].append (sts .MANAGEMENT_ACCOUNT )
610640 for bedrock_account in central_observability_params ["bedrock_accounts" ]:
611- iam .IAM_CLIENT = sts .assume_role (bedrock_account , sts .CONFIGURATION_ROLE , "iam" , iam .get_iam_global_region ())
612- cloudwatch .CROSS_ACCOUNT_TRUST_POLICY = CLOUDWATCH_OAM_TRUST_POLICY [cloudwatch .CROSS_ACCOUNT_ROLE_NAME ]
613- cloudwatch .CROSS_ACCOUNT_TRUST_POLICY ["Statement" ][0 ]["Principal" ]["AWS" ] = \
614- cloudwatch .CROSS_ACCOUNT_TRUST_POLICY ["Statement" ][0 ]["Principal" ]["AWS" ].replace ("<SECURITY_ACCOUNT>" , SECURITY_ACCOUNT )
615- search_iam_role = iam .check_iam_role_exists (cloudwatch .CROSS_ACCOUNT_ROLE_NAME )
616- if search_iam_role [0 ] is False :
617- LOGGER .info (f"CloudWatch observability access manager cross-account role not found, creating { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role..." )
618- if DRY_RUN is False :
619- iam .create_role (cloudwatch .CROSS_ACCOUNT_ROLE_NAME , cloudwatch .CROSS_ACCOUNT_TRUST_POLICY , SOLUTION_NAME )
620- LIVE_RUN_DATA ["OAMCrossAccountRoleCreate" ] = f"Created { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
621- CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
622- CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] += 1
623- LOGGER .info (f"Created { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role" )
624- else :
625- DRY_RUN_DATA ["OAMCrossAccountRoleCreate" ] = f"DRY_RUN: Create { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
626- else :
627- LOGGER .info (f"CloudWatch observability access manager cross-account role found: { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } " )
628-
629- # 5d) Attach managed policies to CloudWatch-CrossAccountSharingRole IAM role
630- cross_account_policies = [
631- "arn:aws:iam::aws:policy/AWSXrayReadOnlyAccess" ,
632- "arn:aws:iam::aws:policy/CloudWatchAutomaticDashboardsAccess" ,
633- "arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess"
634- ]
635- for policy_arn in cross_account_policies :
636- search_attached_policies = iam .check_iam_policy_attached (cloudwatch .CROSS_ACCOUNT_ROLE_NAME , policy_arn )
637- if search_attached_policies is False :
638- LOGGER .info (f"Attaching { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role..." )
641+ for bedrock_region in central_observability_params ["regions" ]:
642+ iam .IAM_CLIENT = sts .assume_role (bedrock_account , sts .CONFIGURATION_ROLE , "iam" , iam .get_iam_global_region ())
643+ cloudwatch .CROSS_ACCOUNT_TRUST_POLICY = CLOUDWATCH_OAM_TRUST_POLICY [cloudwatch .CROSS_ACCOUNT_ROLE_NAME ]
644+ cloudwatch .CROSS_ACCOUNT_TRUST_POLICY ["Statement" ][0 ]["Principal" ]["AWS" ] = \
645+ cloudwatch .CROSS_ACCOUNT_TRUST_POLICY ["Statement" ][0 ]["Principal" ]["AWS" ].replace ("<SECURITY_ACCOUNT>" , SECURITY_ACCOUNT )
646+ search_iam_role = iam .check_iam_role_exists (cloudwatch .CROSS_ACCOUNT_ROLE_NAME )
647+ if search_iam_role [0 ] is False :
648+ LOGGER .info (f"CloudWatch observability access manager cross-account role not found, creating { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role..." )
639649 if DRY_RUN is False :
640- iam .attach_policy (cloudwatch .CROSS_ACCOUNT_ROLE_NAME , policy_arn )
641- LIVE_RUN_DATA ["OAMCrossAccountRolePolicyAttach " ] = f"Attached { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
650+ iam .create_role (cloudwatch .CROSS_ACCOUNT_ROLE_NAME , cloudwatch . CROSS_ACCOUNT_TRUST_POLICY , SOLUTION_NAME )
651+ LIVE_RUN_DATA ["OAMCrossAccountRoleCreate " ] = f"Created { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
642652 CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
643- CFN_RESPONSE_DATA ["deployment_info" ]["configuration_changes " ] += 1
644- LOGGER .info (f"Attached { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role" )
653+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed " ] += 1
654+ LOGGER .info (f"Created { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role" )
645655 else :
646- DRY_RUN_DATA ["OAMCrossAccountRolePolicyAttach" ] = f"DRY_RUN: Attach { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
656+ DRY_RUN_DATA ["OAMCrossAccountRoleCreate" ] = f"DRY_RUN: Create { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
657+ else :
658+ LOGGER .info (f"CloudWatch observability access manager cross-account role found: { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } " )
659+
660+ # 5d) Attach managed policies to CloudWatch-CrossAccountSharingRole IAM role
661+ cross_account_policies = [
662+ "arn:aws:iam::aws:policy/AWSXrayReadOnlyAccess" ,
663+ "arn:aws:iam::aws:policy/CloudWatchAutomaticDashboardsAccess" ,
664+ "arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess"
665+ ]
666+ for policy_arn in cross_account_policies :
667+ search_attached_policies = iam .check_iam_policy_attached (cloudwatch .CROSS_ACCOUNT_ROLE_NAME , policy_arn )
668+ if search_attached_policies is False :
669+ LOGGER .info (f"Attaching { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role..." )
670+ if DRY_RUN is False :
671+ iam .attach_policy (cloudwatch .CROSS_ACCOUNT_ROLE_NAME , policy_arn )
672+ LIVE_RUN_DATA ["OAMCrossAccountRolePolicyAttach" ] = f"Attached { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
673+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
674+ CFN_RESPONSE_DATA ["deployment_info" ]["configuration_changes" ] += 1
675+ LOGGER .info (f"Attached { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role" )
676+ else :
677+ DRY_RUN_DATA ["OAMCrossAccountRolePolicyAttach" ] = f"DRY_RUN: Attach { policy_arn } policy to { cloudwatch .CROSS_ACCOUNT_ROLE_NAME } IAM role"
647678
648- # 5d) OAM link
649- cloudwatch .CWOAM_CLIENT = sts .assume_role (bedrock_account , sts .CONFIGURATION_ROLE , "cloudwatch" , region )
650- search_oam_link = cloudwatch .find_oam_link (oam_sink_arn )
651- if search_oam_link [0 ] is False :
652- if DRY_RUN is False :
653- LOGGER .info ("CloudWatch observability access manager link not found, creating..." )
654- cloudwatch .create_oam_link (oam_sink_arn )
655- LIVE_RUN_DATA ["OAMLinkCreate" ] = "Created CloudWatch observability access manager link"
656- CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
657- CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] += 1
658- LOGGER .info ("Created CloudWatch observability access manager link" )
679+ # 5d) OAM link in bedrock account
680+ cloudwatch .CWOAM_CLIENT = sts .assume_role (bedrock_account , sts .CONFIGURATION_ROLE , "cloudwatch" , bedrock_region )
681+ search_oam_link = cloudwatch .find_oam_link (oam_sink_arn )
682+ if search_oam_link [0 ] is False :
683+ if DRY_RUN is False :
684+ LOGGER .info ("CloudWatch observability access manager link not found, creating..." )
685+ cloudwatch .create_oam_link (oam_sink_arn )
686+ LIVE_RUN_DATA ["OAMLinkCreate" ] = "Created CloudWatch observability access manager link"
687+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
688+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] += 1
689+ LOGGER .info ("Created CloudWatch observability access manager link" )
690+ else :
691+ LOGGER .info ("DRY_RUN: CloudWatch observability access manager link not found, creating..." )
692+ DRY_RUN_DATA ["OAMLinkCreate" ] = "DRY_RUN: Create CloudWatch observability access manager link"
659693 else :
660- LOGGER .info ("DRY_RUN: CloudWatch observability access manager link not found, creating..." )
661- DRY_RUN_DATA ["OAMLinkCreate" ] = "DRY_RUN: Create CloudWatch observability access manager link"
662- else :
663- LOGGER .info ("CloudWatch observability access manager link found" )
694+ LOGGER .info ("CloudWatch observability access manager link found" )
664695
665696 # End
666697 # TODO(liamschn): Consider the 256 KB limit for any cloudwatch log message
0 commit comments