def build_dcv_broker()

in source/idea/idea-administrator/src/ideaadministrator/app/cdk/stacks/virtual_desktop_controller_stack.py [0:0]


    def build_dcv_broker(self):
        # client target group and registration
        client_target_group = elbv2.ApplicationTargetGroup(
            self.stack,
            f'{self.COMPONENT_DCV_BROKER}-client-target-group',
            port=self.BROKER_CLIENT_COMMUNICATION_PORT,
            target_type=elbv2.TargetType.INSTANCE,
            protocol=elbv2.ApplicationProtocol.HTTPS,
            vpc=self.cluster.vpc,
            target_group_name=self.get_target_group_name(f'{self.COMPONENT_DCV_BROKER}-c')
        )
        client_target_group.configure_health_check(
            enabled=True,
            path='/health'
        )

        cdk.CustomResource(
            self.stack,
            'dcv-broker-client-endpoint',
            service_token=self.CLUSTER_ENDPOINTS_LAMBDA_ARN,
            properties={
                'endpoint_name': 'broker-client-endpoint',
                'listener_arn': self.context.config().get_string('cluster.load_balancers.internal_alb.dcv_broker_client_listener_arn', required=True),
                'priority': 0,
                'default_action': True,
                'actions': [
                    {
                        'Type': 'forward',
                        'TargetGroupArn': client_target_group.target_group_arn
                    }
                ]
            },
            resource_type='Custom::DcvBrokerClientEndpointInternal'
        )

        # agent target group and registration
        agent_target_group = elbv2.ApplicationTargetGroup(
            self.stack,
            f'{self.COMPONENT_DCV_BROKER}-agent-target-group',
            port=self.BROKER_AGENT_COMMUNICATION_PORT,
            target_type=elbv2.TargetType.INSTANCE,
            protocol=elbv2.ApplicationProtocol.HTTPS,
            vpc=self.cluster.vpc,
            target_group_name=self.get_target_group_name(f'{self.COMPONENT_DCV_BROKER}-a')
        )
        agent_target_group.configure_health_check(
            enabled=True,
            path='/health'
        )

        cdk.CustomResource(
            self.stack,
            'dcv-broker-agent-endpoint',
            service_token=self.CLUSTER_ENDPOINTS_LAMBDA_ARN,
            properties={
                'endpoint_name': 'broker-client-endpoint',
                'listener_arn': self.context.config().get_string('cluster.load_balancers.internal_alb.dcv_broker_agent_listener_arn', required=True),
                'priority': 0,
                'default_action': True,
                'actions': [
                    {
                        'Type': 'forward',
                        'TargetGroupArn': agent_target_group.target_group_arn
                    }
                ]
            },
            resource_type='Custom::DcvBrokerAgentEndpointInternal'
        )

        # gateway target group and registration
        gateway_target_group = elbv2.ApplicationTargetGroup(
            self.stack,
            f'{self.COMPONENT_DCV_BROKER}-gateway-target-group',
            port=self.BROKER_GATEWAY_COMMUNICATION_PORT,
            target_type=elbv2.TargetType.INSTANCE,
            protocol=elbv2.ApplicationProtocol.HTTPS,
            vpc=self.cluster.vpc,
            target_group_name=self.get_target_group_name(f'{self.COMPONENT_DCV_BROKER}-g')
        )
        gateway_target_group.configure_health_check(
            enabled=True,
            path='/health'
        )

        cdk.CustomResource(
            self.stack,
            'dcv-broker-gateway-endpoint',
            service_token=self.CLUSTER_ENDPOINTS_LAMBDA_ARN,
            properties={
                'endpoint_name': 'broker-gateway-endpoint',
                'listener_arn': self.context.config().get_string('cluster.load_balancers.internal_alb.dcv_broker_gateway_listener_arn', required=True),
                'priority': 0,
                'default_action': True,
                'actions': [
                    {
                        'Type': 'forward',
                        'TargetGroupArn': gateway_target_group.target_group_arn
                    }
                ]
            },
            resource_type='Custom::DcvBrokerGatewayEndpointInternal'
        )

        # security group
        self.dcv_broker_security_group = VirtualDesktopBastionAccessSecurityGroup(
            context=self.context,
            name=f'{self.module_id}-{self.COMPONENT_DCV_BROKER}-security-group',
            scope=self.stack,
            vpc=self.cluster.vpc,
            bastion_host_security_group=self.cluster.get_security_group('bastion-host'),
            description='Security Group for Virtual Desktop DCV Broker',
            directory_service_access=False,
            component_name='DCV Broker'
        )

        # autoscaling group
        dcv_broker_package_uri = self.stack.node.try_get_context('dcv_broker_bootstrap_package_uri')
        https_proxy = self.context.config().get_string('cluster.network.https_proxy', required=False, default='')
        no_proxy = self.context.config().get_string('cluster.network.no_proxy', required=False, default='')
        proxy_config = {}
        if Utils.is_not_empty(https_proxy):
            proxy_config = {
                'http_proxy': https_proxy,
                'https_proxy': https_proxy,
                'no_proxy': no_proxy
            }

        if Utils.is_empty(dcv_broker_package_uri):
            dcv_broker_package_uri = 'not-provided'

        broker_userdata = BootstrapUserDataBuilder(
            aws_region=self.aws_region,
            bootstrap_package_uri=dcv_broker_package_uri,
            install_commands=[
                '/bin/bash dcv-broker/setup.sh'
            ],
            infra_config={
                'BROKER_CLIENT_TARGET_GROUP_ARN': '${__BROKER_CLIENT_TARGET_GROUP_ARN__}',
                'CONTROLLER_EVENTS_QUEUE_URL': '${__CONTROLLER_EVENTS_QUEUE_URL__}'
            },
            proxy_config=proxy_config,
            bootstrap_source_dir_path=ideaadministrator.props.bootstrap_source_dir,
            base_os=self.context.config().get_string('virtual-desktop-controller.dcv_broker.autoscaling.base_os', required=True)
        ).build()
        substituted_userdata = cdk.Fn.sub(broker_userdata, {
            '__BROKER_CLIENT_TARGET_GROUP_ARN__': client_target_group.target_group_arn,
            '__CONTROLLER_EVENTS_QUEUE_URL__': self.event_sqs_queue.queue_url
        })

        self.dcv_broker_role = self._build_iam_role(
            role_description=f'IAM role assigned to virtual-desktop-{self.COMPONENT_DCV_BROKER}',
            component_name=self.COMPONENT_DCV_BROKER,
            component_jinja='virtual-desktop-dcv-broker.yml'
        )

        self.dcv_broker_autoscaling_group = self._build_auto_scaling_group(
            component_name=self.COMPONENT_DCV_BROKER,
            security_group=self.dcv_broker_security_group,
            iam_role=self.dcv_broker_role,
            substituted_userdata=substituted_userdata,
            node_type=constants.NODE_TYPE_INFRA
        )
        self.dcv_broker_autoscaling_group.node.add_dependency(self.event_sqs_queue)

        # receiving error jsii.errors.JSIIError: Cannot add AutoScalingGroup to 2nd Target Group
        # if same ASG is added to both internal and external target groups.
        # workaround below - reference to https://github.com/aws/aws-cdk/issues/5667#issuecomment-827549394
        self.dcv_broker_autoscaling_group.node.default_child.target_group_arns = [
            agent_target_group.target_group_arn,
            client_target_group.target_group_arn,
            gateway_target_group.target_group_arn
        ]