如何使用 terraform 资源为 k8s (AKS) 颁发 letsencrypt 证书?

How to issue letsencrypt certificate for k8s (AKS) using terraform resources?

总结

我无法为我在 azure aks 上的 terraform kubernetes 集群颁发有效证书。域和证书已成功创建(证书是根据 crt.sh 创建的),但是证书未应用于我的域,我的浏览器报告 "Kubernetes Ingress Controller Fake Certificate" 为已应用的证书。

terraform 文件已从一组工作的 yaml 文件(可以很好地颁发证书)转换为我的最佳能力。查看我的地形代码 here.

更新!在最初的问题中,我也无法创建证书。这是通过使用 here 中的 "tls_cert_request" 资源修复的。更改包含在我下面更新的代码中。

这里有一些我已经检查过但发现不是问题的东西

以下是我目前正在调查的一些潜在错误来源。

如果有人有任何其他建议,我将不胜感激(因为这已经困扰我很长一段时间了)!

证书资源

provider "acme" {
  server_url = var.context.cert_server
}

resource "tls_private_key" "reg_private_key" {
  algorithm = "RSA"
}

resource "acme_registration" "reg" {
  account_key_pem = tls_private_key.reg_private_key.private_key_pem
  email_address = var.context.email
}

resource "tls_private_key" "cert_private_key" {
  algorithm = "RSA"
}

resource "tls_cert_request" "req" {
  key_algorithm   = "RSA"
  private_key_pem = tls_private_key.cert_private_key.private_key_pem
  dns_names       = [var.context.domain_address]

  subject {
    common_name = var.context.domain_address
  }
}

resource "acme_certificate" "certificate" {
  account_key_pem = acme_registration.reg.account_key_pem
  certificate_request_pem = tls_cert_request.req.cert_request_pem

  dns_challenge {
    provider = "azure"
    config = {
      AZURE_CLIENT_ID = var.context.client_id
      AZURE_CLIENT_SECRET = var.context.client_secret
      AZURE_SUBSCRIPTION_ID = var.context.azure_subscription_id
      AZURE_TENANT_ID = var.context.azure_tenant_id
      AZURE_RESOURCE_GROUP = var.context.azure_dns_rg
    }
  }
}

Pypiserver 入口资源

resource "kubernetes_ingress" "pypi" {
  metadata {
    name = "pypi"
    namespace = kubernetes_namespace.pypi.metadata[0].name

    annotations = {
      "kubernetes.io/ingress.class" = "inet"
      "kubernetes.io/tls-acme" = "true"
      "certmanager.k8s.io/cluster-issuer" = "letsencrypt-prod"
      "ingress.kubernetes.io/ssl-redirect" = "true"
    }
  }

  spec {
    tls {
      hosts = [var.domain_address]
    }
    rule {
      host = var.domain_address

      http {
        path {
          path = "/"

          backend {
            service_name = kubernetes_service.pypi.metadata[0].name
            service_port = "http"
          }
        }
      }
    }
  }
}

如果需要更多信息,请告诉我,我会根据缺少的内容更新我的问题文本。最后,我会让 terraform 代码 git 回购保持不变并为其他人提供帮助。

我的问题的答案是我必须在我的集群中包含一个证书管理器,据我所知,没有本地 terraform 资源可以创建它。我最终使用 Helm 作为我的入口和证书管理器。

设置最终比我最初想象的要复杂一些,现在需要 运行 两次。这是因为 kubeconfig 没有被更新(必须在 运行ning "terraform apply" 之前应用 "set KUBECONFIG=.kubeconfig" 第二次)。所以它并不漂亮,但它 "works" 作为启动部署和 运行ning 的最小示例。

确实有一些方法可以使用本机 terraform 资源简化 pypi 部署部分,并且可能有一个简单的修复 kubeconfig 未更新的方法。但我还没有时间进一步调查。

如果有人有关于 k8s 集群更优雅、更实用和(可能是最重要的)安全的最小 terraform 设置的提示,我很乐意听到!

无论如何,对于那些感兴趣的人,可以找到生成的 terraform 代码here