millions-energy-69153
12/02/2019, 3:41 AMpulumi-awsx
to create an AWS stack for our app as shown here. It consists of three ECS tasks: one for the server (api), one for the client, and one for our worker. I’d like to get /api*
requests going to the server and the rest going to the client. I’m using an ALB with target groups and a listener rule to try and achieve this.
With everything aligned with port 4000, this works great. If I want to have the ALB serve on 80 and the container ports staying on 4000, I get 503 responses. I’ve tried a number of things to do the port mapping, but nothing seems to work.
I found this issue: https://github.com/pulumi/examples/issues/267#issuecomment-524598748 which says, “If you’re running on Fargate you have to use the same port as what your container is listening on.” I hope this isn’t the case.
Thanks in advance for any guidance you can offer. Pulumi is an amazing tool!clever-sunset-76585
12/02/2019, 5:47 PMportMappings
for each of your FargateService
s? For example, instead of using the respective target group instance (which implements the interface PortMappingProvider
), specify them manually as explicit port mappings: { containerPort: …, hostPort: …, protocol: "tcp" }
. I think what’s happening is, that the port mappings inferred from the target group takes the container port and the host port to be the same, which is not correct if you want the load balancer to forward incoming request from a different port to the container port. You’d want the container port to be published as the port you expect incoming traffic port from the outside, which is the hostPort
. Then you can set the target group’s port to be 80
so that it forwards 80 (ALB) -> 80 (host) -> 4000 (container).millions-energy-69153
12/02/2019, 7:58 PMportMappings: [{ containerPort: 5000, protocol: 'tcp' }]
This still gives me 503 errors.
If I put a hostPort
in there that doesn’t match the containerPort
, I get an error: When networkMode=awsvpc, the host ports and container ports in port mappings must match.
clever-sunset-76585
12/02/2019, 8:46 PMIf I put aAh ok. That makes sense. When you say you changed the port number for the ALB to listen on 80, I am assuming you changed the port number for the listener and not the target group?in there that doesn’t match thehostPort
, I get an error:containerPort
When networkMode=awsvpc, the host ports and container ports in port mappings must match.
millions-energy-69153
12/02/2019, 8:55 PMcontainerPort
in the task definition to use the port I’m serving on in the container but still get 503 errors.clever-sunset-76585
12/02/2019, 10:22 PMFargateService
like in your snippet.
The one thing I noticed is that you have an error in your LoadBalancer
creation. It should be securityGroups
(plural). I think you didn’t get any type errors because you seem to be using JS, which in JS any unknown properties would just get ignored.
Here’s my example (note that I removed the client and the worker services). My “server” service is just a Python-based Flask app that simply returns “Hello World”.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
// Create an ECS Fargate cluster
const cluster = new awsx.ecs.Cluster("cluster");
// Define the networking for our services
const loadBalancer = new awsx.lb.ApplicationLoadBalancer("external-load-balancer", {
external: true,
securityGroups: cluster.securityGroups,
});
const serverTargetGroup = loadBalancer.createTargetGroup("server", {
port: 4000,
protocol: 'HTTP'
});
const serverListener = loadBalancer.createListener("serverListener", {
port: 80,
protocol: "HTTP",
external: true,
// You should specify the "clientTargetGroup" here since that would be your "default" action
// when the request path does not contain "/api".
targetGroup: serverTargetGroup
});
serverListener.addListenerRule("serverListenerRule", {
actions: [{ targetGroupArn: serverTargetGroup.targetGroup.arn, type: "forward" }],
conditions: [{ field: "path-pattern", values: "/api*" }]
});
// Create Fargate service tasks that can scale out for each of our services
new awsx.ecs.FargateService("serverService", {
cluster,
taskDefinitionArgs: {
container: {
image: awsx.ecs.Image.fromPath("server", "./server"),
memory: 512,
portMappings: [serverTargetGroup]
}
},
desiredCount: 2
});
// Export the Internet address for the service
export const url = loadBalancer.loadBalancer.dnsName;
millions-energy-69153
12/03/2019, 6:34 AMclever-sunset-76585
12/03/2019, 4:50 PM