<filename>BIOps_Deployment_Scripts/quicksight-deployment-cdk-slim/cdk/quicksight_target_stack.py
import os
import json
from aws_cdk import aws_iam as iam, aws_ssm as ssm, core
from aws_cdk.custom_resources import (
    AwsCustomResource,
    AwsCustomResourcePolicy,
    PhysicalResourceId,
    AwsSdkCall,
)


class QuicksightTargetStack(core.Stack):
    def __init__(
        self, scope: core.Construct, id: str, central_account, **kwargs
    ) -> None:
        super().__init__(scope, id, **kwargs)
        self.current_dir = os.path.dirname(__file__)

        # Change to your central account
        self.central_account_id = central_account

        self.quicksight_migration_target_assume_role = iam.Role(
            self,
            "quicksight-migration-target-assume-role",
            description="Role for the Quicksight dashboard migration Lambda function to assume",
            role_name="quicksight-migration-target-assume-role",
            max_session_duration=core.Duration.seconds(3600),
            assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
            inline_policies={
                "AllowAccess": iam.PolicyDocument(
                    statements=[
                        iam.PolicyStatement(
                            effect=iam.Effect.ALLOW,
                            actions=[
                                "quicksight:*",
                            ],
                            resources=["*"],
                        ),
                        iam.PolicyStatement(
                            effect=iam.Effect.ALLOW,
                            actions=[
                                "ssm:GetParameter",
                            ],
                            resources=[
                                f"arn:aws:ssm:{core.Aws.REGION}:{core.Aws.ACCOUNT_ID}:parameter/infra/config"
                            ],
                        ),
                        iam.PolicyStatement(
                            effect=iam.Effect.ALLOW,
                            actions=["secretsmanager:GetSecretValue"],
                            resources=[
                                f"arn:aws:secretsmanager:{core.Aws.REGION}:{core.Aws.ACCOUNT_ID}:secret:*"
                            ],
                        ),
                    ]
                )
            },
        )

        self.quicksight_migration_target_assume_role.assume_role_policy.add_statements(
            iam.PolicyStatement(
                effect=iam.Effect.ALLOW,
                actions=["sts:AssumeRole"],
                principals=[iam.AccountPrincipal(self.central_account_id)],
            )
        )

        ssm.StringParameter(
            self,
            "InfraConfigParam",
            parameter_name="/infra/config",
            string_value=json.dumps(self.to_dict()),
        )

        self.quicksight_managed_resources_policy = iam.ManagedPolicy(
            self,
            "iam_policy",
            managed_policy_name="QuickSightMigrationPolicy",
            statements=[
                iam.PolicyStatement(
                    sid="AWSResourceAccess",
                    effect=iam.Effect.ALLOW,
                    actions=[
                        "iam:List*",
                        "redshift:Describe*",
                        "rds:Describe*",
                        "athena:Get*",
                        "athena:List*",
                        "athena:BatchGetQueryExecution",
                        "athena:StartQueryExecution",
                        "athena:StopQueryExecution",
                        "s3:GetBucketLocation",
                        "s3:GetObject",
                        "s3:ListBucket",
                        "s3:ListBucketMultipartUploads",
                        "s3:ListMultipartUploadParts",
                        "s3:AbortMultipartUpload",
                        "s3:CreateBucket",
                        "s3:PutObject",
                        "s3:PutBucketPublicAccessBlock",
                    ],
                    resources=["*"],
                ),
            ],
        )
        # create a custom resource that will create a quicksight user using the IAM target role
        self.qs_user = AwsCustomResource(
            self,
            "AWSCustomResourceQSUser",
            role=self.quicksight_migration_target_assume_role,
            policy=AwsCustomResourcePolicy.from_sdk_calls(
                resources=AwsCustomResourcePolicy.ANY_RESOURCE
            ),
            on_create=self.create_qsuser(),
            on_delete=self.delete_qsuser(),
            resource_type="Custom::QuickSightMigrationUser",
        )
        self.qs_user.node.add_dependency(self.quicksight_managed_resources_policy)

        # create a custom resource that will create a quicksight policy assignment
        self.qs_policy_assignment = AwsCustomResource(
            self,
            "AWSCustomResourceQSPolicyAssignment",
            role=self.quicksight_migration_target_assume_role,
            policy=AwsCustomResourcePolicy.from_sdk_calls(
                resources=AwsCustomResourcePolicy.ANY_RESOURCE
            ),
            on_create=self.create_policy_assignment(),
            on_delete=self.delete_policy_assignment(),
            resource_type="Custom::QuickSightPolicyAssignment",
        )
        self.qs_policy_assignment.node.add_dependency(self.qs_user)

    # create quicksight user
    def create_qsuser(self):
        create_params = {
            "IdentityType": "IAM",
            "Email": " ",
            "UserRole": "ADMIN",
            "IamArn": self.quicksight_migration_target_assume_role.role_arn,
            "SessionName": "quicksight",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
        }

        return AwsSdkCall(
            action="registerUser",
            service="QuickSight",
            parameters=create_params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_qsuser"),
        )

    # delete quicksight user
    def delete_qsuser(self):
        params = {
            "UserName": self.quicksight_migration_target_assume_role.role_name
            + "/quicksight",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
        }

        return AwsSdkCall(
            action="deleteUser",
            service="QuickSight",
            parameters=params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_qsuser"),
        )

    # create policy assignment
    def create_policy_assignment(self):
        create_params = {
            "AssignmentName": "QuickSightMigration",
            "AssignmentStatus": "ENABLED",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
            "Identities": {
                "user": [
                    self.quicksight_migration_target_assume_role.role_name
                    + "/quicksight"
                ]
            },
            "PolicyArn": self.quicksight_managed_resources_policy.managed_policy_arn,
        }

        return AwsSdkCall(
            action="createIAMPolicyAssignment",
            service="QuickSight",
            assumed_role_arn=self.quicksight_migration_target_assume_role.role_arn,
            parameters=create_params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_policyassignment"),
        )

    # delete policy assignment
    def delete_policy_assignment(self):
        delete_params = {
            "AssignmentName": "QuickSightMigration",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
        }

        return AwsSdkCall(
            action="deleteIAMPolicyAssignment",
            service="QuickSight",
            assumed_role_arn=self.quicksight_migration_target_assume_role.role_arn,
            parameters=delete_params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_policyassignment"),
        )

    def to_dict(self):
        config = {}
        config["vpcId"] = ""
        config["redshiftUsername"] = "admin"
        config["redshiftSecretId"] = ""
        config["redshiftClusterId"] = ""
        config["redshiftHost"] = ""
        config["redshiftDB"] = ""
        config["rdsUsername"] = "admin"
        config["rdsSecretId"] = ""
        config["rdsInstanceId"] = ""
        config["rdsDB"] = ""
        config["rdsPort"] = ""
        config["rdsPort"] = ""
        config["namespace"] = "default"
        config["version"] = "1"

        return config

<filename>BIOps_Deployment_Scripts/quicksight-deployment-cdk-slim/cdk/quicksight_target_stack.py
import os
import json
from aws_cdk import aws_iam as iam, aws_ssm as ssm, core
from aws_cdk.custom_resources import (
    AwsCustomResource,
    AwsCustomResourcePolicy,
    PhysicalResourceId,
    AwsSdkCall,
)


class QuicksightTargetStack(core.Stack):
    def __init__(
        self, scope: core.Construct, id: str, central_account, **kwargs
    ) -> None:
        super().__init__(scope, id, **kwargs)
        self.current_dir = os.path.dirname(__file__)

        # Change to your central account
        self.central_account_id = central_account

        self.quicksight_migration_target_assume_role = iam.Role(
            self,
            "quicksight-migration-target-assume-role",
            description="Role for the Quicksight dashboard migration Lambda function to assume",
            role_name="quicksight-migration-target-assume-role",
            max_session_duration=core.Duration.seconds(3600),
            assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
            inline_policies={
                "AllowAccess": iam.PolicyDocument(
                    statements=[
                        iam.PolicyStatement(
                            effect=iam.Effect.ALLOW,
                            actions=[
                                "quicksight:*",
                            ],
                            resources=["*"],
                        ),
                        iam.PolicyStatement(
                            effect=iam.Effect.ALLOW,
                            actions=[
                                "ssm:GetParameter",
                            ],
                            resources=[
                                f"arn:aws:ssm:{core.Aws.REGION}:{core.Aws.ACCOUNT_ID}:parameter/infra/config"
                            ],
                        ),
                        iam.PolicyStatement(
                            effect=iam.Effect.ALLOW,
                            actions=["secretsmanager:GetSecretValue"],
                            resources=[
                                f"arn:aws:secretsmanager:{core.Aws.REGION}:{core.Aws.ACCOUNT_ID}:secret:*"
                            ],
                        ),
                    ]
                )
            },
        )

        self.quicksight_migration_target_assume_role.assume_role_policy.add_statements(
            iam.PolicyStatement(
                effect=iam.Effect.ALLOW,
                actions=["sts:AssumeRole"],
                principals=[iam.AccountPrincipal(self.central_account_id)],
            )
        )

        ssm.StringParameter(
            self,
            "InfraConfigParam",
            parameter_name="/infra/config",
            string_value=json.dumps(self.to_dict()),
        )

        self.quicksight_managed_resources_policy = iam.ManagedPolicy(
            self,
            "iam_policy",
            managed_policy_name="QuickSightMigrationPolicy",
            statements=[
                iam.PolicyStatement(
                    sid="AWSResourceAccess",
                    effect=iam.Effect.ALLOW,
                    actions=[
                        "iam:List*",
                        "redshift:Describe*",
                        "rds:Describe*",
                        "athena:Get*",
                        "athena:List*",
                        "athena:BatchGetQueryExecution",
                        "athena:StartQueryExecution",
                        "athena:StopQueryExecution",
                        "s3:GetBucketLocation",
                        "s3:GetObject",
                        "s3:ListBucket",
                        "s3:ListBucketMultipartUploads",
                        "s3:ListMultipartUploadParts",
                        "s3:AbortMultipartUpload",
                        "s3:CreateBucket",
                        "s3:PutObject",
                        "s3:PutBucketPublicAccessBlock",
                    ],
                    resources=["*"],
                ),
            ],
        )
        # create a custom resource that will create a quicksight user using the IAM target role
        self.qs_user = AwsCustomResource(
            self,
            "AWSCustomResourceQSUser",
            role=self.quicksight_migration_target_assume_role,
            policy=AwsCustomResourcePolicy.from_sdk_calls(
                resources=AwsCustomResourcePolicy.ANY_RESOURCE
            ),
            on_create=self.create_qsuser(),
            on_delete=self.delete_qsuser(),
            resource_type="Custom::QuickSightMigrationUser",
        )
        self.qs_user.node.add_dependency(self.quicksight_managed_resources_policy)

        # create a custom resource that will create a quicksight policy assignment
        self.qs_policy_assignment = AwsCustomResource(
            self,
            "AWSCustomResourceQSPolicyAssignment",
            role=self.quicksight_migration_target_assume_role,
            policy=AwsCustomResourcePolicy.from_sdk_calls(
                resources=AwsCustomResourcePolicy.ANY_RESOURCE
            ),
            on_create=self.create_policy_assignment(),
            on_delete=self.delete_policy_assignment(),
            resource_type="Custom::QuickSightPolicyAssignment",
        )
        self.qs_policy_assignment.node.add_dependency(self.qs_user)

    # create quicksight user
    def create_qsuser(self):
        create_params = {
            "IdentityType": "IAM",
            "Email": " ",
            "UserRole": "ADMIN",
            "IamArn": self.quicksight_migration_target_assume_role.role_arn,
            "SessionName": "quicksight",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
        }

        return AwsSdkCall(
            action="registerUser",
            service="QuickSight",
            parameters=create_params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_qsuser"),
        )

    # delete quicksight user
    def delete_qsuser(self):
        params = {
            "UserName": self.quicksight_migration_target_assume_role.role_name
            + "/quicksight",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
        }

        return AwsSdkCall(
            action="deleteUser",
            service="QuickSight",
            parameters=params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_qsuser"),
        )

    # create policy assignment
    def create_policy_assignment(self):
        create_params = {
            "AssignmentName": "QuickSightMigration",
            "AssignmentStatus": "ENABLED",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
            "Identities": {
                "user": [
                    self.quicksight_migration_target_assume_role.role_name
                    + "/quicksight"
                ]
            },
            "PolicyArn": self.quicksight_managed_resources_policy.managed_policy_arn,
        }

        return AwsSdkCall(
            action="createIAMPolicyAssignment",
            service="QuickSight",
            assumed_role_arn=self.quicksight_migration_target_assume_role.role_arn,
            parameters=create_params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_policyassignment"),
        )

    # delete policy assignment
    def delete_policy_assignment(self):
        delete_params = {
            "AssignmentName": "QuickSightMigration",
            "AwsAccountId": core.Aws.ACCOUNT_ID,
            "Namespace": "default",
        }

        return AwsSdkCall(
            action="deleteIAMPolicyAssignment",
            service="QuickSight",
            assumed_role_arn=self.quicksight_migration_target_assume_role.role_arn,
            parameters=delete_params,
            physical_resource_id=PhysicalResourceId.of("cdksdk_policyassignment"),
        )

    def to_dict(self):
        config = {}
        config["vpcId"] = ""
        config["redshiftUsername"] = "admin"
        config["redshiftSecretId"] = ""
        config["redshiftClusterId"] = ""
        config["redshiftHost"] = ""
        config["redshiftDB"] = ""
        config["rdsUsername"] = "admin"
        config["rdsSecretId"] = ""
        config["rdsInstanceId"] = ""
        config["rdsDB"] = ""
        config["rdsPort"] = ""
        config["rdsPort"] = ""
        config["namespace"] = "default"
        config["version"] = "1"

        return config

# Change to your central account # create a custom resource that will create a quicksight user using the IAM target role # create a custom resource that will create a quicksight policy assignment # create quicksight user # delete quicksight user # create policy assignment # delete policy assignment