Home > front end >  2 different ways of doing terraform dynamic statement, what's the difference
2 different ways of doing terraform dynamic statement, what's the difference

Time:05-27

I have come across 2 terraform dynamic syntax, just wondering what's the difference?

dynamic "storage_account" {
    for_each = var.storage_account == null ? {} : var.storage_account
    content {
      name         = storage_account.value.name
      type         = storage_account.value.type
      account_name = storage_account.value.account_name
      share_name   = storage_account.value.share_name
      access_key   = storage_account.value.access_key
      mount_path   = storage_account.value.mount_path
    }
  }

dynamic "backup" {
    for_each = var.app_service_backup != null ? [1] : []
    content {
      name                = var.app_service_backup.name
      enabled             = true
      storage_account_url = var.app_service_backup.storage_account_url
      schedule {
        frequency_interval = var.app_service_backup.frequency_interval
        frequency_unit     = var.app_service_backup.frequency_unit
      }
    }
  }

and variable is

variable "storage_account" {
  description = <<EOF
  (Optional) - One or more storage_account blocks as defined below.

  (Required) name - The name of the storage account identifier.
  (Required) type - The type of storage. Possible values are AzureBlob and AzureFiles.
  (Required) account_name - The name of the storage account.
  (Required) share_name - The name of the file share (container name, for Blob storage).
  (Required) access_key - The access key for the storage account.
  (Required) mount_path - The path to mount the storage within the site's runtime environment.
  EOF
  type = map(object({
    name         = string
    type         = string
    account_name = string
    share_name   = string
    access_key   = string
    mount_path   = string
  }))

  default = null
}


variable "app_service_backup" {
  description = <<EOF
    (Optional) - The app service backup block supports the following:

    (Required) name - Specifies the name for this Backup.
    (Required) storage_account_url - The SAS URL to a Storage Container where Backups should be saved.
    (Required) frequency_interval - Sets how often the backup should be executed.
    (Required) frequency_unit - Sets the unit of time for how often the backup should be executed. Possible values are Day or Hour.
  EOF

  type = object({
    name                = string
    storage_account_url = string
    frequency_interval  = number
    frequency_unit      = string

  })

  default = null
}

notice how the first dynamic storage_account it's using things like storage_account.value.name and second "backup" is using var.app_service_backup.name

for the second one, can I use backup.value.name?

CodePudding user response:

When you have Conditional Expression in TF such as

condition ? true_val : false_val

true_val and false_val must be of same type.

So in your first example:

for_each = var.storage_account == null ? {} : var.storage_account

var.storage_account is map, so the true_val must also be a map. In this case its an empty map {}. Since this map does not have any elements, for_each will not run.

In your second example maps could also be used, but lists are shorter to write, so you have (just a convention):

 for_each = var.app_service_backup != null ? [1] : []

where [] is an empty list, and [1] is a list with one element. So for_each will run only once. The value of the element in the list [1] is 1, but it really does not matter. It can be any value, as long as length of the list is not zero.

UPDATE.

You can't use backup.value.name in the second example, because in that case backup.value is literally 1 as its the value from [1]. Also it does not make sense to forcibly change your for_each to use var.app_service_backup, as its just a single value. There is no iteration needed for it. So you just access it directly.

  • Related