0
votes

We have an existing CDK project that has already created the Application load balancer, VPC, ... I am putting in place a new CDK Global template to deploy our microservices in ECS and auto-register in an existing ALB.

That new project has two stacks TaskDefintionStack and ServiceTask(Dynamic stack). Every new service to deploy will give as env variable the name of its stack, like that we can deploy multiple services with the same CDK project.

_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()

If the service is open to the world it has to register a rule to forward traffics to its target in the existing ALB listener. Unfortunately, from the CDK documentation, it states that we can not call loadBalancer.addListener() and listener.addTargets(). https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_ecs/README.html#using-a-load-balancer-from-a-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] )

My question is there a workaround? The workaround gave here does not work, or at least it works only for the first service registered. All new services fall to the issue I stated above. https://github.com/aws-samples/aws-cdk-examples/tree/master/typescript/ecs/cross-stack-load-balancer

1

1 Answers

0
votes

I found a workaround to the problem. The fact that the listener was created from another project. ECS service or fargetServie service are not kind of able to register directly a target on it.

I used CFN classes to by pass the issue. Here the code

_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")