Terraform, используя счет со списком внутри списка переменных? - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь создать несколько учетных записей хранения и несколько контейнеров в каждой учетной записи. Мне нужно создать это как модуль, чтобы я мог использовать его снова. Я думаю об этом, создав переменную типа

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

. Я создал следующий код. Тем не менее, я думаю, что эта строка

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

дает мне ошибку. Я хочу l oop через массив storageaccount, получить контейнеры и назначить «длину» ключа контейнеров для «count» внутри «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.

Как я могу сделать sh это? Или есть способ получше?

Вот полный код.

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 голосов
/ 01 апреля 2020

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
0 голосов
/ 01 апреля 2020
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

Извините, не было возможности протестировать код, но я надеюсь, что это поможет.

...