English 中文(简体)
avoid cyclic dependency when defining an ecs service with loadbalancer listener in AWS-CDK
原标题:

I have two (and several other) stacks which create a cyclic dependency:

  • app.py
app = cdk.App()
vpc_stack = RcsVpcStack(app, "RcsVPCStack")
efs_stack = RcsEfsStack(app, "RcsEfsStack", vpc_stack=vpc_stack)
ecs_stack = RcsECSStack(app, "RcsECSStack", vpc_stack=vpc_stack, fileSystem=efs_stack.efs_filesystem)

elbv2_stack = RcsELBv2Stack(app, "RcsELBv2Stack", 
                            vpc_stack=vpc_stack,  
                            cert_arn=CERT_ARN
                            )
ecs_service_stack = RcsECSServiceStack(app, "RcsECSServiceStack", 
                   vpc_stack=vpc_stack, 
                   ecs_stack=ecs_stack,
                   elbv2_stack=elbv2_stack
                   )
  • Elbv2Stack
    defines an ApplicationLoadbalancer with listener

      self.domain_cert = certm.Certificate.from_certificate_arn(
          self,
          "rcs-domain-cert",
          cert_arn
      )
      self.elbv2_loadbalancer = elbv2.ApplicationLoadBalancer(
          self,
          "rcs-elastic-loadbalancer",
          load_balancer_name="rcs-elastic-loadbalancer",
          vpc=vpc_stack.vpc,
          vpc_subnets=ec2.SubnetSelection(
              subnets=vpc_stack.vpc.public_subnets
          ),
          idle_timeout=Duration.seconds(300),
          internet_facing=True
      )
      self.elbv2_loadbalancer_listener = self.elbv2_loadbalancer.add_listener(
          "rcs-elastic-loadbalancer-listener",
          port=443,
          protocol=elbv2.ApplicationProtocol.HTTPS,
          certificates=[elbv2.ListenerCertificate.from_certificate_manager(self.domain_cert)]
      )
      self.elbv2_loadbalancer_listener.add_targets(
          "rcs-default-target-group",
          port=80,
          protocol=elbv2.ApplicationProtocol.HTTP
      )
    
  • EcsStack
    defines an ECS Container service

      # ... service definitions 
    
      elbv2_stack.elbv2_loadbalancer_listener.add_targets(
          "rcs-api-backend-loadbalancer-target",
          port=80,
          targets=[
              ecs_service_stack.ecs_api_backend.load_balancer_target(
                  container_name="testService",
                  container_port=someContainerPort
              )
          ]
      )
      self.test_target_group = elbv2.ApplicationTargetGroup(
          self,
          "rcs-api-backend-target-group",
          vpc=vpc_stack.vpc,
          port=80,
          protocol=elbv2.ApplicationProtocol.HTTP,
          health_check=elbv2.HealthCheck(
              healthy_http_codes="200-299",
              interval=Duration.seconds(20),
              path="/health-check",
              protocol=elbv2.Protocol.HTTP,
              timeout=Duration.seconds(5),
              healthy_threshold_count=2
          )
      )
      elbv2_stack.elbv2_loadbalancer_listener.add_action(
          "rcs-api-backend-elbv2-action",
          action=elbv2.ListenerAction.forward(
              target_groups=[self.test_target_group],
          ),
          priority=2,
          conditions=[
              elbv2.ListenerCondition.path_patterns(["*"])
          ]
      )
    

The Error:

RuntimeError: Error:  RcsECSServiceStack  depends on  RcsELBv2Stack  
({RcsECSServiceStack/rcs-api-backend/Service}.addDependency({RcsELBv2Stack/rcs-elastic-loadbalancer/rcs-elastic-loadbalancer-listener/Resource}), 
{RcsECSServiceStack/rcs-api-backend/Service}.addDependency({RcsELBv2Stack/rcs-elastic-loadbalancer/rcs-elastic-loadbalancer-listener/rcs-default-target-groupGroup/Resource}), 
{RcsECSServiceStack/rcs-api-backend/Service}.addDependency({RcsELBv2Stack/rcs-elastic-loadbalancer/rcs-elastic-loadbalancer-listener/rcs-api-backend-loadbalancer-targetGroup/Resource}), 
{RcsECSServiceStack/rcs-api-backend/Service}.addDependency({RcsELBv2Stack/rcs-elastic-loadbalancer/rcs-elastic-loadbalancer-listener/rcs-api-backend-elbv2-actionRule/Resource})). Adding this dependency (RcsELBv2Stack -> RcsECSServiceStack/rcs-api-backend-target-group/Resource.Ref) would create a cyclic reference.

To have an overview, it would be great to define the container service with its target group in the dedicated stack, but I get a cyclic dependency if I do that.
Is it a problem with the action added?
Is there a possible solution to this?

问题回答

From our experience, we had to separate how we create an ECS service and a Load Balancer. We ended up having an ECS Service construct that can be deployed even without a load balancer and target group attached to it.

The ECS service construct we made have optional parameters to put in the load balancer ARN and the load balancer HTTPS listener ARN. We then use LookUps to reference those ALB and Listeners.





相关问题
Get webpage contents with Python?

I m using Python 3.1, if that helps. Anyways, I m trying to get the contents of this webpage. I Googled for a little bit and tried different things, but they didn t work. I m guessing that this ...

What is internal representation of string in Python 3.x

In Python 3.x, a string consists of items of Unicode ordinal. (See the quotation from the language reference below.) What is the internal representation of Unicode string? Is it UTF-16? The items ...

What does Python s builtin __build_class__ do?

In Python 3.1, there is a new builtin function I don t know in the builtins module: __build_class__(...) __build_class__(func, name, *bases, metaclass=None, **kwds) -> class Internal ...

what functional tools remain in Python 3k?

I have have read several entries regarding dropping several functional functions from future python, including map and reduce. What is the official policy regarding functional extensions? is lambda ...

Building executables for Python 3 and PyQt

I built a rather simple application in Python 3.1 using PyQt4. Being done, I want the application to be distributed to computers without either of those installed. I almost exclusively care about ...

热门标签