首页 > 解决方案 > Terraform 在列表变量中使用带有列表的计数?

问题描述

我正在尝试在每个帐户中创建一些存储帐户和一些容器。我需要将它创建为一个模块,以便我可以重用它。我想这样做的方法是创建一个变量,例如

storageaccounts = [
    {
      name       = "testbackupstorage11"
      containers = ["logs", "web", "backups"]
    },
    {
      name       = "testbackupstorage12"
      containers = ["logs-1", "web-1"]
    }
  ]

我创建了以下代码。但是,我认为这条线

count                 = length(var.storageaccounts.*.containers)

给我错误。我想遍历 storageaccount 数组,获取容器并将容器键的“长度”分配给“azurerm_storage_container”内的“计数”,以便此块创建多个存储帐户。

但是,这并没有按预期工作,很可能是因为 * 我也测试过

count                 = length(var.storageaccounts[count.index].containers)

当我这样做时,我得到了错误

 on ..\modules\storage\main.tf line 21, in resource "azurerm_storage_container" "this":
  21:   count                 = length(var.storageaccounts[count.index].containers)

The "count" object can be used only in "resource" and "data" blocks, and only
when the "count" argument is set.

我怎样才能做到这一点?或者有没有更好的方法?

这是完整的代码。

resource "random_id" "this" {
  count = length(var.storageaccounts)
  keepers = {
    storagename = 1
  }

  byte_length = 6
  prefix      = var.storageaccounts[count.index].name
}

resource "azurerm_storage_account" "this" {
  count                    = length(var.storageaccounts)
  name                     = substr(lower(random_id.this[count.index].hex), 0, 24)
  resource_group_name      = var.resourcegroup
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "this" {
  count                 = length(var.storageaccounts.*.containers)
  name                  = var.storageaccounts[count.index].containers[count.index]
  storage_account_name  = azurerm_storage_account.this[count.index].name
  container_access_type = "private"
}

provider "random" {
  version = "2.2"
}
locals {
  storageaccounts = [
    {
      name       = "testbackupstorage11"
      containers = ["logs", "web", "backups"]
    },
    {
      name       = "testbackupstorage12"
      containers = ["logs-1", "web-1"]
    }
  ]

}

module "storage" {
  source          = "../modules/storage"
  resourcegroup   = "my-test"
  location        = "eastus"
  storageaccounts = local.storageaccounts

}

provider "azurerm" {
  version = "=2.0.0"
  features {}
}

//variable "prefix" {}
variable "location" {}
variable "resourcegroup" {}
variable "storageaccounts" {
  default = []
  type = list(object({
    name       = string
    containers = list(string)
  }))
}

标签: terraform

解决方案


count = length(var.storageaccounts.*.containers)将返回其长度var.storageaccounts为 2。

count = length(var.storageaccounts[count.index].containers)会失败,因为您无法引用尚未声明的内容。

您可以做的是展平列表。

例如:

变量.tf

variable "storageaccounts" {
  default = []
  type = list(object({
    name       = string
    containers = list(string)
  }))
}

主文件

resource "null_resource" "cluster" {
  count = length(flatten(var.storageaccounts.*.containers))
  provisioner "local-exec" {
    command = "echo ${flatten(var.storageaccounts.*.containers)[count.index]}"
  }
}

变量.tfvars

storageaccounts = [
    {
      name       = "testbackupstorage11"
      containers = ["logs", "web", "backups"]
    },
    {
      name       = "testbackupstorage12"
      containers = ["logs-1", "web-1"]
    }
  ]

计划

terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # null_resource.cluster[0] will be created
  + resource "null_resource" "cluster" {
      + id = (known after apply)
    }

  # null_resource.cluster[1] will be created
  + resource "null_resource" "cluster" {
      + id = (known after apply)
    }

  # null_resource.cluster[2] will be created
  + resource "null_resource" "cluster" {
      + id = (known after apply)
    }

  # null_resource.cluster[3] will be created
  + resource "null_resource" "cluster" {
      + id = (known after apply)
    }

  # null_resource.cluster[4] will be created
  + resource "null_resource" "cluster" {
      + id = (known after apply)
    }

Plan: 5 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

This plan was saved to: /path/plan

To perform exactly these actions, run the following command to apply:
    terraform apply "/path/plan"

应用程序

terraform apply  
/outputs/basics/plan
null_resource.cluster[1]: Creating...
null_resource.cluster[4]: Creating...
null_resource.cluster[3]: Creating...
null_resource.cluster[0]: Creating...
null_resource.cluster[2]: Creating...
null_resource.cluster[3]: Provisioning with 'local-exec'...
null_resource.cluster[1]: Provisioning with 'local-exec'...
null_resource.cluster[4]: Provisioning with 'local-exec'...
null_resource.cluster[0]: Provisioning with 'local-exec'...
null_resource.cluster[2]: Provisioning with 'local-exec'...
null_resource.cluster[3] (local-exec): Executing: ["/bin/sh" "-c" "echo logs-1"]
null_resource.cluster[2] (local-exec): Executing: ["/bin/sh" "-c" "echo backups"]
null_resource.cluster[4] (local-exec): Executing: ["/bin/sh" "-c" "echo web-1"]
null_resource.cluster[1] (local-exec): Executing: ["/bin/sh" "-c" "echo web"]
null_resource.cluster[0] (local-exec): Executing: ["/bin/sh" "-c" "echo logs"]
null_resource.cluster[2] (local-exec): backups
null_resource.cluster[2]: Creation complete after 0s [id=3936346761857660500]
null_resource.cluster[4] (local-exec): web-1
null_resource.cluster[3] (local-exec): logs-1
null_resource.cluster[0] (local-exec): logs
null_resource.cluster[1] (local-exec): web
null_resource.cluster[4]: Creation complete after 0s [id=3473332636300628727]
null_resource.cluster[3]: Creation complete after 0s [id=8036538301397331156]
null_resource.cluster[1]: Creation complete after 0s [id=8566902439147392295]
null_resource.cluster[0]: Creation complete after 0s [id=6115664408585418236]

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate

推荐阅读