How to attach a fargate service to an existing target-group (pulumi)?

Viewed 530

I'm trying to replicate the flow described in here.

I have a load balancer, a listener on 80 port which is supposed to redirect calls to different target groups and a target group for a specific service.

How do I tell pulumi that I want to associate a specific service with existing lb, listener and a target group? A sample from here creates a listener but I don't want it to be derived from my target group, it should be able to handle multiple target groups as I described earlier.

When I'm using AWS Console, I can easily specify a target group in a service definition, as seen on the picture: enter image description here

But I'm unable to find analogous fields in pulumi doc.

1 Answers

ECS's level of indirection, console magic and naming overloads ("service is valid for ECS and ALBs) can often be difficult to understand.

Ultimately, the configuration I think you're looking for is here in the ECS service definition.

When you define your ECS definition, you can the target group you wish to use, like so:

const svcA = new aws.ecs.Service("example-A", {
    cluster: cluster.arn,
    desiredCount: 1,
    launchType: "FARGATE",
    taskDefinition: taskDefinition.arn,
    networkConfiguration: {
        assignPublicIp: true,
        subnets: subnets.ids,
        securityGroups: [ securityGroup.id ]
    },
    loadBalancers: [{
        targetGroupArn: targetGroupA.arn,
        containerName: "my-app",
        containerPort: 80,
    }]
})

Note the loadBalancers object defined there.

You can then define multiple services and point them at whichever target group you like. Here, we can define a loadbalancer with two listeners and target groups:

// define a loadbalancer
const lb = new aws.lb.LoadBalancer("example", {
  securityGroups: [securityGroup.id],
  subnets: subnets.ids,
});

// target group for port 80
const targetGroupA = new aws.lb.TargetGroup("example-A", {
  port: 80,
  protocol: "HTTP",
  targetType: "ip",
  vpcId: vpc.id,
});

// listener for port 80
const listenerA = new aws.lb.Listener("example-A", {
  loadBalancerArn: lb.arn,
  port: 80,
  defaultActions: [
    {
      type: "forward",
      targetGroupArn: targetGroupA.arn,
    },
  ],
});

// target group for port 8080
const targetGroupB = new aws.lb.TargetGroup("example-B", {
  port: 8080,
  protocol: "HTTP",
  targetType: "ip",
  vpcId: vpc.id,
});

// listener for port 8080
const listenerB = new aws.lb.Listener("example-B", {
  loadBalancerArn: lb.arn,
  port: 8080,
  defaultActions: [
    {
      type: "forward",
      targetGroupArn: targetGroupB.arn,
    },
  ],
});

And then define two distinct services that point to different target groups:

// service listening on port 80
const svcA = new aws.ecs.Service("example-A", {
  cluster: cluster.arn,
  desiredCount: 1,
  launchType: "FARGATE",
  taskDefinition: taskDefinition.arn,
  networkConfiguration: {
    assignPublicIp: true,
    subnets: subnets.ids,
    securityGroups: [securityGroup.id],
  },
  loadBalancers: [
    {
      targetGroupArn: targetGroupA.arn,
      containerName: "my-app",
      containerPort: 80,
    },
  ],
});

// service listening on port 8080
const svcB = new aws.ecs.Service("example-B", {
  cluster: cluster.arn,
  desiredCount: 1,
  launchType: "FARGATE",
  taskDefinition: taskDefinition.arn,
  networkConfiguration: {
    assignPublicIp: true,
    subnets: subnets.ids,
    securityGroups: [securityGroup.id],
  },
  loadBalancers: [
    {
      targetGroupArn: targetGroupB.arn,
      containerName: "my-app",
      containerPort: 80,
    },
  ],
});

You can find a full end to end example of how this looks here

Related