Look at the following CDK stack definition:
export class AwsStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const myHostedZone = new route53.HostedZone(this, "HostedZone", {
zoneName: domain,
});
const certificate = new acm.Certificate(this, "Certificate", {
domainName: `*.${domain}`,
validation: acm.CertificateValidation.fromDns(myHostedZone),
});
const image = new ecr.DockerImageAsset(this, "Image", { directory: "." });
const vpc = new ec2.Vpc(this, "ApplicationVpc", { maxAzs: 2 });
const cluster = new ecs.Cluster(this, "Cluster", {
clusterName: "Cluster",
vpc,
});
const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef");
taskDefinition.addContainer("DefaultContainer", {
image: ecs.ContainerImage.fromDockerImageAsset(image),
portMappings: [
{ containerPort: 3000, hostPort: 3000 },
{ containerPort: 3001, hostPort: 3001 },
],
});
const service = new ecsPatterns.ApplicationLoadBalancedFargateService(this, "Service", {
cluster,
publicLoadBalancer: true,
taskDefinition,
certificate,
});
service.loadBalancer.addRedirect()
service.listener.addTargets("api", {
priority: 10,
conditions: [elb.ListenerCondition.hostHeaders([`api.${domain}`])],
// what to do???
});
}
}
I want to map incoming traffic with api.domain
to port 3001 and everything else should map to port 3000.
How can I achieve this?
CodePudding user response:
Use the port
property of the AddApplicationTargetsProps
:
service.listener.addTargets("api", {
priority: 10,
conditions: [elb.ListenerCondition.hostHeaders([`api.${domain}`])],
port: 3001,
targets: [service.service]
});
service.listener.addTargets("default", {
port: 3000,
targets: [service.service]
});
CodePudding user response:
I was able to solve it with the following
export class AwsStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const zone = new route53.HostedZone(this, "HostedZone", {
zoneName: domain,
});
//const certificate = acm.Certificate.fromCertificateArn(this, "Certificate", certificateArn);
const certificate = new acm.Certificate(this, "Certificate", {
domainName: domain,
subjectAlternativeNames: [`*.${domain}`],
validation: acm.CertificateValidation.fromDns(zone),
});
const image = new ecr.DockerImageAsset(this, "Image", { directory: "." });
const vpc = new ec2.Vpc(this, "ApplicationVpc", { maxAzs: 2 });
const cluster = new ecs.Cluster(this, "Cluster", {
clusterName: "Cluster",
vpc,
});
const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef");
taskDefinition.addContainer("DefaultContainer", {
image: ecs.ContainerImage.fromDockerImageAsset(image),
portMappings: [
{ containerPort: 3000, hostPort: 3000 },
{ containerPort: 3001, hostPort: 3001 },
],
logging: new ecs.AwsLogDriver({
streamPrefix: domain,
}),
});
const service = new ecs.FargateService(this, "Service", {
cluster,
taskDefinition,
assignPublicIp: true,
});
const lb = new elb.ApplicationLoadBalancer(this, "LoadBalancer", {
vpc,
internetFacing: true,
});
const listener = lb.addListener("Listener", {
port: 443,
certificates: [certificate],
});
listener.addTargets("API", {
priority: 10,
conditions: [elb.ListenerCondition.hostHeaders([`api.${domain}`])],
port: 80,
targets: [service.loadBalancerTarget({ containerName: "DefaultContainer", containerPort: 3001 })],
healthCheck: {
healthyHttpCodes: "200-399",
},
});
listener.addTargets("UI", {
port: 80,
targets: [service.loadBalancerTarget({ containerName: "DefaultContainer", containerPort: 3000 })],
healthCheck: {
healthyHttpCodes: "200-399",
},
});
new route53.ARecord(this, "AliasRecord", {
zone,
target: route53.RecordTarget.fromAlias(new alias.LoadBalancerTarget(lb)),
});
new route53.ARecord(this, "AliasRecordAPI", {
recordName: `api.${domain}`,
zone,
target: route53.RecordTarget.fromAlias(new alias.LoadBalancerTarget(lb)),
});
}
}
I am still wondering why listener.addTargets
requires port 80
.