在列表变量中使用带计数的Terraform?

时间:2020-04-01 02:22:03

标签: terraform

我正在尝试创建几个存储帐户,并在每个帐户中创建一些容器。我需要将其创建为模块,以便可以重复使用。我想做到这一点的方法是创建一个变量

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

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

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

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

但是,这不能按预期工作,很可能是因为* 我还用

进行了测试
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)
  }))
}

2 个答案:

答案 0 :(得分:0)

length(var.storageaccounts.*.containers)

您的计数没有意义,您要求提供带有属性容器的存储帐户列表。因此它将寻找

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

尝试使用本地人将所有内容合并为一个列表:

    locals{
        storageaccounts = [for x in var.storageaccounts: x.containers]
    } // Returns list of lists

然后

count = length(flatten(local.storageaccounts)) //all one big list

https://www.terraform.io/docs/configuration/functions/flatten.html

对不起,没有机会测试代码,但是我希望这会有所帮助。

答案 1 :(得分:0)

count = length(var.storageaccounts.*.containers)将返回var.storageaccounts的长度,即2。

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

您可以做的是将列表弄平。

例如:

variables.tf

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

main.tf

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

variables.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