# How to extract  form Terraform complex variable value??

Variable:

```plaintext
# Selection
variable "selections" {
  description = "A map of selction maps"
  type = map(object({
    name         = string
    plan_id      = optional(string)
    iam_role_arn = optional(string)
    selection_tags = optional(map(object({
      type  = string
      key   = string
      value = string
    })))
    condition = optional(map(object({
      string_equals = optional(map(object({
        key   = string
        value = string
      })))

      string_like = optional(map(object({
        key   = string
        value = string
      })))

      string_not_equals = optional(map(object({
        key   = string
        value = string
      })))

      string_not_like = optional(map(object({
        key   = string
        value = string
      })))
    })))
    
  }))
  default = {}
}
```

tfvars:

```plaintext
selections = {
  selection1 = {
    name          = "selection-1"
    resources     = ["arn:aws:dynamodb:ap-southeast-1:123456789101:table/mydynamodb-table1"]
    not_resources = []
    selection_tags = {
      1 = {
        type  = "STRINGEQUALS"
        key   = "Environment"
        value = "production"
      },
      2 = {
        type  = "STRINGEQUALS"
        key   = "Owner"
        value = "production"
      }
    }
  },
  selection2 = {
    name      = "selection-2"
    resources = ["arn:aws:dynamodb:ap-southeast-1:123456789101:table/mydynamodb-table2"]
  },
  selection3 = {
    name          = "selection-3"
    resources     = ["arn:aws:dynamodb:ap-southeast-1:123456789101:table/mydynamodb-table3"]
    not_resources = []
    condition = {
      string_equals = {
        1 = {
          key   = "aws:ResourceTag/Component"
          value = "rds"
        },
        2 = {
          key   = "aws:ResourceTag/Project"
          value = "Project1"
        },
      }
    }
  },
}
```

Xử lý:

```plaintext
resource "aws_backup_selection" "backup_selection" {
  # count = var.enable_backup ? length(local.selections) : 0
  for_each = local.selections

  iam_role_arn = var.backup_iam_role_arn != null ? var.backup_iam_role_arn : aws_iam_role.backup_role[0].arn
  name         = try(local.selections[each.key]["name"], null)
  plan_id      = aws_backup_plan.backup_plan[0].id

  resources     = try(local.selections[each.key]["resources"], null)
  not_resources = try(local.selections[each.key]["not_resources"], null)

  dynamic "selection_tag" {
    for_each = each.value.selection_tags != null ? each.value.selection_tags : {}
    content {
      type  = try(selection_tag.value["type"], null)
      key   = try(selection_tag.value["key"], null)
      value = try(selection_tag.value["value"], null)
    }
  }

  condition {
    dynamic "string_equals" {
      for_each = lookup(try(each.value.condition[each.key].value["string_equals"], {}), "string_equals", {})
      content {
        key   = try(string_equals.value["key"], null)
        value = lookup(string_equals.value["value"], null)
      }
    }
  }
}
```

Hiện tại đang bị lỗi chưa biết cách lấy giá trị khai báo để tạo ra condition string\_equals (Khi apply code như trên đang bị condition = {}

Nhờ anh chị em chỉ giúp ạ

\=> **Solution + chỉnh sửa:** Hiện tại code đã chạy khi làm như bên dưới.

**Cách troubleshooting + testing:** Em tạo ra 1 variable condition {} tách biệt riêng ra khỏi hẳn selections và test việc lấy các giá trị trên variable riêng đó, việc này sẽ giúp em tận dụng được terraform console dễ dàng hơn, vì không bị lẫn các giá trị, loop nhiều lần.

Sau khi lấy được thành công giá trị từ biến condition tách biệt, thì em đưa vào trong xử lý chung với selections. Nhận thấy rằng condition cùng level select với selection\_tags => có thể get block condition ra tương tự như selection\_tags block, việc xử lý thì chỉ cần copy từ cách xử lý variable condtion tách biệt là done!

Bài học rút ra là Terraform console là một feature rất nên sử dụng của Terraform, giúp thuận tiện cho việc troubleshooting.

```plaintext
variable "selections" {
  description = "A map of selction maps"
  type = map(object({
    name         = string
    plan_id      = optional(string)
    iam_role_arn = optional(string)
    selection_tags = optional(map(object({
      type  = string
      key   = string
      value = string
    })))
    condition = optional(object({
      string_equals = optional(map(object({
        key   = string
        value = string
      }))),
      string_like = optional(map(object({
        key   = string
        value = string
      }))),
      string_not_equals = optional(map(object({
        key   = string
        value = string
      }))),
      string_not_like = optional(map(object({
        key   = string
        value = string
      }))),
    }))
  }))
  default = {}
}
```

Khai báo tfvars:

```plaintext
selections = {
  selection1 = {
    name          = "selection-1"
    resources     = ["arn:aws:dynamodb:ap-southeast-1:123456789101:table/mydynamodb-table1"]
    not_resources = []
    selection_tags = {
      1 = {
        type  = "STRINGEQUALS"
        key   = "Environment"
        value = "production"
      },
      2 = {
        type  = "STRINGEQUALS"
        key   = "Owner"
        value = "production"
      }
    }
  },
  selection2 = {
    name      = "selection-2"
    resources = ["arn:aws:dynamodb:ap-southeast-1:123456789101:table/mydynamodb-table2"]
  },
  selection3 = {
    name          = "selection-3"
    resources     = ["arn:aws:dynamodb:ap-southeast-1:123456789101:table/mydynamodb-table3"]
    not_resources = []
    selection_tags = {
      1 = {
        type  = "STRINGEQUALS"
        key   = "Environment"
        value = "production"
      }
    }
    condition = {
      string_equals = {
        1 = {
          key   = "aws:ResourceTag/Component"
          value = "rds"
        },
        2 = {
          key   = "aws:ResourceTag/Project"
          value = "Project1"
        },
      }
      string_like = {
        1 = {
          key   = "aws:ResourceTag/Application"
          value = "app*"
        }
      }
      string_not_equals = {
        1 = {
          key   = "aws:ResourceTag/Backup"
          value = "false"
        },
      }
      string_not_like = {
        1 = {
          key   = "aws:ResourceTag/Environment"
          value = "test*"
        },
      }
    }
  },
}

tags = {
  Owner       = "devops"
  Environment = "production"
  Terraform   = true
}
```

Xử lý:

```plaintext
resource "aws_backup_selection" "backup_selection" {
  for_each = local.selections

  iam_role_arn = var.backup_iam_role_arn != null ? var.backup_iam_role_arn : aws_iam_role.backup_role[0].arn
  name         = try(local.selections[each.key]["name"], null)
  plan_id      = aws_backup_plan.backup_plan[0].id

  resources     = try(local.selections[each.key]["resources"], null)
  not_resources = try(local.selections[each.key]["not_resources"], null)

  dynamic "selection_tag" {
    for_each = each.value.selection_tags != null ? each.value.selection_tags : {}
    content {
      type  = try(selection_tag.value["type"], null)
      key   = try(selection_tag.value["key"], null)
      value = try(selection_tag.value["value"], null)
    }
  }

  dynamic "condition" {
    for_each = each.value.condition != null ? each.value.condition : {}
    content {
      dynamic "string_equals" {
        #for_each = var.selection_conditions["string_equals"] != null ? var.selection_conditions["string_equals"] : {}
        for_each = each.value.condition["string_equals"] != null ? each.value.condition["string_equals"] : {}
        content {
          key   = try(string_equals.value["key"], null)
          value = try(string_equals.value["value"], null)
        }
      }
      dynamic "string_like" {
        for_each = each.value.condition["string_like"] != null ? each.value.condition["string_like"] : {}
        content {
          key   = try(string_like.value["key"], null)
          value = try(string_like.value["value"], null)
        }
      }
      dynamic "string_not_equals" {
        for_each = each.value.condition["string_not_equals"] != null ? each.value.condition["string_not_equals"] : {}
        content {
          key   = try(string_not_equals.value["key"], null)
          value = try(string_not_equals.value["value"], null)
        }
      }
      dynamic "string_not_like" {
        for_each = each.value.condition["string_not_like"] != null ? each.value.condition["string_not_like"] : {}
        content {
          key   = try(string_not_like.value["key"], null)
          value = try(string_not_like.value["value"], null)
        }
      }
    }
  }
}
```

local:

```plaintext
locals {

  # Selection
  selection = var.selection_name == null ? {} : {
    selection = {
      name           = var.selection_name
      resources      = var.selection_resources
      not_resources  = var.selection_not_resources
      conditions     = var.selection_conditions
      selection_tags = var.selection_tags
    }
  }

  # Selections
  selections = merge(local.selection, var.selections)
}
```
