Aws-load-balancer-controller: Feature req: HTTP -> HTTPS redirects (ALB-native)

Created on 26 Jul 2018  路  92Comments  路  Source: kubernetes-sigs/aws-load-balancer-controller

Right now, in order to redirect users to HTTPS, the application's backend had to serve the redirects since until now ALBs didn't support modifying requests. For comparison, the nginx ingress controller supports HTTP->HTTPS redirects from an annotation because nginx itself will happily redirect.

Today a new ALB feature was launched which lets the ALB itself redirect traffic. This could be used for a few different things, but the obvious primary use-case (and the one called out in the blog post) is HTTP->HTTPS redirects. So hopefully there's a potential clean way for alb-ingress-controller to offer this feature.

Feature announcement, supports redirects and static responses without hitting the backend: https://aws.amazon.com/about-aws/whats-new/2018/07/elastic-load-balancing-announces-support-for-redirects-and-fixed-responses-for-application-load-balancer/

Specific documentation for redirects: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#redirect-actions

kinfeature

Most helpful comment

For reference, here is my working ingress object:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.redirect: '{"Type": "redirect", "RedirectConfig":
      { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: redacted
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80,"HTTPS": 443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/subnets: redacted
  name: test
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: redirect
          servicePort: use-annotation
        path: /*
  - host: test.com
    http:
      paths:
      - backend:
          serviceName: test
          servicePort: 80
        path: /*

All 92 comments

Please someone do this 馃帀

@bigkraig Are you planning to have this in v1.0?

How would you all like to see this implemented? The ingress spec is somewhat limiting.

Even I am looking for https redirection with alb-ingress.When are you guys planning to implement this feature??

@bigkraig I think it would make sense to have this as another ingress annotation?

I think that would be the only way, but I hate to make people make more json encoded annotation strings.

The ingress backend spec has serviceName and servicePort.

I'm pretty sure service names can't include a :, so what if we used that to configure the ALB rule actions?

Something like this

paths:
- path: /invalid
  backend:
    serviceName: fixed-response:{"ContentType":"text/plain","StatusCode":503,"MessageBody":"message body"}
- path: /
  backend:
    serviceName: echoserver
    servicePort: 80

I think it's better to have a boolean annotation and redirect all HTTP requests to HTTPS requests by a listener creation to AWS. What do you think @bigkraig ?

The redirect action is much more powerful than that and rather than providing two methods that would conflict, i'd prefer to let users leverage all of the action options in the same method.

^ I would agree with @bigkraig it would be good to provide an easy example of the HTTP -> HTTPS config but lets not do two functionality sets, I think that implementation looks good @bigkraig.

I agree with you about the reusable methods. If you can provide examples then I think it totally works. Anw, I think it's still best to extend the method and utilise what AWS offers.

This is pretty big for us, what's the current workaround you've been using to enforce this?

At least I'm using https proxy (a nginx app with redirect feature).
However, if we can use AWS ALB feature, it's best.
I tried to create the listener manually but after that, it makes reconcile procedure error as SG has 1 more rule and ALB has 1 more listener.

How do you think if all the state of resources at AWS can be the super-set of what has been configured in the Ingress object?

Using the serviceName field won't work, there is some validation that happens.

# * spec.rules[0].http.backend.serviceName: Invalid value: "test:test": a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name',  or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?')

Yeah. I thought about this and it happened with validation.
Is that big to extend the create listener function? @bigkraig

the hard part is figuring out a way to configure the actions without making a bunch of complicated annotations. i'll try to find some time to think about it today

What does everyone think of this? My only concern here is if the service name my-fixed-response also corresponds to a service in the cluster. In that case I would just default to the annotation.

The idea is that we can define actions using the alb.ingress.kubernetes.io/actions.<action name> annotation and then reference the action in the serviceName. servicePort is unfortunately a required field.

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.my-fixed-response: >-
      {"Type": "fixed-response", "Config": {"ContentType":"text/plain",
      "StatusCode":503, "MessageBody":"message body"}}
spec:
  rules:
    - http:
        paths:
          - path: /503-action-path
            backend:
              serviceName: my-fixed-response
              servicePort: unused

@bigkraig I think for the type fixed-response, it's good enough. How's about an example for redirect?

@anhpham1509 the action looks like:

                    "Type": "redirect",
                    "Order": 1,
                    "RedirectConfig": {
                        "Protocol": "HTTPS",
                        "Port": "44",
                        "Host": "#{host}",
                        "Path": "/#{path}",
                        "Query": "#{query}",
                        "StatusCode": "HTTP_301"
                    }

I think Order is unused, or at least I didn't see a way to configure it in the console. The AWS docs describe protocol://hostname:port/path?query as a config URI, so we could go with the URI or we could go with individual fields. Individual fields would be easier to implement but maybe more complicated to read in an annotation.

alb.ingress.kubernetes.io/actions.my-redirect-via-params: >-
  {"Type": "redirect", "Config": {"Protocol":"HTTPS",
  "Port":"443", "Host":"#{host}", "Path": "/#{path}", "Query": "#{query}", "StatusCode": "HTTP_301"}}
alb.ingress.kubernetes.io/actions.my-redirect-via-uri: >-
  {"Type": "redirect", "Config": {"URI":"https://#{host}:443//#{path}?#{query}", "StatusCode": "HTTP_301"}}

Yeah. This sounds really good, IMO.
How big is this to be implemented?
I think handling annotations for usage in rule is a bit complicated.

It's probably a little more than half a day of work. I'd just need to parse the annotations into a new action type and then replace service backends with those actions, but i'm sure there will be some problems along the way.

A bit longer than that, since the default backend stuff would also need it and it has different logic to deal with.

Thinking about it, we should also have some kind of way to trigger the annotation usage, incase there are naming conflicts. So use servicePort for that:

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.my-fixed-response: >-
      {"Type": "fixed-response", "Config": {"ContentType":"text/plain",
      "StatusCode":503, "MessageBody":"message body"}}
spec:
  rules:
    - http:
        paths:
          - path: /503-action-path
            backend:
              serviceName: my-fixed-response
              servicePort: actions-annotation

I'll probably reuse the SDKs types and support all configuration options in https://docs.aws.amazon.com/sdk-for-go/api/service/elbv2/#Action

Sounds good with the use of servicePort. I鈥檓 thinking this would probably takes more than a day. Hope that you have time to implement this soon.

@anhpham1509 I type fast.

If anyone wants to try it out, see #542. Docs are in there and before I give some examples i'd prefer if people read the doc and make sure it is easy to understand, it's probably one of the more complicated annotations.

The only thing left to do in #542 is to add support for the custom actions for the ingresses default backend. I'll probably tackle that next week sometime.

@bigkraig Incredible speed. 馃憦
I left some comments in the PR. You can take a look through ;-)

Resolved via #542, i'll cut a 1.0-beta.6 tag as soon as I double check that there isn't something else that I want to get in there.

Done! Please see https://github.com/kubernetes-sigs/aws-alb-ingress-controller/blob/master/docs/ingress-resources.md on how to configure the actions with the alb.ingress.kubernetes.io/actions.* annotation.

/reopen

@bigkraig I tried to create a redirect action and failed to do so. Can you give me a full ingress example?

@anhpham1509: you can't re-open an issue/PR unless you authored it or you are assigned to it.

In response to this:

/reopen

@bigkraig I tried to create a redirect action and failed to do so. Can you give me a full ingress example?

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@anhpham1509 Can you tell me what you tried and what error you got? The example in the docs was from one that I had used.

alb.ingress.kubernetes.io/actions.redirect: {"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "StatusCode": "HTTP_301"}}

with serviceName: redirect and servicePort: use-annotation

@bigkraig shouldn't the json be enclosed in ' so it's a string?

Also, do you need to add: alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80, "HTTPS": 443}]'? or would that mess up with the action?

When I implement HTTP to HTTPS redirect as follows:

alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80, "HTTPS": 443}]'
alb.ingress.kubernetes.io/actions.service-api: '{"Type": "redirect", "RedirectConfig":{ "Protocol": "HTTPS", "StatusCode": "HTTP_301"}}'
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: service-api
          servicePort: use-annotation

The redirect happens like this: http://app.myservice.com/status -> https://app.myservice.com:80/status

Also if I look at the logs I see:

 1 albingress.go:292] default/service-api:  - Failed Listener modification: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.

UID:"36995ba8-8a32-11e8-b646-0e497ceae82a", APIVersion:"extensions/v1beta1", ResourceVersion:"4463108", FieldPath:""}): type: 'Warning' reason: 'ERROR' Error modifying 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.

Which makes sense because I don't want the HTTPS rule to do the redirect, that wouldn't make sense, only HTTP, and it's doing it for HTTP (although wrong because it adds :80 after the URL. What am I doing wrong?

Update: I added Port: "443". In my RedirectConfig and that works, maybe the docs should be updated to show that. The problem I have now is that it still tries to update the HTTPS listener too, not only the HTTP one.

I think if the redirect annotation exist, it should redirect all HTTP to HTTPS without an action to specify serviceName and servicePort in the spec.rules section.

@anhpham1509 I think that should be configurable per rule. I would imagine a use case where you have multiple services behind a single ALB ingress and only want to turn this on for single services.

I'm currently getting the same error as @gabzim. Seems like the controller tries to apply the rule for both listeners, HTTP and HTTPS, which results in the HTTPS -> HTTPS loop.

I think this starts to get into what is requested in #135, where you can configure specific services for specific listeners.

@bigkraig what about the bug that @devkid and I are running into? Seems like the controller tries to apply the rule for both listeners, HTTP and HTTPS, which results in the HTTPS -> HTTPS loop.

Also how does use-annotation work exactly? what if your service is running on port 2000, how will servicePort know that?

Right, all of the rules are applies to all of the listeners equally, being able to configure them to specific listeners is what is requested in #135. So you would only apply the HTTP redirect rule to your HTTP port. I'd like to avoid adding a special case for HTTP, since it wouldn't be obvious to users what is happening and most likely leads to more special cases.

WRT use-annotation I am not sure I understand, when that port is applied the "service" is no longer a kubernetes service, but an annotation describing an ALB action.

So are you saying that as it stands now, the HTTP -> HTTPS will not work then? It doesn't for me because I run into the above mentioned problem. It redirects HTTP -> HTTPS successfully but then goes and tries to do HTTPS -> HTTPS. So I guess I can't use the newly added actions yet.

What do you guys think about what was just mentioned in #298, https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/mergeable-ingress-types?

It would mean you would have to define a few ingress objects for the single ALB.

This would actually be awesome. This would also make the mapping ALB -> "Ingress master", Listener -> "Ingress slave", Target group -> service clearer.

@devkid Hi, I agree that the port should be configurable.
@bigkraig Can you add the HTTP -> HTTPS boolean annotation as I think it's common case people are using for redirects.
About the multiple Ingress solution, I think it's just too complicated to use that just for HTTPS redirect.

As I understood from the comments, an annotation for a specific use case is discouraged when a more general annotation is available. Having said that, I do believe HTTP -> HTTPS is a huge use case that probably merits a simple one-liner to pull off.

I would say that this ticket is not done yet. Please reopen this anw, @bigkraig.

Also, if you insist on using this action annotation, then redirect case should go without any additional serviceName and servicePort specification.

What's on your mind?

@bigkraig Do you have any time this week for this ticket?

Ping @bigkraig

Any updates for this ticket? @bigkraig

bigraik replies quickly, I think we should just wait for him to have time instead of spamming this thread.

Hey everybody. I'm starting to side with the crowd on this one, while I hate to have behind the scenes magic going on, I am not seeing other one-off cases that would need to be dealt with and it would definitely simplify the definitions if we just filtered out HTTPS->HTTPS redirects.

Our sandbox cluster is going through maintenance right now but if that is available later today, I'll look to getting this in there.

@bigkraig Yeah. If the HTTPS->HTTPS redirects can be filtered out, it's awesome.
I just check your implementation and it seems to be very promising.
How can we test it out?

@anhpham1509 try out the 487-https-loops tag

So, what's currently the proper way to add this? I have this annotation: alb.ingress.kubernetes.io/actions.service-api: '{"Type": "redirect", "RedirectConfig":{"Protocol": "HTTPS", "StatusCode": "HTTP_301"}}', but it doesn't seem to do anything. Do I need to add an extra backend for / with serviceName: service-api and servicePort: use-annotation? How does this fit if I already have a backend for /?

The nginx ingress controller supports the ingress.kubernetes.io/force-ssl-redirect annotation to provide this feature. The ingress spec looks, if anything, to be geared _against_ doing port-specific stuff, which I think makes sense. The only time it's sane to do different things on port 80 vs. 443 is redirecting HTTP to HTTPS. The downside is when you come to this very simple definition:

spec:
  rules:
    - host: hosty.hostname
      http:
        paths:
          - path: /
            backend:
              serviceName: ui
              servicePort: 8080

What can I put there to indicate that I want HTTP to be redirected to HTTPS? : in the host is prohibited. Doing anything with a path rule doesn't make sense.

Would something like this do what you're looking for, and if not, what would you need done? These action annotations are just starting to be used.

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.my-fixed-response: >-
      {"Type": "fixed-response", "FixedResponseConfig":
      {"ContentType":"text/plain", "StatusCode":"502", "MessageBody":"message
      body"}}
    alb.ingress.kubernetes.io/actions.redirect: >-
      {"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS",
      "StatusCode": "HTTP_301"}}
    alb.ingress.kubernetes.io/certificate-arn: >-
      arn:aws:acm:us-east-1:XXXXXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80, "HTTPS": 443}]'
  name: example
spec:
  backend:
    serviceName: my-fixed-response
    servicePort: use-annotation
  rules:
    - host: hosty.hostname
      http:
        paths:
          - backend:
              serviceName: redirect
              servicePort: use-annotation
          - backend:
              serviceName: hosty-service
              servicePort: 8080

That looks fine to me

@bigkraig The redirect is working now.
However, I would like to ignore the creation of rule forward to hosty-service if the redirect exists in the source listener port.
Can you turn them in?

@anhpham1509 sorry, i'm not clear on what you are asking

@bigkraig I can explain my idea by example.

If I configure the Ingress the same way like this

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.my-fixed-response: >-
      {"Type": "fixed-response", "FixedResponseConfig":
      {"ContentType":"text/plain", "StatusCode":"502", "MessageBody":"message
      body"}}
    alb.ingress.kubernetes.io/actions.redirect: >-
      {"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS",
      "StatusCode": "HTTP_301"}}
    alb.ingress.kubernetes.io/certificate-arn: >-
      arn:aws:acm:us-east-1:XXXXXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80, "HTTPS": 443}]'
  name: example
spec:
  backend:
    serviceName: my-fixed-response
    servicePort: use-annotation
  rules:
    - host: hosty.hostname
      http:
        paths:
          - backend:
              serviceName: redirect
              servicePort: use-annotation
          - backend:
              serviceName: hosty-service
              servicePort: 8080

Currently, it will create listener HTTP:80 for ALB with 3 rules: 1 redirect, 1 forward and 1 default and listener HTTPS:443 for ALB with 2 rules: 1 forward and 1 default.

IMO, if a listener has redirect config, it should not contain forward config.

You've closed this issue, but it still isn't working for me:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: main-ingress-alb
  namespace: qa
  labels:
    app: main-ingress-alb
  annotations:
    external-dns.alpha.kubernetes.io/hostname: me.example.com.

    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: redacted
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80, "HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.service-api: '{"Type": "redirect", "RedirectConfig":{ "Protocol": "HTTPS",
"StatusCode": "HTTP_301"}}'

    # healthcheck endpoints are defined on a per-service basis
    alb.ingress.kubernetes.io/backend-protocol: HTTPS
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTPS
spec:
  rules:
  - host:
    http:
      paths:
        - backend:
            serviceName: redirect
            servicePort: use-annotation
        - backend:
            serviceName: nginx-router-service
            servicePort: 443

I'm getting this error in the controller:

I0908 17:47:10.755211       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"qa", Name:"main-ingress-alb", UID:"e04654a5-b2b4-11e8-9630-0a98811e7e92", APIVersion:"extensions/v1beta1", ResourceVersion:"303198", FieldPath:""}): type: 'Warning' reason: 'ERROR' error instantiating load balancer: `servicePort: use-annotation` was requested for`serviceName: redirect` but an annotation for that action does not exist

I'm using image: quay.io/coreos/alb-ingress-controller:d1782a0. What am I doing wrong? I'm simply unclear how this is supposed to be used.

You named your action service-api not redirect

Wow, thank you @bigkraig. That was a good one.

Now I've got this error:

I0908 19:03:17.904695       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"qa", Name:"main-ingress-alb", UID:"e04654a5-b2b4-11e8-9630-0a98811e7e92", APIVersion:"extensions/v1beta1", ResourceVersion:"314042", FieldPath:""}): type: 'Normal' reason: 'MODIFY' 80 listener modified
I0908 19:03:17.930354       1 rule.go:143] qa/main-ingress-alb: Start Rule creation.
I0908 19:03:17.930565       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"qa", Name:"main-ingress-alb", UID:"e04654a5-b2b4-11e8-9630-0a98811e7e92", APIVersion:"extensions/v1beta1", ResourceVersion:"314042", FieldPath:""}): type: 'Normal' reason: 'MODIFY' 1 rule modified
I0908 19:03:17.953572       1 rule.go:148] qa/main-ingress-alb: Completed Rule creation. Rule Priority: "2" | Condition: [{    Field: "path-pattern",    Values: ["/"]  }]
I0908 19:03:17.953768       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"qa", Name:"main-ingress-alb", UID:"e04654a5-b2b4-11e8-9630-0a98811e7e92", APIVersion:"extensions/v1beta1", ResourceVersion:"314042", FieldPath:""}): type: 'Normal' reason: 'CREATE' 2 rule created
E0908 19:03:17.987357       1 albingress.go:290] qa/main-ingress-alb: Failed to reconcile state on this ingress
E0908 19:03:17.987375       1 albingress.go:292] qa/main-ingress-alb:  - Failed Listener modification: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
E0908 19:03:17.987380       1 albingress.go:292] qa/main-ingress-alb:   status code: 400, request id: d8906535-b399-11e8-b1ed-f180442d9087
E0908 19:03:17.987392       1 albingress.go:295] qa/main-ingress-alb: Will retry to reconcile in 1m0.325465532s
I0908 19:03:17.987490       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"qa", Name:"main-ingress-alb", UID:"e04654a5-b2b4-11e8-9630-0a98811e7e92", APIVersion:"extensions/v1beta1", ResourceVersion:"314042", FieldPath:""}): type: 'Warning' reason: 'ERROR' Error modifying 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
    status code: 400, request id: d8906535-b399-11e8-b1ed-f180442d9087

It did seem to work, however. Though, when I curl it I get this:

$ curl -i me.example.com -L
HTTP/1.1 301 Moved Permanently
Server: awselb/2.0
Date: Sat, 08 Sep 2018 19:07:09 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
Location: https://me.example.com:80/

curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

So it's not redirecting to the right port.

Ah, fixed the above with @gabzim 's comment from earlier. For documentation purposes, here's the working yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: main-ingress-alb
  namespace: qa
  labels:
    app: main-ingress-alb
  annotations:
    external-dns.alpha.kubernetes.io/hostname: me.example.com.

    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: <acm arn>
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80, "HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.redirect: '{"Type": "redirect", "RedirectConfig":{ "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'

    # healthcheck endpoints are defined on a per-service basis
    alb.ingress.kubernetes.io/backend-protocol: HTTPS
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTPS
spec:
  rules:
  - host:
    http:
      paths:
        - backend:
            serviceName: redirect
            servicePort: use-annotation
        - backend:
            serviceName: nginx-router-service
            servicePort: 443

This still produces the loop error above, though.

Are you running either the latest or 487-https-loops images?

@bigkraig I'm running quay.io/coreos/alb-ingress-controller:d1782a0

@smaslennikov

Looking at your yaml your internal nginx is on port 443? Is it supposed to be https from the alb to the nginx service? Im not sure albs have a specification for protocol from the alb to the backend service. https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html explicitly notates the alb's ssl capabilities as 'ssl offload'.

I am running latest and it produces the loop error above. The only way it doesn't is if I put the serviceName:redirect after the standard service. However that then creates the rule for port 80 to go to the target group and then the second rule is the redirect rule

I just tried it with the 487-https-loops branch and the same thing happens

on:"extensions/v1beta1", ResourceVersion:"3038952", FieldPath:""}): type: 'Warning' reason: 'ERROR' Error creating 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
        status code: 400, request id: 60c69d87-b520-11e8-b92d-0b414361bf96
F0910 17:38:50.531278       1 albingresses.go:167] ERROR: Work Unit failed due to a recoverable error: 'runtime error: invalid memory address or nil pointer dereference'
, Stack Trace:

This is my yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: sacp-alb
  namespace: default
  annotations:
    alb.ingress.kubernetes.io/actions.redirect: '{"Type": "redirect", "RedirectConfig":{
      "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:371066304662:certificate/309a6d7a-a4fb-415f-9b4d-718c4c3dda36
    alb.ingress.kubernetes.io/healthcheck-path: /login.html
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80,"HTTPS": 443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/tags: Environment=dev,Team=devops,Note=k8s
    alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true, stickiness.lb_cookie.duration_seconds=86400
    alb.ingress.kubernetes.io/target-type: ip
    kubernetes.io/ingress.class: alb

spec:
  rules:
    - host: foo
      http:
        paths:
          - backend:
              serviceName: redirect
              servicePort: use-annotation
          - backend:
              serviceName: foo
              servicePort: 80

@bdirito yeah, I must maintain SSL on hops due to HIPAA. Or something like that.

@smaslennikov ah. im not familiar with the intricacies there. do you know for sure such a thing can be done with albs?

@bigkraig
I am seeing the same thing as qgriffith-xylem.

E0910 18:23:32.700816       1 albingress.go:290] splunk/splunk: Failed to reconcile state on this ingress
E0910 18:23:32.700834       1 albingress.go:292] splunk/splunk:  - Failed Listener modification: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
E0910 18:23:32.700839       1 albingress.go:292] splunk/splunk:         status code: 400, request id: 9fa649a8-b526-11e8-8e7d-85cb66be53b8
E0910 18:23:32.700849       1 albingress.go:295] splunk/splunk: Will retry to reconcile in 3m58.910034089s
I0910 18:23:32.701033       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"splunk", Name:"splunk", UID:"a8cc8a2e-a4aa-11e8-9812-06e1fa182b34", APIVersion:"extensions/v1beta1", ResourceVersion:"7277806", FieldPath:""}): type: 'Warning' reason: 'ERROR' Error modifying 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
        status code: 400, request id: 9fa649a8-b526-11e8-8e7d-85cb66be53b``
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: splunk
  namespace: splunk
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-abc123...
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/security-groups: albing
    alb.ingress.kubernetes.io/success-codes: 303,200
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80, "HTTPS": 443}]'
    alb.ingress.kubernetes.io/actions.redirect: >-
      {"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS",
      "StatusCode": "HTTP_301"}}
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: redirect
              servicePort: use-annotation
    - host: splunk.example.com
      http:
        paths:
          # - backend:
          #     serviceName: redirect
          #     servicePort: use-annotation
          - path:
            backend:
              serviceName: splunkweb
              servicePort: 80
    - host: splunkhec.example.com
      http:
        paths:
          # - backend:
          #     serviceName: redirect
          #     servicePort: use-annotation

          - path:
            backend:
              serviceName: splunkhec
              servicePort: 80

Note that with my slightly different config and use of latest this log does NOT have the null memory dereference error as shown in qgriffith-xylem

@qgriffith-xylem ive found that you can pass in a port to the redirect action. this makes the redirect action work. However it still reports itself as failing in the log and goes into its backoff logic.

    alb.ingress.kubernetes.io/actions.redirect: >-
      {"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS",
      "StatusCode": "HTTP_301", "Port": "443"}}

@bdirito
Mine if failing to create the 443 listener, it creates the 80 then crashes with the memory issue during the 443 part and does the bit about how it can't create it because it would cause a redirect loop

Same here. I'm getting below with image 487-https-loops.
InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.

Is it possible to re-open this issue?
It's still working neither with latest nor with 487-https-loops . 馃憥

I'll try and take a look at this again today. I tested one of the configurations yesterday and I wasn't able to reproduce it.

@bigkraig Please let me know if you need any information, happy to help.

I saw there was alistener-nil-pointerimage out there and gave it a try. The alb pod no longer crashes however 443 isn't being made

 Warning  ERROR   34s  aws-alb-ingress-controller  Error creating 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
           status code: 400, request id: 163a8898-b763-11e8-bccc-8300fb2f0b19

Getting closer

@qgriffith-xylem can you run with --aws-api-debug true and see what that request looks like? I wasn't able to reproduce it on my side with similar ingresses so i'm having a hard time fixing it. That info might help me produce a test case.

Sure thing, here is the output

0913 16:53:07.483682       1 loadbalancer.go:265] default/sacp-alb: Start ELBV2 creation.
I0913 16:53:07.483993       1 loadbalancer.go:404] Request: elasticloadbalancing/CreateLoadBalancer, Payload: {  IpAddressType: "ipv4",  Name: "3440dd9e-default-sacpalb-bb86",  Scheme: "internet-facing",  SecurityGroups: ["sg-978638e6"],  Subnets: [    "subnet-0f940678",    "subnet-360ab96f",    "subnet-c1ef95fb",    "subnet-c8ae76e3"  ],  Tags: [    {      Key: "Environment",      Value: "dev"    },    {      Key: "Team",      Value: "devops"    },    {      Key: "Note",      Value: "k8s"    },    {      Key: "kubernetes.io/cluster/sa-dev-eks-1",      Value: "owned"    },    {      Key: "kubernetes.io/namespace",      Value: "default"    },    {      Key: "kubernetes.io/ingress-name",      Value: "sacp-alb"    }  ]}
I0913 16:53:08.277061       1 loadbalancer.go:272] default/sacp-alb: Completed ELBV2 creation. Name: 3440dd9e-default-sacpalb-bb86 | ARN: arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c
I0913 16:53:08.277083       1 targetgroup.go:225] default/sacp-alb: Start TargetGroup creation.
I0913 16:53:08.277260       1 targetgroup.go:266] Request: elasticloadbalancing/CreateTargetGroup, Payload: {  HealthCheckIntervalSeconds: 15,  HealthCheckPath: "/login.html",  HealthCheckPort: "traffic-port",  HealthCheckProtocol: "HTTP",  HealthCheckTimeoutSeconds: 5,  HealthyThresholdCount: 2,  Matcher: {    HttpCode: "200"  },  Name: "3440dd9e-e5f5084bacfe6b7d2f3",  Port: 1,  Protocol: "HTTP",  TargetType: "ip",  UnhealthyThresholdCount: 2,  VpcId: "vpc-b6e29ed3"}
I0913 16:53:08.277290       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Normal' reason: 'CREATE' 3440dd9e-default-sacpalb-bb86 created
I0913 16:53:08.473731       1 elbv2.go:519] Request: elasticloadbalancing/AddTags, Payload: {  ResourceArns: ["arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31"],  Tags: [    {      Key: "Environment",      Value: "dev"    },    {      Key: "Team",      Value: "devops"    },    {      Key: "Note",      Value: "k8s"    },    {      Key: "kubernetes.io/cluster/sa-dev-eks-1",      Value: "owned"    },    {      Key: "kubernetes.io/namespace",      Value: "default"    },    {      Key: "kubernetes.io/ingress-name",      Value: "sacp-alb"    },    {      Key: "kubernetes.io/service-name",      Value: "sacp-war"    },    {      Key: "kubernetes.io/service-port",      Value: "9090"    }  ]}
I0913 16:53:08.545519       1 targetgroup.go:475] Request: elasticloadbalancing/RegisterTargets, Payload: {  TargetGroupArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31",  Targets: [{      Id: "10.32.13.49",      Port: 8080    },{      Id: "10.32.16.220",      Port: 8080    }]}
I0913 16:53:08.875790       1 targetgroup.go:294] Request: elasticloadbalancing/ModifyTargetGroupAttributes, Payload: {  Attributes: [{      Key: "stickiness.enabled",      Value: "true"    },{      Key: "stickiness.lb_cookie.duration_seconds",      Value: "86400"    }],  TargetGroupArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31"}
I0913 16:53:08.912261       1 targetgroup.go:230] default/sacp-alb: Succeeded TargetGroup creation. ARN: arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31 | Name: 3440dd9e-e5f5084bacfe6b7d2f3.
I0913 16:53:08.912285       1 listener.go:197] default/sacp-alb: Start Listener creation.
I0913 16:53:08.912366       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Normal' reason: 'CREATE' 3440dd9e-e5f5084bacfe6b7d2f3 target group created
I0913 16:53:08.912459       1 listener.go:240] Request: elasticloadbalancing/CreateListener, Payload: {  DefaultActions: [{      RedirectConfig: {        Host: "#{host}",        Path: "/#{path}",        Port: "443",        Protocol: "HTTPS",        Query: "#{query}",        StatusCode: "HTTP_301"      },      Type: "redirect"    }],  LoadBalancerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c",  Port: 80,  Protocol: "HTTP"}
I0913 16:53:08.948382       1 listener.go:202] default/sacp-alb: Completed Listener creation. ARN: arn:aws:elasticloadbalancing:us-east-1:371066304662:listener/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c/9c2dafd57b153c27 | Port: 80 | Proto: HTTP.
I0913 16:53:08.948401       1 rule.go:143] default/sacp-alb: Start Rule creation.
I0913 16:53:08.948535       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Normal' reason: 'CREATE' 80 listener created
I0913 16:53:08.948604       1 rule.go:183] Request: elasticloadbalancing/CreateRule, Payload: {  Actions: [{      RedirectConfig: {        Host: "#{host}",        Path: "/#{path}",        Port: "443",        Protocol: "HTTPS",        Query: "#{query}",        StatusCode: "HTTP_301"      },      Type: "redirect"    }],  Conditions: [{      Field: "host-header",      Values: ["sacp-k8s.dev1-sensus-analytics.com"]    },{      Field: "path-pattern",      Values: ["/"]    }],  ListenerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:listener/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c/9c2dafd57b153c27",  Priority: 1}
I0913 16:53:09.015582       1 rule.go:148] default/sacp-alb: Completed Rule creation. Rule Priority: "1" | Condition: [{    Field: "host-header",    Values: ["sacp-k8s.dev1-sensus-analytics.com"]  },{    Field: "path-pattern",    Values: ["/"]  }]
I0913 16:53:09.015604       1 rule.go:143] default/sacp-alb: Start Rule creation.
I0913 16:53:09.015691       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Normal' reason: 'CREATE' 1 rule created
I0913 16:53:09.015879       1 rule.go:183] Request: elasticloadbalancing/CreateRule, Payload: {  Actions: [{      TargetGroupArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31",      Type: "forward"    }],  Conditions: [{      Field: "host-header",      Values: ["sacp-k8s.dev1-sensus-analytics.com"]    },{      Field: "path-pattern",      Values: ["/"]    }],  ListenerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:listener/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c/9c2dafd57b153c27",  Priority: 2}
I0913 16:53:09.171619       1 rule.go:148] default/sacp-alb: Completed Rule creation. Rule Priority: "2" | Condition: [{    Field: "host-header",    Values: ["sacp-k8s.dev1-sensus-analytics.com"]  },{    Field: "path-pattern",    Values: ["/"]  }]
I0913 16:53:09.171644       1 listener.go:197] default/sacp-alb: Start Listener creation.
I0913 16:53:09.171836       1 listener.go:240] Request: elasticloadbalancing/CreateListener, Payload: {  Certificates: [{      CertificateArn: "arn:aws:acm:us-east-1:371066304662:certificate/309a6d7a-a4fb-415f-9b4d-718c4c3dda36"    }],  DefaultActions: [{      RedirectConfig: {        Host: "#{host}",        Path: "/#{path}",        Port: "443",        Protocol: "HTTPS",        Query: "#{query}",        StatusCode: "HTTP_301"      },      Type: "redirect"    }],  LoadBalancerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c",  Port: 443,  Protocol: "HTTPS",  SslPolicy: "ELBSecurityPolicy-2016-08"}
I0913 16:53:09.171874       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Normal' reason: 'CREATE' 2 rule created
E0913 16:53:09.487418       1 api.go:318] Failed request: elasticloadbalancing/CreateListener, Payload: {  Certificates: [{      CertificateArn: "arn:aws:acm:us-east-1:371066304662:certificate/309a6d7a-a4fb-415f-9b4d-718c4c3dda36"    }],  DefaultActions: [{      RedirectConfig: {        Host: "#{host}",        Path: "/#{path}",        Port: "443",        Protocol: "HTTPS",        Query: "#{query}",        StatusCode: "HTTP_301"      },      Type: "redirect"    }],  LoadBalancerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c",  Port: 443,  Protocol: "HTTPS",  SslPolicy: "ELBSecurityPolicy-2016-08"}, Error: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
        status code: 400, request id: 7e3c2e88-b775-11e8-9b2f-df73d947993a
E0913 16:53:09.487557       1 albingress.go:290] default/sacp-alb: Failed to reconcile state on this ingress
E0913 16:53:09.487566       1 albingress.go:292] default/sacp-alb:  - Failed Listener creation: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
E0913 16:53:09.487570       1 albingress.go:292] default/sacp-alb:      status code: 400, request id: 7e3c2e88-b775-11e8-9b2f-df73d947993a.
E0913 16:53:09.487579       1 albingress.go:295] default/sacp-alb: Will retry to reconcile in 501.08777ms
I0913 16:53:09.487598       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Warning' reason: 'ERROR' Error creating 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
        status code: 400, request id: 7e3c2e88-b775-11e8-9b2f-df73d947993a
I0913 16:53:33.222690       1 loadbalancer.go:511] default/sacp-alb: Modifying ELBV2 tags to [  {    Key: "Environment",    Value: "dev"  },  {    Key: "Note",    Value: "k8s"  },  {    Key: "Team",    Value: "devops"  },  {    Key: "kubernetes.io/cluster/sa-dev-eks-1",    Value: "owned"  },  {    Key: "kubernetes.io/ingress-name",    Value: "sacp-alb"  },  {    Key: "kubernetes.io/namespace",    Value: "default"  }].
I0913 16:53:33.222859       1 elbv2.go:519] Request: elasticloadbalancing/AddTags, Payload: {  ResourceArns: ["arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c"],  Tags: [    {      Key: "Environment",      Value: "dev"    },    {      Key: "Note",      Value: "k8s"    },    {      Key: "Team",      Value: "devops"    },    {      Key: "kubernetes.io/cluster/sa-dev-eks-1",      Value: "owned"    },    {      Key: "kubernetes.io/ingress-name",      Value: "sacp-alb"    },    {      Key: "kubernetes.io/namespace",      Value: "default"    }  ]}
I0913 16:53:33.276507       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Normal' reason: 'MODIFY' 3440dd9e-default-sacpalb-bb86 tags modified
I0913 16:53:33.276562       1 listener.go:197] default/sacp-alb: Start Listener creation.
I0913 16:53:33.276762       1 listener.go:240] Request: elasticloadbalancing/CreateListener, Payload: {  Certificates: [{      CertificateArn: "arn:aws:acm:us-east-1:371066304662:certificate/309a6d7a-a4fb-415f-9b4d-718c4c3dda36"    }],  DefaultActions: [{      RedirectConfig: {        Host: "#{host}",        Path: "/#{path}",        Port: "443",        Protocol: "HTTPS",        Query: "#{query}",        StatusCode: "HTTP_301"      },      Type: "redirect"    }],  LoadBalancerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c",  Port: 443,  Protocol: "HTTPS",  SslPolicy: "ELBSecurityPolicy-2016-08"}
E0913 16:53:33.335800       1 api.go:318] Failed request: elasticloadbalancing/CreateListener, Payload: {  Certificates: [{      CertificateArn: "arn:aws:acm:us-east-1:371066304662:certificate/309a6d7a-a4fb-415f-9b4d-718c4c3dda36"    }],  DefaultActions: [{      RedirectConfig: {        Host: "#{host}",        Path: "/#{path}",        Port: "443",        Protocol: "HTTPS",        Query: "#{query}",        StatusCode: "HTTP_301"      },      Type: "redirect"    }],  LoadBalancerArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:loadbalancer/app/3440dd9e-default-sacpalb-bb86/3787e1828778aa7c",  Port: 443,  Protocol: "HTTPS",  SslPolicy: "ELBSecurityPolicy-2016-08"}, Error: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
        status code: 400, request id: 8c9a5051-b775-11e8-a841-e93d5dfe5193
I0913 16:53:33.335851       1 targetgroup.go:209] default/sacp-alb: Start TargetGroup deletion. ARN: arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31 | Name: 3440dd9e-e5f5084bacfe6b7d2f3.
I0913 16:53:33.335965       1 elbv2.go:319] Request: elasticloadbalancing/DeleteTargetGroup, Payload: {  TargetGroupArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31"}
I0913 16:53:33.336004       1 event.go:221] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"sacp-alb", UID:"7d0ed9fc-b775-11e8-bb39-12e8e94032c2", APIVersion:"extensions/v1beta1", ResourceVersion:"3515806", FieldPath:""}): type: 'Warning' reason: 'ERROR' Error creating 443 listener: InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.
        status code: 400, request id: 8c9a5051-b775-11e8-a841-e93d5dfe5193
E0913 16:53:33.410116       1 api.go:1025] Failed request: elasticloadbalancing/DeleteTargetGroup, Payload: {  TargetGroupArn: "arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31"}, Error: ResourceInUse: Target group 'arn:aws:elasticloadbalancing:us-east-1:371066304662:targetgroup/3440dd9e-e5f5084bacfe6b7d2f3/7f1aa34de9706b31' is currently in use by a listener or a rule
        status code: 400, request id: 8ca636de-b775-11e8-af25-19718a8be12f

@bigkraig Anything else I can do to help? This is the last thing on my list to get working before I can go live with k8s. So let me know what I can do to assist. Thanks.

so the new defaultbackend-404 image worked from the stand point it no longer throws a redirect error and 443 listener is created. However everything is throwing a 404 that I try to hit on the ALB. if I hit the app outside of the ALB I don't get a 404 and get the page I expect.

Ok if I remove ```
IF(all match)

Path is /
```
From the rule all works as it should but I don't know what is adding that rule and it will get re-created all the time.

So I have it working with

spec:
  rules:
    - http:
       paths:
         - path: /*
           backend:
              serviceName: redirect
              servicePort: use-annotation 
    - host: foo
      http:
        paths:
          - path: /*
            backend:
             serviceName: foo
             servicePort: 9090  

I got one nil pointer it seemed to be because I didn't have enough spaces between backend: and serviceName on the new line. Once I fixed that and re-deployed all was well. Great work @bigkraig

Is it OK to swtich to latest now or can you let us know when it is merged? @bigkraig

@qgriffith-xylem it'll be merged soon but we are still a little bit away from the next beta release

For reference, here is my working ingress object:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.redirect: '{"Type": "redirect", "RedirectConfig":
      { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: redacted
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80,"HTTPS": 443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/subnets: redacted
  name: test
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: redirect
          servicePort: use-annotation
        path: /*
  - host: test.com
    http:
      paths:
      - backend:
          serviceName: test
          servicePort: 80
        path: /*

Guys, please add this as an example in the repository. This is something very common when using ALBs.

@AndresPineros
Hi, the docs are now available in https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/tasks/ssl_redirect/ 馃槃

I understand this topic is marked as closed, but I was wondering if there is a way to stop :443 from being appended to #{host}?

I've tried doing this (I note a comment made), but does not appear to be valid syntax. Not at least from internal/alb/ls/rules_test.go

    alb.ingress.kubernetes.io/actions.ssl-redirect: >-
      {   
        "Type": "redirect",
        "RedirectConfig": {
          "URI": "https://#{host}/#{path}?#{query}",
          "StatusCode": "HTTP_301"
        }   
      } 

Perhaps a URI feature can be added for config flexibility?

:443 shows up with curl

$ curl -k  -H 'Host: www.example.com' -IL http://xxx.ap-southeast-2.elb.amazonaws.com
HTTP/1.1 301 Moved Permanently
Server: awselb/2.0
Date: Wed, 13 Nov 2019 03:02:37 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
Location: https://www.example.com:443/

HTTP/2 301
server: nginx
date: Wed, 13 Nov 2019 03:02:38 GMT
content-type: text/html; charset=UTF-8
x-powered-by: PHP/7.0.33
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache
x-redirect-by: WordPress
set-cookie: PHPSESSID=9b476f35e469fc2c771d5caedfa8435d; path=/
set-cookie: pmpro_visit=1; path=/
location: https://example.com/
alt-svc: quic=":443"; ma=86400; v="43,39"

Screenshot from AWS console ALB Rules

Screen Shot 2019-11-13 at 1 32 12 pm

@stevenpall thanks for posting your working version! It helped me a ton in figuring this out.

@M00nF1sh I think it would be huge help to add an example hostname ingress configuration to the documentation for those looking to configure ssl-redirects. The hostname configuration is more tricky than the path based configuration because with hostnames both the SSL redirect and the service want to use path: "/*".

If you're into adding this to the docs, I can open a PR!

Unfortunately, loadbalancer which is created by this Ingress resource is not acceptable by AWS Security Hub. When I'm trying to apply ssl redirect to default rule (spec.backend), I'm getting following error in logs. @M00nF1sh

E1211 13:52:41.629511       1 controller.go:217] kubebuilder/controller "msg"="Reconciler error" "error"="failed to reconcile listeners due to failed to reconcile listener due to InvalidLoadBalancerAction: The redirect configuration is not valid because it creates a loop.\n\tstatus code: 400, request id: 65e65437-ec47-41c5-9231-798beeb212da"  "controller"="alb-ingress-controller" "request"={"Namespace":"default","Name":"app"}

As far as I understand, the loop can appear because of applying the same default rule to both listeners 80 and 443.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mgoodness picture mgoodness  路  5Comments

rootd00d picture rootd00d  路  4Comments

jchoi926 picture jchoi926  路  3Comments

joseppla picture joseppla  路  5Comments

rdubya16 picture rdubya16  路  4Comments