带有 Terraform 的 Azure 容器实例 - 多个机密卷

Azure Container Instance with Terraform - multiple secrets volumes

我有以下 Terraform 代码来从一些 json 变量部署 Azure 容器实例:

resource "azurerm_container_group" "aci" {
  count               = length(var.ContainerInstances)
  name                = var.ContainerInstances[count.index].Name
  resource_group_name = var.ContainerInstances[count.index].ResourceGroup
  location            = var.ContainerInstances[count.index].Location
  dns_name_label      = var.ContainerInstances[count.index].DnsNameLabel
  os_type             = var.ContainerInstances[count.index].OsType
  tags                = merge(var.workspace_tags, var.ContainerInstances[count.index].Tags)
  ip_address_type     = var.ContainerInstances[count.index].IpAddressType

  dynamic "container" {

    for_each = [for k, v in var.ContainerInstances[count.index].Containers :
      {
        name     = lookup(v, "Name", "")
        image    = lookup(v, "Image", "")
        cpu      = lookup(v, "Cpu", "")
        memory   = lookup(v, "Memory", "")
        port     = lookup(v, "Port", "")
        protocol = lookup(v, "Protocol", "")

        environmentvariables         = lookup(v, "EnvironmentVariables", "")
        secure_environment_variables = lookup(v, "SecureEnvironmentVariables", "")
        volumes                      = lookup(v, "Volumes", {})
      }
    ]

    content {
      name   = container.value.name
      image  = container.value.image
      cpu    = container.value.cpu
      memory = container.value.memory

      ports {
        port     = container.value.port
        protocol = container.value.protocol
      }

      environment_variables        = container.value.environmentvariables
      secure_environment_variables = container.value.secure_environment_variables

      dynamic "volume" {

          for_each = [for x in container.value.volumes :
            {
              name      = lookup(x, "Name", "")
              mountpath = lookup(x, "MountPath", "")
              readonly  = lookup(x, "ReadOnly", "")
              secrets   = { for key, value in lookup(x, "Secrets", {}) : value => base64encode(value) }
            }
          ]

          content {
            name       = volume.value.name
            mount_path = volume.value.mountpath
            read_only  = volume.value.readonly

            secret = volume.value.secrets
          }
      }
    }
  }
}

基本上,我需要在每个 ACI 中添加多个包含机密的卷。每个卷的秘密和挂载点都略有不同,所以我认为我不能将所有值都放在一个卷中。

这是一个完整的例子:https://github.com/ossentoo/terraform-aci-volumes/blob/main/aci.tf

问题是,当我 运行 这个带有 terraform 的示例代码应用时,它 运行 无休止地并且没有完成。如果我在 运行 大约 5 分钟后转到 Azure 门户,我会看到 ACI 已经创建,但它是不健康的。因此,我的配置似乎有问题。你能看出它有什么问题吗?

当我通过首先注释掉配置的动态卷部分来尝试 运行 这个示例时,确实创建了 aci。所以我很确定问题出在动态代码上。

我在我的环境中尝试了同样的方法,使用变量,我也遇到了同样的问题,但硬编码成功了。

问题出在您正在使用的 For_each secrets argument动态音量:

secrets = { for key, value in lookup(x, "Secrets", {}) : value => base64encode(value) }

而不是上面秘密中的 value 你必须使用 key 如下:

secrets = { for key, value in lookup(x, "Secrets", {}) : key => base64encode(value).

编辑后的测试代码(来自您分享的GitHub示例):

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "aci-rg" {
  name     = var.ContainerInstances.ResourceGroup
  location = var.ContainerInstances.Location
}

resource "azurerm_container_group" "aci" {
  name                = var.ContainerInstances.Name
  resource_group_name = var.ContainerInstances.ResourceGroup
  location            = var.ContainerInstances.Location
  dns_name_label      = var.ContainerInstances.DnsNameLabel
  os_type             = var.ContainerInstances.OsType
  ip_address_type     = var.ContainerInstances.IpAddressType

  container {

    name   = var.ContainerInstances.Container.Name
    image  = var.ContainerInstances.Container.Image
    cpu    = var.ContainerInstances.Container.Cpu
    memory = var.ContainerInstances.Container.Memory

    environment_variables        = var.ContainerInstances.Container.EnvironmentVariables
    secure_environment_variables = var.ContainerInstances.Container.SecureEnvironmentVariables

    ports {
      port     = var.ContainerInstances.Container.Port
      protocol = var.ContainerInstances.Container.Protocol
    }

    dynamic "volume" {

      for_each = [for x in var.ContainerInstances.Container.Volumes :
        {
          name      = lookup(x, "Name", "")
          mountpath = lookup(x, "MountPath", "")
          readonly  = lookup(x, "ReadOnly", "")
          secrets   = { for key, value in lookup(x, "Secrets", {}) : key => base64encode(value) }
        }
      ]

      content {
        name       = volume.value.name
        mount_path = volume.value.mountpath
        read_only  = volume.value.readonly
        secret = volume.value.secrets
      }
    }
  }
  depends_on = [
    azurerm_resource_group.aci-rg
  ]
}

输出: