通过 Terraform Helm provider 和 Azure DevOps 部署 Helm charts,同时从 ACR 获取 Helm charts。

4

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

Helm提供程序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"
}

错误: Error: 看起来 "" 不是一个有效的图表库或无法访问:获取 /index.yaml 失败 : 404 Not Found


1
乍一看,我会说 data.helm_repository.cluster_rbac_helm_chart_repo.metadata[0].name 应该是 data.helm_repository.cluster_rbac_helm_chart_repo.metadata.0.name 但不确定百分之百。如果您能展示完整的错误信息而不仅仅是当前问题中的摘录,那将非常有用。 - ydaetskcoR
3个回答

5
目前为止,Helm仍不支持直接从OCI注册表安装Chart。
推荐的步骤如下:
  1. helm chart remove mycontainerregistry.azurecr.io/helm/hello-world:v1
  2. helm chart pull mycontainerregistry.azurecr.io/helm/hello-world:v1
  3. helm chart export mycontainerregistry.azurecr.io/helm/hello-world:v1 --destination ./install
  4. 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]
}

不是完美的,但可以工作。


注意:Terraform Helm提供程序> = [v2.5.0](https://github.com/hashicorp/terraform-provider-helm/releases/tag/v2.5.0)现在支持OCI注册表。 - Mr-DC

3
问题在于你在Terraform helm_repository中使用了错误的url。ACR的正确url看起来是这样的:
https://acrName.azurecr.io/helm/v1/repo

ACR 是一个私有的登记表,这意味着您需要添加用户名和密码。最后,您的 Terraform 代码应该像这样,使用 helm provider 的 2.0+ 版本:

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: 看起来 "***/helm/v1/repo" 不是有效的图表存储库或无法访问:无法获取 ***/helm/v1/repo/index.yaml : 401 Unauthorized 在我的情况下,我无法直接在terraform文件中提供用户名和密码,因为我正在通过Azure DevOps管道使用服务主体,所以是否有任何方法可以从管道传递用户名和密码到tf文件中,而不是将其写入文件中? - user3616775
@user3616775 你仔细阅读了答案吗?我说过你需要添加你的ACR的用户名和密码。 - Charles Xu
是的,我看过了,但我不能直接通过它。 - 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
@user3616775,你在Terraform中设置了ACR的凭据吗?这不是SP凭据,而是ACR的凭据。 - Charles Xu
@user3616775 你解决了这个问题吗?如果答案对你有用,请接受它。 - Charles Xu
显示剩余7条评论

0

对上述解决方案进行小改进。包括一个触发器,每次都强制下载图表。否则,它期望您在第一次部署后始终保留图表的本地副本。

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
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接