Describe the bug
I want to create an ApplicationListener without setting a default group:
const listener = myElb.addListener('httpToHttpsRedirectionListener', {
port: 80,
protocol: elb.ApplicationProtocol.Http,
// defaultTargetGroups: don't want one because this is just a redirection listener
});
new elb.CfnListenerRule(this, "httpToHttpsRedirectionListenerRule", {
listenerArn: listener.listenerArn,
priority: 1,
conditions: [], // might be another bug because we have no conditions - API says: "Each rule can include zero or one of the following conditions" -> see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#rule-condition-types
actions: [
{
type: "redirect", redirectConfig: {
protocol: "HTTPS",
port: "443",
host: "#{host}",
path: "/#{path}",
query: "#{query}",
statusCode: "HTTP_301"
}
}
]
});
This is giving me the following error:
Listener needs at least one default target group (call addTargetGroups)
To Reproduce
See code above
Expected behavior
Creation of an ApplicationListener with no defaultTargetGroup and a redirect config rule without condition renders a CF template.
Version:
I think you will want to use CloudFormation overrides to work around this one, or implement a redirect target.
I think the proper solution would be to implement the redirect rule directly within CDK. I'm interested in doing this as well. @mhuebner , did you find a viable workaround in the meantime?
My current implementation is:
const listener = loadBalancer.addListener(Utils.createId('HttpListener', tenantId, app, env), {
port: 80,
protocol: elb.ApplicationProtocol.HTTP,
defaultTargetGroups: [targetGroup],
});
new elb.CfnListenerRule(this, Utils.createId('HttpListenerRule', tenantId, app, env), {
listenerArn: listener.listenerArn,
priority: 1,
conditions: [
{
field: 'path-pattern',
values: ['*']
}
],
actions: [
{
type: "redirect", redirectConfig: {
protocol: "HTTPS",
port: "443",
host: "#{host}",
path: "/#{path}",
query: "#{query}",
statusCode: "HTTP_301"
}
}
]
});
Thanks. I did something just a little differently that works for me. I added a "dummy" default action to the L2 Construct, then dug into the L1 CfnListener to overwrite defaultActions with a custom redirect rule:
const httpListener = loadBalancer.addListener("HttpListener", {
protocol: elbv2.ApplicationProtocol.HTTP
});
httpListener.addFixedResponse("DummyResponse", {
statusCode: "404"
});
const cfnHttpListener = httpListener.node.defaultChild as elbv2.CfnListener;
cfnHttpListener.defaultActions = [{
type: "redirect",
redirectConfig: {
protocol: "HTTPS",
host: "#{host}",
path: "/#{path}",
query: "#{query}",
port: "443",
statusCode: "HTTP_301"
}
}];
That renders to CloudFormation like:
"LBHttpListenerA225B711": {
"Type": "AWS::ElasticLoadBalancingV2::Listener",
"Properties": {
"DefaultActions": [
{
"RedirectConfig": {
"Host": "#{host}",
"Path": "/#{path}",
"Port": "443",
"Protocol": "HTTPS",
"Query": "#{query}",
"StatusCode": "HTTP_301"
},
"Type": "redirect"
}
],
"LoadBalancerArn": {
"Ref": "LB8A12904C"
},
"Port": 80,
"Protocol": "HTTP",
"Certificates": []
},
"Metadata": {
"aws:cdk:path": ".../LB/HttpListener/Resource"
}
}
Most helpful comment
Thanks. I did something just a little differently that works for me. I added a "dummy" default action to the L2 Construct, then dug into the L1
CfnListenerto overwritedefaultActionswith a custom redirect rule:That renders to CloudFormation like: