我们有一个现有的CDK项目,它已经创建了应用程序负载均衡器VPC。。。我正在建立一个新的CDK Global模板,在ECS中部署我们的微服务,并在现有的ALB中自动注册。
这个新项目有两个堆栈TaskDefinitionStack和ServiceTask(动态堆栈(。每个要部署的新服务都会将其堆栈的名称作为env变量,就像我们可以用同一个CDK项目部署多个服务一样。
_env = {'account': os.environ['CDK_DEFAULT_ACCOUNT'], 'region': os.environ['CDK_DEFAULT_REGION']}
props = {}
environment = os.getenv("ENVIRONMENT", "int")
taskStackName = "{}-{}-task".format(environment, os.environ["SERVICE_NAME"])
serviceStackName = "{}-{}-service".format(environment, os.environ["SERVICE_NAME"])
task = PayiciTaskDefStack(app, taskStackName, props, env=_env)
service = PayiciServiceStack(app, serviceStackName, task.outputs, env=_env)
task.add_dependency(task)
app.synth()
如果服务对世界开放,它必须注册一个规则,将流量转发到现有ALB侦听器中的目标。不幸的是,从CDK文档中,它指出我们不能调用loadBalancer.addListener((和listener.addTargets((。https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_ecs/README.html#using-a-load-balancer-from-different-stack
if props["need_alb"] == "True":
_alb = elbv2.ApplicationLoadBalancer.from_lookup(self,id="ALB",load_balancer_arn=props["load_balancer_arn"])
_listener = elbv2.ApplicationListener.from_lookup(self,id="albLiistener",listener_arn=props["listener_arn"], listener_port=80)
if props["need_alb_ssl"] != "True":
# here port 80 check if port 80 listener exist
_target_group = _listener.add_targets("ECS1", port=80, target=[_fargate_service] )
_fargate_service.register_load_balancer_targets()
else:
# here port 443
_target_group = _listener.add_targets("ECS1", port=443, targets=[_fargate_service] )
我的问题是有变通办法吗?这里给出的解决方法不起作用,或者至少它只适用于注册的第一个服务。所有新的服务都属于我上面提到的问题。https://github.com/aws-samples/aws-cdk-examples/tree/master/typescript/ecs/cross-stack-load-balancer
我找到了解决问题的方法。侦听器是从另一个项目创建的。ECS服务或fargetServie服务不能直接在上面注册目标
我使用CFN类来绕过这个问题。这里的代码
_target_group = elbv2.ApplicationTargetGroup(self,id="{}-{}-tg".format(props["environment"], props["service_name"]),
vpc=_vpc,
port=int(_important_port),
protocol=elbv2.ApplicationProtocol.HTTP,
health_check=elbv2.HealthCheck(interval=cdk.Duration.seconds(60), path="/", timeout=cdk.Duration.seconds(5), healthy_http_codes="200-499"),stickiness_cookie_duration=cdk.Duration.hours(1), deregistration_delay=cdk.Duration.seconds(30), targets=[_service_target] )
_conditions = [{"field": "path-pattern", "values":[props["application_path"]]}]
if bool(props["alb_host_header"]):
_conditions = [{"field": "host-header", "values:[props["alb_host_header"]]}]
if props["need_alb"] == "True":
if props["need_alb_ssl"] != "True":
# here port 80 check if port 80 listener exist
_rule1 = elbv2.CfnListenerRule(self, id="{}-{}-rule".format(props["environment"], props["service_name"]),
listener_arn=props["listener_arn"], conditions=_conditions, actions=[{"targetGroupArn": _target_group.target_group_arn,"type": "forward"} ], priority=int(props["priority"]) )
else:
# here port 443
print("Here goes the https redirection")