in source/idea/idea-administrator/src/ideaadministrator/app/cdk/stacks/cluster_stack.py [0:0]
def build_cluster_endpoints(self):
lambda_name = 'cluster-endpoints'
cluster_endpoints_policy = Policy(
context=self.context,
name=f'{lambda_name}-policy',
scope=self.stack,
policy_template_name='custom-resource-cluster-endpoints.yml'
)
cluster_endpoints_role = Role(
context=self.context,
name=f'{lambda_name}-role',
scope=self.stack,
description=f'Role for cluster endpoints lambda function for Cluster: {self.cluster_name}',
assumed_by=['lambda'])
cluster_endpoints_role.attach_inline_policy(cluster_endpoints_policy)
self.cluster_endpoints_lambda = LambdaFunction(
context=self.context,
name=lambda_name,
scope=self.stack,
idea_code_asset=IdeaCodeAsset(
lambda_package_name='idea_custom_resource_cluster_endpoints',
lambda_platform=SupportedLambdaPlatforms.PYTHON
),
description='Manage cluster endpoints exposed via internal and external ALB',
timeout_seconds=600,
role=cluster_endpoints_role,
log_retention_role=self.roles[app_constants.LOG_RETENTION_ROLE_NAME]
)
self.cluster_endpoints_lambda.node.add_dependency(cluster_endpoints_policy)
self.cluster_endpoints_lambda.node.add_dependency(cluster_endpoints_role)
# external ALB - can be deployed in public or private subnets
is_public = self.context.config().get_bool('cluster.load_balancers.external_alb.public', default=True)
external_alb_subnets = self.public_subnets(SubnetFilterKeys.LOAD_BALANCER_SUBNETS) if is_public is True else self.private_subnets(SubnetFilterKeys.LOAD_BALANCER_SUBNETS)
self.external_alb = elbv2.ApplicationLoadBalancer(
self.stack,
f'{self.cluster_name}-external-alb',
load_balancer_name=f'{self.cluster_name}-external-alb',
security_group=self.security_groups['external-load-balancer'],
http2_enabled=True,
vpc=self.vpc,
vpc_subnets=ec2.SubnetSelection(subnets=external_alb_subnets),
internet_facing=is_public
)
if self.external_certificate is not None:
self.external_alb.node.add_dependency(self.external_certificate)
# internal ALB - will always be deployed in private subnets
self.internal_alb = elbv2.ApplicationLoadBalancer(
self.stack,
f'{self.cluster_name}-internal-alb',
load_balancer_name=f'{self.cluster_name}-internal-alb',
security_group=self.security_groups['internal-load-balancer'],
http2_enabled=True,
vpc=self.vpc,
vpc_subnets=ec2.SubnetSelection(subnets=self.private_subnets()),
internet_facing=False
)
# Manage Access Logs for external/internal Application Load Balancer
# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html
external_alb_enable_access_log = self.context.config().get_bool('cluster.load_balancers.external_alb.access_logs', default=False)
internal_alb_enable_access_log = self.context.config().get_bool('cluster.load_balancers.internal_alb.access_logs', default=False)
cluster_s3_bucket = None
if external_alb_enable_access_log or internal_alb_enable_access_log:
cluster_s3_bucket = s3.Bucket.from_bucket_name(scope=self.stack, id='cluster-s3-bucket', bucket_name=self.context.config().get_string('cluster.cluster_s3_bucket', required=True))
if external_alb_enable_access_log:
self.external_alb.log_access_logs(cluster_s3_bucket, f'logs/{self.module_id}/alb-access-logs/external-alb')
if internal_alb_enable_access_log:
self.internal_alb.log_access_logs(cluster_s3_bucket, f'logs/{self.module_id}/alb-access-logs/internal-alb')
# Drop invalid headers from requests to the ALB as a security measure
self.external_alb.set_attribute('routing.http.drop_invalid_header_fields.enabled', 'true')
self.internal_alb.set_attribute('routing.http.drop_invalid_header_fields.enabled', 'true')
elbv2.CfnListener(
self.external_alb,
'http-listener',
port=80,
load_balancer_arn=self.external_alb.load_balancer_arn,
protocol='HTTP',
default_actions=[
elbv2.CfnListener.ActionProperty(
type='redirect',
redirect_config=elbv2.CfnListener.RedirectConfigProperty(
host='#{host}',
path='/#{path}',
port='443',
protocol='HTTPS',
query='#{query}',
status_code='HTTP_301'
)
)
]
)
# ALB listener must be created with a default action.
# after the cluster stack is deployed, the cluster manager stack can update the default action to point to web portal
# to avoid replacing the default action set for web-portal, fetch the default actions if the listener exists
external_alb_listener_arn = self.context.config().get_string('cluster.load_balancers.external_alb.https_listener_arn')
external_alb_default_actions = self.get_alb_listener_default_actions(external_alb_listener_arn)
if self.external_certificate is None:
external_acm_certificate_arn = self.context.config().get_string('cluster.load_balancers.external_alb.certificates.acm_certificate_arn', required=True)
else:
external_acm_certificate_arn = self.external_certificate.get_att_string('acm_certificate_arn')
self.external_alb_https_listener = elbv2.CfnListener(
self.external_alb,
'https-listener',
port=443,
ssl_policy=self.context.config().get_string('cluster.load_balancers.external_alb.ssl_policy', default='ELBSecurityPolicy-TLS13-1-2-2021-06'),
load_balancer_arn=self.external_alb.load_balancer_arn,
protocol='HTTPS',
certificates=[
elbv2.CfnListener.CertificateProperty(
certificate_arn=external_acm_certificate_arn
)
],
default_actions=external_alb_default_actions
)
if self.external_certificate is not None:
self.external_alb_https_listener.node.add_dependency(self.external_certificate)
self.internal_alb.node.add_dependency(self.internal_certificate)
internal_acm_certificate_arn = self.internal_certificate.get_att_string('acm_certificate_arn')
self.internal_alb_https_listener = elbv2.CfnListener(
self.internal_alb,
'https-listener',
port=443,
ssl_policy=self.context.config().get_string('cluster.load_balancers.internal_alb.ssl_policy', default='ELBSecurityPolicy-TLS13-1-2-2021-06'),
load_balancer_arn=self.internal_alb.load_balancer_arn,
protocol='HTTPS',
certificates=[
elbv2.CfnListener.CertificateProperty(
certificate_arn=internal_acm_certificate_arn
)
],
default_actions=[
elbv2.CfnListener.ActionProperty(
type='fixed-response',
fixed_response_config=elbv2.CfnListener.FixedResponseConfigProperty(
status_code='200',
content_type='application/json',
message_body=Utils.to_json({
'success': True,
'message': 'OK'
})
)
)
]
)
self.internal_alb_https_listener.node.add_dependency(self.internal_certificate)
if self.aws_region in Utils.get_value_as_list('ROUTE53_CROSS_ZONE_ALIAS_RESTRICTED_REGION_LIST', constants.CAVEATS, []):
self.internal_alb_dns_record_set = route53.CnameRecord(
self.stack,
'internal-alb-dns-record',
record_name=f'internal-alb.{self.private_hosted_zone.zone_name}',
zone=self.private_hosted_zone,
domain_name=self.internal_alb.load_balancer_dns_name,
ttl=cdk.Duration.minutes(5)
)
else:
self.internal_alb_dns_record_set = route53.RecordSet(
self.stack,
'internal-alb-dns-record',
record_type=route53.RecordType.A,
target=route53.RecordTarget.from_alias(route53_targets.LoadBalancerTarget(self.internal_alb)),
ttl=cdk.Duration.minutes(5),
record_name=f'internal-alb.{self.private_hosted_zone.zone_name}',
zone=self.private_hosted_zone
)
if self.context.config().is_module_enabled(constants.MODULE_VIRTUAL_DESKTOP_CONTROLLER):
dcv_broker_client_listener_arn = self.context.config().get_string('cluster.external_alb.dcv_broker_client_listener_arn')
dcv_broker_client_listener_default_actions = self.get_alb_listener_default_actions(dcv_broker_client_listener_arn)
dcv_broker_client_communication_port = self.context.config().get_int('virtual-desktop-controller.dcv_broker.client_communication_port', required=True)
self.internal_alb_dcv_broker_client_listener = elbv2.CfnListener(
self.internal_alb,
'dcv-broker-client-listener',
port=dcv_broker_client_communication_port,
ssl_policy=self.context.config().get_string('virtual-desktop-controller.dcv_broker.ssl_policy', default='ELBSecurityPolicy-TLS13-1-2-2021-06'),
load_balancer_arn=self.internal_alb.load_balancer_arn,
protocol='HTTPS',
certificates=[
elbv2.CfnListener.CertificateProperty(
certificate_arn=internal_acm_certificate_arn
)
],
default_actions=dcv_broker_client_listener_default_actions
)
self.internal_alb_dcv_broker_client_listener.node.add_dependency(self.internal_certificate)
self.security_groups['internal-load-balancer'].add_ingress_rule(
ec2.Peer.ipv4(self.vpc.vpc_cidr_block),
ec2.Port.tcp(dcv_broker_client_communication_port),
description='Allow HTTPS traffic from DCV Clients to DCV Broker'
)
dcv_broker_agent_listener_arn = self.context.config().get_string('cluster.external_alb.dcv_broker_agent_listener_arn')
dcv_broker_agent_listener_default_actions = self.get_alb_listener_default_actions(dcv_broker_agent_listener_arn)
dcv_broker_agent_communication_port = self.context.config().get_int('virtual-desktop-controller.dcv_broker.agent_communication_port', required=True)
self.internal_alb_dcv_broker_agent_listener = elbv2.CfnListener(
self.internal_alb,
'dcv-broker-agent-listener',
port=dcv_broker_agent_communication_port,
ssl_policy=self.context.config().get_string('virtual-desktop-controller.dcv_broker.ssl_policy', default='ELBSecurityPolicy-TLS13-1-2-2021-06'),
load_balancer_arn=self.internal_alb.load_balancer_arn,
protocol='HTTPS',
certificates=[
elbv2.CfnListener.CertificateProperty(
certificate_arn=internal_acm_certificate_arn
)
],
default_actions=dcv_broker_agent_listener_default_actions
)
self.internal_alb_dcv_broker_agent_listener.node.add_dependency(self.internal_certificate)
self.security_groups['internal-load-balancer'].add_ingress_rule(
ec2.Peer.ipv4(self.vpc.vpc_cidr_block),
ec2.Port.tcp(dcv_broker_agent_communication_port),
description='Allow HTTPS traffic from DCV Agents to DCV Broker'
)
dcv_broker_gateway_listener_arn = self.context.config().get_string('cluster.external_alb.dcv_broker_gateway_listener_arn')
dcv_broker_gateway_listener_default_actions = self.get_alb_listener_default_actions(dcv_broker_gateway_listener_arn)
dcv_broker_gateway_communication_port = self.context.config().get_int('virtual-desktop-controller.dcv_broker.gateway_communication_port', required=True)
self.internal_alb_dcv_broker_gateway_listener = elbv2.CfnListener(
self.internal_alb,
'dcv-broker-gateway-listener',
port=dcv_broker_gateway_communication_port,
ssl_policy=self.context.config().get_string('virtual-desktop-controller.dcv_broker.ssl_policy', default='ELBSecurityPolicy-TLS13-1-2-2021-06'),
load_balancer_arn=self.internal_alb.load_balancer_arn,
protocol='HTTPS',
certificates=[
elbv2.CfnListener.CertificateProperty(
certificate_arn=internal_acm_certificate_arn
)
],
default_actions=dcv_broker_gateway_listener_default_actions
)
self.internal_alb_dcv_broker_gateway_listener.node.add_dependency(self.internal_certificate)
self.security_groups['internal-load-balancer'].add_ingress_rule(
ec2.Peer.ipv4(self.vpc.vpc_cidr_block),
ec2.Port.tcp(dcv_broker_gateway_communication_port),
description='Allow HTTPS traffic from DCV Connection Gateway to DCV Broker'
)