通过 Terraform Helm 提供程序和 Azure DevOps 部署 helm 图表,同时从 ACR 获取 helm 图表

Posted

技术标签:

【中文标题】通过 Terraform Helm 提供程序和 Azure DevOps 部署 helm 图表,同时从 ACR 获取 helm 图表【英文标题】:Deploying helm charts via Terraform Helm provider and Azure DevOps while fetching the helm charts from ACR 【发布时间】:2020-04-21 05:51:09 【问题描述】:

我正在尝试使用 Terraform helm 提供程序和 Azure DevOps 容器作业将 helm 图表从 ACR 部署到 AKS 集群,但在从 ACR 获取 helm 图表时失败。请让我知道出了什么问题。

helm provider tf 模块:

data "helm_repository" "cluster_rbac_helm_chart_repo" 
  name = "mcp-rbac-cluster"
  url  = "https://mcpshareddcr.azurecr.io"

# Deploy Cluster RBAC helm chart onto the cluster
resource "helm_release" "cluster_rbac_helm_chart_release" 
  name  = "mcp-rbac-cluster"
  repository = data.helm_repository.cluster_rbac_helm_chart_repo.metadata[0].name
  chart = "mcp-rbac-cluster"

提供者:

  version                    = "=1.36.0"
  tenant_id                  = var.ARM_TENANT_ID
  subscription_id            = var.ARM_SUBSCRIPTION_ID
  client_id                  = var.ARM_CLIENT_ID
  client_secret              = var.ARM_CLIENT_SECRET
  skip_provider_registration = true


data "azurerm_kubernetes_cluster" "aks_cluster" 
  name                = var.aks_cluster
  resource_group_name = var.resource_group_aks


locals 
  kubeconfig_path = "/tmp/kubeconfig"


resource "local_file" "kubeconfig" 
  filename = local.kubeconfig_path
  content  = data.azurerm_kubernetes_cluster.aks_cluster.kube_admin_config_raw


provider "helm" 
  home = "resources/.helm"
  kubernetes 
    load_config_file = true
    config_path = local.kubeconfig_path
  


module "aks_resources" 
  source = "./modules/helm/aks-resources"

错误: 错误:看起来“”不是有效的图表存储库或无法访问:无法获取 /index.yaml : 404 Not Found

【问题讨论】:

乍一看,我会说data.helm_repository.cluster_rbac_helm_chart_repo.metadata[0].name 应该是data.helm_repository.cluster_rbac_helm_chart_repo.metadata.0.name,但不是100% 确定。如果您可以同时显示您得到的完整错误而不是当前问题中的摘录,那将会很有用。 【参考方案1】:

到目前为止,Helm 仍然不支持直接从 OCI 注册表安装图表。

推荐的步骤是:

    helm chart remove mycontainerregistry.azurecr.io/helm/hello-world:v1 helm chart pull mycontainerregistry.azurecr.io/helm/hello-world:v1 helm chart export mycontainerregistry.azurecr.io/helm/hello-world:v1 --destination ./install cd install & helm install myhelmtest ./hello-world

所以我的解决方案是:

resource "null_resource" "download_chart" 
  provisioner "local-exec" 
    command = <<-EOT
      export HELM_EXPERIMENTAL_OCI=1
      helm registry login mycontainerregistry.azurecr.io --username someuser --password somepass
      helm chart remove mycontainerregistry.azurecr.io/helm/hello-world:v1
      helm chart pull mycontainerregistry.azurecr.io/helm/hello-world:v1
      helm chart export mycontainerregistry.azurecr.io/helm/hello-world:v1 --destination ./install
    EOT
  


resource "helm_release" "chart" 
  name             = "hello_world"
  repository       = "./install"
  chart            = "hello-world"
  version          = "v1"

  depends_on = [null_resource.download_chart]

不完美但有效。

【讨论】:

【参考方案2】:

问题是您在 Terraform helm_repository 中使用了错误的 url。 ACR 的右 url 如下所示:

https://acrName.azurecr.io/helm/v1/repo

而且 ACR 是一个私有注册表,因此这意味着您需要为其添加用户名和密码。最后,您的 Terraform 代码应该与 2.0+ 版本的 helm provider 一样:

resource "helm_release" "my-chart" 
  name  = "my-chart"
  chart = "my/chart"
  repository  = "https://$var.acr_name.azurecr.io/helm/v1/repo"
  repository_username = var.acr_user_name
  repository_password = var.acr_user_password

或使用 1.x helm 提供程序:

data "helm_repository" "cluster_rbac_helm_chart_repo" 
  name = "mcp-rbac-cluster"
  url  = "https://mcpshareddcr.azurecr.io/helm/v1/repo"

  username = "xxxxx"
  password = "xxxxx"


# Deploy Cluster RBAC helm chart onto the cluster
resource "helm_release" "cluster_rbac_helm_chart_release" 
  name  = "mcp-rbac-cluster"
  repository = data.helm_repository.cluster_rbac_helm_chart_repo.metadata[0].name
  chart = "mcp-rbac-cluster"

更新

这是运行良好并在 AKS 中部署图表的屏幕截图:

【讨论】:

感谢您的回复。我确实将 URL 放在上面,它到达了 ACR 并以 Error: Looks like "***/helm/v1/repo" is not a valid chart repository or cannot be reached: Failed to fetch ***/helm/v1/repo/index.yaml : 401 Unauthorized 失败在我的情况下,我无法直接在 terraform 文件中提供用户名和密码,因为我通过 azure devops 管道使用服务主体,所以存在任何意味着我可以将用户名和密码从管道传递到 tf 文件,而不是将其写入文件? @user3616775 你仔细阅读答案了吗?我说你需要添加你的 ACR 的用户名和密码。 是的,我读到了,但我不能直接传递它``` - bash: 'terraform init -input=false' env: TF_VAR_ARM_ACCESS_KEY: $(storage_access_key) TF_VAR_ARM_CLIENT_ID: $(AZURE_CLIENT_ID) TF_VAR_ARM_CLIENT_SECRET: $(AZURE_CLIENT_SECRET) TF_VAR_ARM_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) TF_VAR_ARM_TENANT_ID: $(AZURE_TENANT_ID) TF_LOG: DEBUG displayName: 'terraform init' ``` @user3616775 您是否在 Terraform 中设置了 ACR 的凭据?这不是 sp 凭证,而是 ACR。 @user3616775 你解决问题了吗?如果答案对您有用,请接受。【参考方案3】:

对上述解决方案的小幅增强。包括一个触发器以强制每次下载图表。否则,它希望您在第一次部署后始终维护图表的本地副本

resource "null_resource" "download_chart" 
  triggers = 
    always_run = timestamp()
  

  provisioner "local-exec" 
    command = <<-EOT
      export HELM_EXPERIMENTAL_OCI=1
      helm registry login $var.registry_fqdn --username $var.acr_client_id --password $var.acr_client_secret
      helm chart remove $var.registry_fqdn/helm/$var.chart_name:$var.chart_tag
      helm chart pull $var.registry_fqdn/helm/$var.chart_name:$var.chart_tag
      helm chart export $var.registry_fqdn/helm/$var.chart_name:$var.chart_tag --destination ./install
    EOT
  

【讨论】:

以上是关于通过 Terraform Helm 提供程序和 Azure DevOps 部署 helm 图表,同时从 ACR 获取 helm 图表的主要内容,如果未能解决你的问题,请参考以下文章

在 GKE 集群上使用 Terraform 部署 Helm 工作负载

使用 Helm 而不是 Terraform 的困惑

通过 helm / terraform 安装自定义 grafana 数据源

等待条件时terraform helm释放超时

卡在 Terraform 到 Kubernetes 的部分 helm 版本中

从 terraform helm_release 资源获取 redis 主机 url