0

As I work on configuring my infrastructure with Terraform, I am currently attempting to create an ingress and apply Let's Encrypt to enable secure communication. However, despite my best efforts, I have encountered an error with the Nginx controller that is preventing me from successfully implementing the Let's Encrypt certificate. It's been frustrating trying to troubleshoot and resolve the issue, but I am determined to find a solution so that I can ensure secure communication for my infrastructure. With that in mind, I am reaching out to ask for your guidance on how to proceed and fix this issue.

W0318 02:10:06.465217 7 controller.go:1333] Error getting SSL certificate "project/cert-manager-private-key": local SSL certificate project/cert-manager-private-key was not found. Using default certificate
module "cert_manager" {
  source = "terraform-iaac/cert-manager/kubernetes"

  cluster_issuer_email                   = "dan.habot@gmail.com"
  cluster_issuer_name                    = "cert-manager-global"
  cluster_issuer_private_key_secret_name = "cert-manager-private-key"
  cluster_issuer_create = true

  # certificates = {
  #   main = {
  #     dns_names = ["api.project.io"]
  #     secret_name = "cert-manager-private-key"
  #   }
  # }

  create_namespace = false
  namespace_name   = kubernetes_namespace.project.metadata[0].name
}

resource "helm_release" "ingress-nginx" {
  repository = "https://kubernetes.github.io/ingress-nginx"
  chart      = "ingress-nginx"
  name       = "ingress-nginx"
  set {
    name  = "controller.publishService.enabled"
    value = true
  }
  set {
    name = "controller.admissionWebhooks.certManager.enabled"
    value = true
  }
  set {
    name = "controller.scope.namespace"
    value = kubernetes_namespace.project.metadata[0].name
  }
  set {
    name = "controller.tcp.configMapNamespace"
    value = kubernetes_namespace.project.metadata[0].name
  }
  set {
    name = "webhook.enabled"
    value = "true"
  }

  set {
    name = "rbac.create"
    value = "true"
  }

  set {
    name = "webhook.enabled"
    value = "true"
  }

  set {
    name = "ingressShim.defaultIssuerKind"
    value = "ClusterIssuer"
  }

  set {
    name = "ingressShim.defaultIssuerName"
    value = module.cert_manager.cluster_issuer_name
  }
}

resource "kubernetes_ingress_v1" "nginx" {
  metadata {
    name      = "nginx"
    namespace = kubernetes_namespace.project.metadata[0].name
    labels = {
      "ingress" = "entrypoint"
      "app.kubernetes.io/name" = "ingress-nginx"
      "app.kubernetes.io/part-of" = "project"

    }
    annotations = {
      "kubernetes.io/ingress.class" = "nginx"
      "cert-manager.io/cluster-issuer" = module.cert_manager.cluster_issuer_private_key_name
    }
  }

  spec {
    tls {
      hosts       = ["api.project.io"]
      secret_name = module.cert_manager.cluster_issuer_private_key_name
    }

    ingress_class_name = "nginx2"

    rule {
      host = "api.project.io"

      http {

        path {
          path = "/alerts"
          backend {
            service {
              name = kubernetes_service.alerts_service.metadata[0].name
              port {
                name = kubernetes_service.alerts_service.spec[0].port[0].name
              }
            }
            # service {
            #   name = kubernetes_service.entrypoint.metadata[0].name
            #   port {
            #     name = "http"
            #   }
            # }
          }
        }
        path {
          path = "/loader"
          backend {
            service {
              name = kubernetes_service.httploader_service.metadata[0].name
              port {
                name = kubernetes_service.httploader_service.spec[0].port[0].name
              }
            }
            # service {
            #   name = kubernetes_service.entrypoint.metadata[0].name
            #   port {
            #     name = "http"
            #   }
            # }
          }
        }
      }
    }
  }
}

module "nginx-ingress-controller" {
  source = "github.com/danhab99/terraform-kubernetes-nginx-ingress-controller"
  # however recommended way is to add this repository as a submodule
  tls_secret_name = module.cert_manager.cluster_issuer_private_key_name


  namespace = kubernetes_namespace.project.metadata[0].name
  # optional
  tcp_services = {
    "loader" = {
      namespace      = kubernetes_namespace.project.metadata[0].name
      service_name   = kubernetes_service.httploader_service.metadata[0].name
      container_port = local.alerts_port
      ingress_port   = kubernetes_service.httploader_service.spec[0].port[0].port
    },
    "alerts" = {
      namespace      = kubernetes_namespace.project.metadata[0].name
      service_name   = kubernetes_service.alerts_service.metadata[0].name
      container_port = local.httploader_port
      ingress_port   = kubernetes_service.alerts_service.spec[0].port[0].port
    },
  }
  # lb_annotations = {
  #   "service.beta.kubernetes.io/aws-load-balancer-type" = "nlb"
  #   "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": 360
  #   "service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags": "environment=test,name=kubernetes-ingress"
  # }
}

Right now ingress is using self signed certificates, I'm not sure where this is happening but I want it to use the letsencrypt private key that's stored in the secret.

Dan
  • 179
  • 1
  • 1
  • 13

1 Answers1

2

looks like not able to request the certificate and due to that it's using the default self singed cert. that one will get overwritten once cert manager get cert in same secret that you have mapped to ingress.

However i also noticed one mistake try changing it and give it try plus make sure if you are terminating & requesting there is also limit to request cert from let's cert might get block for week.

resource "kubernetes_ingress_v1" "nginx" {
  metadata {
    name      = "nginx"
    namespace = kubernetes_namespace.project.metadata[0].name
    labels = {
      "ingress" = "entrypoint"
      "app.kubernetes.io/name" = "ingress-nginx"
      "app.kubernetes.io/part-of" = "project"

    }
    annotations = {
      "kubernetes.io/ingress.class" = "nginx"
      "cert-manager.io/cluster-issuer" = module.cert_manager.cluster_issuer_name
    }
  }

value will be : cluster_issuer_name = "cert-manager-global"

update this line in above block : "cert-manager.io/cluster-issuer" = module.cert_manager.cluster_issuer_name

cluster_issuer_private_key_name is secret name which will store your cert.

You can refer to my answer for fields ref : https://stackoverflow.com/a/67178626/5525824

Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102
  • This didn't help. According to some logs I found, the nginx controller that the certmanager module creates is underpowered. I can't even imagine how to fix that. – Dan Mar 20 '23 at 01:54
  • thanks for sharing the details, if you can't share logs or details no will be able to help much thn. – Harsh Manvar Mar 20 '23 at 04:15