如何将值从 terraform 传递到 Helm 图表 value.yaml 文件?

问题描述 投票:0回答:1

我正在使用 Terraform 中的 Helm 图表创建 ingress-nginx 控制器。我确实有一个values.yaml 文件,可以在其中添加自定义信息,但我需要从 Terraform 资源传递 SSL 证书值,那么我该怎么做呢?我正在使用下面的代码,但出现错误。

resource "aws_acm_certificate" "ui_cert" {
  domain_name       = var.DOMAIN_NAME
  validation_method = "DNS"

  tags = {
    Environment = var.ENVIRONMENT 
  }

  lifecycle {
    create_before_destroy = true
  }

}

resource "helm_release" "nginix_ingress" {

  depends_on = [module.eks, kubernetes_namespace.nginix_ingress,aws_acm_certificate.ui_cert]

  name       = "ingress-nginx"
  repository = "https://kubernetes.github.io/ingress-nginx"
  chart      = "ingress-nginx"
  namespace  = var.NGINX_INGRESS_NAMESPACE
   
  values = [templatefile("values.yaml", {
    controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
  })]
}

我收到以下错误:

 Error: Reference to undeclared resource
│
│   on ui.tf line 27, in resource "helm_release" "nginix_ingress":
│   27:     controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
│
│ A managed resource "controller" "service" has not been declared in the root
│ module.
╵
╷
│ Error: Invalid reference
│
│   on ui.tf line 27, in resource "helm_release" "nginix_ingress":
│   27:     controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
│
│ A reference to a resource type must be followed by at least one attribute
│ access, specifying the resource name.
╵
╷
│ Error: Unsupported attribute
│
│   on ui.tf line 27, in resource "helm_release" "nginix_ingress":
│   27:     controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
│
│ This object has no argument, nested block, or exported attribute named
│ "name".
╵
╷
│ Error: Reference to undeclared resource
│
│   on ui.tf line 27, in resource "helm_release" "nginix_ingress":
│   27:     controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
│
│ A managed resource "controller" "service" has not been declared in the root
│ module.
╵
╷
│ Error: Invalid reference
│
│   on ui.tf line 27, in resource "helm_release" "nginix_ingress":
│   27:     controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
│
│ A reference to a resource type must be followed by at least one attribute
│ access, specifying the resource name.
╵
╷
│ Error: Unsupported attribute
│
│   on ui.tf line 27, in resource "helm_release" "nginix_ingress":
│   27:     controller.service.beta.kubernetes.io/aws-load-balancer-internal = aws_acm_certificate.ui_cert.name,
│
│ This object has no argument, nested block, or exported attribute named
│ "name".
controller:
  name: controller
  image:
    chroot: false
    registry: registry.k8s.io
    image: ingress-nginx/controller
    tag: "v1.3.0"
    digest: sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5
    digestChroot: sha256:0fcb91216a22aae43b374fc2e6a03b8afe9e8c78cbf07a09d75636dc4ea3c191
    pullPolicy: IfNotPresent
    runAsUser: 101
    allowPrivilegeEscalation: true
  containerName: controller
  containerPort:
    # http: 80
    https: 443
  config:
    use-proxy-protocol: "true"
  # -- Optionally customize the pod hostname.
  hostname: {}

  # -- Process IngressClass per name (additionally as per spec.controller).
  ingressClassByName: false

  # -- This configuration defines if Ingress Controller should allow users to set
  # their own *-snippet annotations, otherwise this is forbidden / dropped
  # when users add those annotations.
  # Global snippets in ConfigMap are still respected
  allowSnippetAnnotations: true

  ## This section refers to the creation of the IngressClass resource
  ## IngressClass resources are supported since k8s >= 1.18 and required since k8s >= 1.19
  ingressClassResource:
    # -- Name of the ingressClass
    name: nginx
    # -- Is this ingressClass enabled or not
    enabled: true
    # -- Is this the default ingressClass for the cluster
    default: false
    # -- Controller-value of the controller that is processing this ingressClass
    controllerValue: "k8s.io/ingress-nginx"

    # -- Parameters is a link to a custom resource containing additional
    # configuration for the controller. This is optional if the controller
    # does not require extra parameters.
    parameters: {}

  # -- For backwards compatibility with ingress.class annotation, use ingressClass.
  # Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation
  ingressClass: nginx

  # -- Labels to add to the pod container metadata
  podLabels: {}
  #  key: value

  # -- Security Context policies for controller pods

  # -- Allows customization of the source of the IP address or FQDN to report
  # in the ingress status field. By default, it reads the information provided
  # by the service. If disable, the status field reports the IP address of the
  # node or nodes where an ingress controller pod is running.
  publishService:
    # -- Enable 'publishService' or not
    enabled: true
    # -- Allows overriding of the publish service to bind to
    # Must be <namespace>/<service_name>
    pathOverride: ""

  tcp:
    # -- Allows customization of the tcp-services-configmap; defaults to $(POD_NAMESPACE)
    configMapNamespace: ""
    # -- Annotations to be added to the tcp config configmap
    annotations: {}

  udp:
    # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE)
    configMapNamespace: ""
    # -- Annotations to be added to the udp config configmap
    annotations: {}

  # -- Use a `DaemonSet` or `Deployment`
  kind: Deployment

  # -- Annotations to be added to the controller Deployment or DaemonSet
  ##
  annotations: {}
  #  keel.sh/pollSchedule: "@every 60m"

  # -- Labels to be added to the controller Deployment or DaemonSet and other resources that do not have option to specify labels
  ##
  labels: {}
  #  keel.sh/policy: patch
  #  keel.sh/trigger: poll


  # -- The update strategy to apply to the Deployment or DaemonSet
  ##
  updateStrategy: {}
  #  rollingUpdate:
  #    maxUnavailable: 1
  #  type: RollingUpdate

  # -- `minReadySeconds` to avoid killing pods before we are ready
  ##
  minReadySeconds: 0



  # -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in.
  ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
  ##
  topologySpreadConstraints: []
    # - maxSkew: 1
    #   topologyKey: topology.kubernetes.io/zone
    #   whenUnsatisfiable: DoNotSchedule
    #   labelSelector:
    #     matchLabels:
    #       app.kubernetes.io/instance: ingress-nginx-internal

  # -- `terminationGracePeriodSeconds` to avoid killing pods before we are ready
  ## wait up to five minutes for the drain of connections
  ##
  terminationGracePeriodSeconds: 300

  # -- Node labels for controller pod assignment
  ## Ref: https://kubernetes.io/docs/user-guide/node-selection/
  ##
  nodeSelector:
    kubernetes.io/os: linux

  ## Liveness and readiness probe values
  ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
  ##
  ## startupProbe:
  ##   httpGet:
  ##     # should match container.healthCheckPath
  ##     path: "/healthz"
  ##     port: 10254
  ##     scheme: HTTP
  ##   initialDelaySeconds: 5
  ##   periodSeconds: 5
  ##   timeoutSeconds: 2
  ##   successThreshold: 1
  ##   failureThreshold: 5
  livenessProbe:
    httpGet:
      # should match container.healthCheckPath
      path: "/healthz"
      port: 10254
      scheme: HTTP
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 5
  readinessProbe:
    httpGet:
      # should match container.healthCheckPath
      path: "/healthz"
      port: 10254
      scheme: HTTP
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 3


  # -- Path of the health check endpoint. All requests received on the port defined by
  # the healthz-port parameter are forwarded internally to this path.
  healthCheckPath: "/healthz"

  # -- Address to bind the health check endpoint.
  # It is better to set this option to the internal node address
  # if the ingress nginx controller is running in the `hostNetwork: true` mode.
  healthCheckHost: ""

  # -- Annotations to be added to controller pods
  ##
  podAnnotations: {}

  replicaCount: 1

  minAvailable: 1

  ## Define requests resources to avoid probe issues due to CPU utilization in busy nodes
  ## ref: https://github.com/kubernetes/ingress-nginx/issues/4735#issuecomment-551204903
  ## Ideally, there should be no limits.
  ## https://engineering.indeedblog.com/blog/2019/12/cpu-throttling-regression-fix/
  resources:
  ##  limits:
  ##    cpu: 100m
  ##    memory: 90Mi
    requests:
      cpu: 100m
      memory: 90Mi

  # Mutually exclusive with keda autoscaling
  autoscaling:
    enabled: false
    minReplicas: 1
    maxReplicas: 11
    targetCPUUtilizationPercentage: 50
    targetMemoryUtilizationPercentage: 50
    behavior: {}
      # scaleDown:
      #   stabilizationWindowSeconds: 300
      #  policies:
      #   - type: Pods
      #     value: 1
      #     periodSeconds: 180
      # scaleUp:
      #   stabilizationWindowSeconds: 300
      #   policies:
      #   - type: Pods
      #     value: 2
      #     periodSeconds: 60

  autoscalingTemplate: []
  # Custom or additional autoscaling metrics
  # ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-custom-metrics
  # - type: Pods
  #   pods:
  #     metric:
  #       name: nginx_ingress_controller_nginx_process_requests_total
  #     target:
  #       type: AverageValue
  #       averageValue: 10000m

  # Mutually exclusive with hpa autoscaling
  keda:
    apiVersion: "keda.sh/v1alpha1"
    ## apiVersion changes with keda 1.x vs 2.x
    ## 2.x = keda.sh/v1alpha1
    ## 1.x = keda.k8s.io/v1alpha1
    enabled: false
    minReplicas: 1
    maxReplicas: 11
    pollingInterval: 30
    cooldownPeriod: 300
    restoreToOriginalReplicaCount: false
    scaledObject:
      annotations: {}
      # Custom annotations for ScaledObject resource
      #  annotations:
      # key: value
    triggers: []
 #     - type: prometheus
 #       metadata:
 #         serverAddress: http://<prometheus-host>:9090
 #         metricName: http_requests_total
 #         threshold: '100'
 #         query: sum(rate(http_requests_total{deployment="my-deployment"}[2m]))

    behavior: {}
 #     scaleDown:
 #       stabilizationWindowSeconds: 300
 #       policies:
 #       - type: Pods
 #         value: 1
 #         periodSeconds: 180
 #     scaleUp:
 #       stabilizationWindowSeconds: 300
 #       policies:
 #       - type: Pods
 #         value: 2
 #         periodSeconds: 60

  # -- Enable mimalloc as a drop-in replacement for malloc.
  ## ref: https://github.com/microsoft/mimalloc
  ##
  enableMimalloc: true

  ## Override NGINX template
  customTemplate:
    configMapName: ""
    configMapKey: ""

  service:
    enabled: true
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
      service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "ssl-cert"
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"

有人可以告诉我如何让它发挥作用吗?

amazon-web-services terraform kubernetes-helm terraform-provider-helm
1个回答
5
投票

templatefile
内置函数用于将值传递给模板文件中定义的变量。例如,在您的情况下,您可以在模板文件中定义一个变量,例如
ssl_cert
。然后,当调用
templatefile
函数时,您将向其传递 ACM 资源提供的值:

  values = [templatefile("values.yaml", {
    ssl_cert = aws_acm_certificate.ui_cert.name
  })]

ssl_cert
内部的
templatefile
变量将与注释
controller.service.beta.kubernetes.io/aws-load-balancer-ssl-cert
相关联。根据 YML 文件,应在文件的最后部分添加变量:

  service:
    enabled: true
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
      service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "${ssl_cert}" # here is where the replacement will be made
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"

templatefile
函数确实很强大,但我强烈建议在使用它时了解变量和变量替换的工作原理[1]。除非您在调用函数时和模板文件中都有占位符变量,否则它不会知道您想要进行的替换。


[1] https://www.terraform.io/language/functions/templatefile

© www.soinside.com 2019 - 2024. All rights reserved.