ECSPatterns: Support switch for http->https redirect
See original GitHub issueIt’s common use case to redirect all http requests to https at the load balancer level. Use cases include UI:s that are served from containers and API implementations as well. Giving https upgrade automatically to your users (end users using application and developers testing your API’s) is a usability issue. It’s like saying: “here I am, but could you talk securely to me?”.
Application Load Balancer has great support for this already, but unfortunately it seems like this use case is not supported in ApplicationLoadBalancedFargateService
pattern. Same thing probably affects other ALB based high level patterns as well.
Use Case
If you need to implement http to https redirect with ECS Patterns, you have to do some heavy lifting in order to be able to configure simple redirect. ApplicationLoadBalancedFargateServiceProps
builder has loadBalancer()
, but it seems like then you have to do the heavy VPC configuration and such.
Workaround seems to be something like following.
ApplicationLoadBalancer loadBalancer = new ApplicationLoadBalancer(this, "loadBalancer", ApplicationLoadBalancerProps.builder()
.internetFacing(true)
.vpc(vpc)
.build());
ApplicationListener httpListener = loadBalancer.addListener("httpListener", BaseApplicationListenerProps.builder()
.protocol(ApplicationProtocol.HTTP)
.build());
httpListener.addRedirectResponse("https-redirect", AddRedirectResponseProps.builder().statusCode("HTTP_301").protocol("HTTPS").port("443").build());
ApplicationLoadBalancedFargateService fargateService = new ApplicationLoadBalancedFargateService(
this,
"my-fargate-service",
ApplicationLoadBalancedFargateServiceProps.builder()
.cluster(cluster)
.certificate(Certificate.fromCertificateArn(this, "ALB-certificate",
"arn:aws:acm:eu-west-1:XXXXXXXXXXXX:certificate/XXXXXXXXX"))
.domainName("myservice.acme.com")
.domainZone(hostedZone)
.loadBalancer(loadBalancer)
.taskImageOptions(ApplicationLoadBalancedTaskImageOptions.builder()
.image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample"))
.build())
.build());
This “decorates” used load balancer and merges configuration pretty intelligently and this is totally acceptable workaround for me. I personally feel that this is really common pattern in web applications to be able to listen both http and https traffic and upgrade all http requests to https, and it would help AWS and CDK newcomers to be able to define this really common use case in more easy way.
Proposed Solution
High level constructs could take additional “redirectHttpToHttps(boolean)”, such as
ApplicationLoadBalancedFargateService fargateService = new ApplicationLoadBalancedFargateService(
this,
"my-fargate-service",
ApplicationLoadBalancedFargateServiceProps.builder()
.cluster(cluster)
.certificate(Certificate.fromCertificateArn(this, "ALB-certificate",
"arn:aws:acm:eu-west-1:XXXXXXXXXXXX:certificate/XXXXXXXXX"))
.domainName("myservice.acme.com")
.domainZone(hostedZone)
.redirectHttpToHttps(true)
.taskImageOptions(ApplicationLoadBalancedTaskImageOptions.builder()
.image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample"))
.build())
.build());
If redirectHttpToHttps
is called with true
, when certificate is not set, synth should fail, because then http listener which redirects traffic to target group is configured.
More advanced option would be the ability to configure http traffic to target group, because there are applications in the wild that want (for some reason…) handle both http and https traffic. This could be done with something like:
httpPolicy(HttpPolicy.NO_LISTENER)
No listener for http
httpPolicy(HttpPolicy.REDIRECT_TO_HTTPS)
Do http->https redirect
httpPolicy(HttpPolicy.ROUTE_TO_TARGET_GROUP)
Route http traffic to target group
Other
This is just an idea I wanted to share. I don’t mind rejection 😃 I would love to help out, and if this is regarded as a good idea, I just might take some time to investigate how this could be implemented.
- 👋 I may be able to implement this feature request
- ⚠️ This feature might incur a breaking change
This is a 🚀 Feature Request
Issue Analytics
- State:
- Created 4 years ago
- Reactions:13
- Comments:35 (14 by maintainers)
I was struggling with the same problem today and found a solution:
You need to create a listener for your load balancer for HTTP on port 80.
And then you can redirect all incoming HTTP requests to HTTPS by adding a RedirectResponse like so:
I think this is a common problem and an example solution should be inserted to the cdk examples or documentation.
@08en Your suggestion seems really promising, but since
new ecs_patterns.ApplicationLoadBalancedFargateService(...)
already creates a loadbalancer with a port 80 listener, I get:A listener already exists on this port for this load balancer '<arn>' (Service: AmazonElasticLoadBalancingV2; Status Code: 400; Error Code: DuplicateListener; Request ID: <req id>)
I haven’t found a way obtain a reference to the existing port 80 listener. (Something like
loadBalancer.getListeners()
would have been nice…)Is there a solution to this?