Home > Net >  How to create AWS ALB using kubernetes_ingress terraform resource?
How to create AWS ALB using kubernetes_ingress terraform resource?

Time:11-26

I'm trying to deploy an Application Load Balancer to AWS using Terraform's kubernetes_ingress resource:

I'm using aws-load-balancer-controller which I've installed using helm_release resource to my cluster.

Now I'm trying to deploy a deployment with a service and ingress.

This is how my service looks like:

resource "kubernetes_service" "questo-server-service" {
  metadata {
    name      = "questo-server-service-${var.env}"
    namespace = kubernetes_namespace.app-namespace.metadata.0.name
  }
  spec {
    selector = {
      "app.kubernetes.io/name" = lookup(kubernetes_deployment.questo-server.metadata.0.labels, "app.kubernetes.io/name")
    }

    port {
      port        = 80
      target_port = 4000
    }
    type = "LoadBalancer"
  }
}

And this is how my ingress looks like:

resource "kubernetes_ingress" "questo-server-ingress" {
  wait_for_load_balancer = true
  metadata {
    name = "questo-server-ingress-${var.env}"
    namespace = kubernetes_namespace.app-namespace.metadata.0.name
    annotations = {
      "kubernetes.io/ingress.class" = "alb"
      "alb.ingress.kubernetes.io/target-type" = "instance"
    }
  }
  spec {
    rule {
      http {
        path {
          path = "/*"
          backend {
            service_name = kubernetes_service.questo-server-service.metadata.0.name
            service_port = 80
          }
        }
      }
    }
  }
}

The issue is that when I run terraform apply it creates a Classic Load Balancer instead of an Application Load Balancer.

I've tried changing service's type to NodePort but it didn't help.

I've also tried with adding more annotations to ingress like "alb.ingress.kubernetes.io/load-balancer-name" = "${name}" but then the it created two load balancers at once! One internal ALB and one internet facing CLB.

Any ideas how I can create an internet facing Application Load Balancer using this setup?

--- Update ----

I've noticed, that actually, the service is the Classic Load Balancer via which I can connect to my deployment.

Ingress creates an ALB, but it's prefixed with internal, so my questions here is, how to create an internet facing ALB?

Thanks!

CodePudding user response:

Try using the alb.ingress.kubernetes.io/scheme: internet-facing annotation.

You find a list of all available annotations here: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/

CodePudding user response:

Answering my own question, like most of the times :)

This is the proper setup, just in case someone come across it:

The service's type has to be NodePort:

resource "kubernetes_service" "questo-server-service" {
  metadata {
    name      = "questo-server-service-${var.env}"
    namespace = kubernetes_namespace.app-namespace.metadata.0.name
  }
  spec {
    selector = {
      "app.kubernetes.io/name" = lookup(kubernetes_deployment.questo-server.metadata.0.labels, "app.kubernetes.io/name")
    }

    port {
      port        = 80
      target_port = 4000
    }
    type = "NodePort"
  }
}

And ingress's annotation has to be set as follows: (you can ingnore load-balancer-name and healthcheck-pass as they are not relevant to the question:

resource "kubernetes_ingress" "questo-server-ingress" {
  wait_for_load_balancer = true
  metadata {
    name      = "questo-server-ingress-${var.env}"
    namespace = kubernetes_namespace.app-namespace.metadata.0.name
    annotations = {
      "kubernetes.io/ingress.class"                  = "alb"
      "alb.ingress.kubernetes.io/target-type"        = "ip"
      "alb.ingress.kubernetes.io/scheme"             = "internet-facing"
      "alb.ingress.kubernetes.io/load-balancer-name" = "questo-server-alb-${var.env}"
      "alb.ingress.kubernetes.io/healthcheck-path"   = "/health"
    }
  }

  spec {
    rule {
      http {
        path {
          path = "/*"
          backend {
            service_name = kubernetes_service.questo-server-service.metadata.0.name
            service_port = 80
          }
        }
      }
    }
  }
} 
  • Related