Transform list to map in Terraform(end)
Tags: terraform, list, map, foreach
Published: 2023-07-24 05:36:30

Product ส่วนใหญ่ทำมาเพื่อให้ชีวิตง่ายขึ้น แน่นอนว่า Series นี้ว่าด้วยความง่าย คือให้ผู้ใช้ Terraform ใส่สิ่งที่ต้องการเฉพาะที่จำเป็น แล้วสร้าง Resources ออกมาตามที่ต้องการ


อ่านตอนที่ 1,2
[1: ทำไมใช้ for_each แทน count ใน terraform](https://bit.ly/tf_for_each)
[2: Enumerate the Variables in Terraform.](https://bit.ly/tf_var1)

ตอนนี้เป็นตอนสุดท้ายครับ จะแปลง List ที่เราได้ Enumerate ออกมา แปลงเป็น map

การเป็น map จะต้องมี key:value ฉะนั้นการแปลง list เป็น map เราจะต้องระบุ key ให้ได้เสียก่อน

Key จะต้อง unique ด้วย ก็คือไม่ซ้ำกัน เช่นจะมี user 2 ค่าไม่ได้ ในที่นี้ก็คือจะมีเครื่องที่มีตัว key เดียวกันไม่ได้นั่นเอง

ในบทความก่อนหน้า(ตามลิงค์ด้านบน) เราได้สร้าง list ของแต่ละเครื่องออกมาแล้ว หนึ่งในนั้นคือ name ซึ่งประกอบไปด้วย Group name รวมกับลำดับใน Group นั้น ซึ่งมีความ Unique จึงสามารถมานำ name ตรงนี้มาใช้เป็น key ให้กับ map ที่จะสร้างได้

ส่วนถัดมาคือ value, ก็คือ Property ของแต่ละ key หรือแต่ละ Resource นั่นเอง
ในตัวอย่างจะเป็น Property ของ VM ก็คือจะนำค่าจาก property ใน list ก่อนหน้ามาใช้ได้เลยนั่นเอง

จากตอนก่อนหน้า เราทราบแล้วว่าต้องการสร้าง map, และ map ใช้ {} นั่นเอง

การสร้าง key:value ใน map ใช้สัญลักษณ์ =>

ตอนก่อนหน้า เราได้ใส่ index ของ vm ในแต่ละ group แล้ว แต่ยังไม่มี global index สำหรับทุกๆ VM ซึ่งเราจะใส่ในขั้นตอนนี้ โดยใช้เป็น
for indeex, i in local.vm_list
จะได้ว่า i จะเป็น Element แต่ละตัวใน local.vm_list
และ index จะเป็น incremental เริ่มที่ 0, 1, 2 ไปในแต่ละ element i ใน local.vm_list

นำด้านบนมาประกอบกัน จะทำการสร้าง map ได้ดังนี้ครับ

```
vm_map = {for index, i in local.vm_list: i.name => {

```
ในเคสนี้ จะใช้ loop ชั้นเดียว เพราะ local.vm_list นั้นถูก Enumerate มาเป็นข้อมูลแต่ละ Resource(VM) ตั้งแต่ขั้นตอนก่อนหน้า(ซึ่งตอนนั้นทำ Loop 2 ชั้น คือ Group และ VM และแต่ละ Group ไปให้แล้ว)

จากนั้นก็เหลือขั้นตอนการให้ค่า value ที่จะคู่กับ key ที่เป็น name
value ที่ใช้จะเลือกเป็น list หรือเป็น map ในกรณีนี้แต่ละ resource มี Unique key และไม่มีซ้ำ ฉะนั้นจึงควรเลือกเป็น key โดยมี key ดังนี้ name, group, cpu, memory, index, index_all(ค่า Global Index ที่ได้จาก index ที่ใส่เพิ่มมาในบรรทัด for นั่นเอง)

เมื่อประกอบ loop และการให้ค่าใน value เข้าด้วยกัน จะได้ดังนี้

```
  vm_map = {for index, i in local.vm_list: i.name => {
        name  = i.name
        group = i.group
        cpu   = i.cpu
        memory= i.memory
        index = i.index
        index_all = index+1
  }}
```

ฉะนั้น สามารถสรุปขั้นตอนการแปลงค่าจาก list อย่างง่าย ให้ Enumerate ออกมาเป็น Map ได้ดังนี้
Step 0: สารตั้งตั้น

```
vm = tolist([                                                                                                                                                                                                      {                                                                                                                                                                                                                  "count" = 2                                                                                                                                                                                                      "cpu" = 2                                                                                                                                                                                                        "group" = "GropuA"                                                                                                                                                                                               "memory" = 2048                                                                                                                                                                                                },                                                                                                                                                                                                               {                                                                                                                                                                                                                  "count" = 1                                                                                                                                                                                                      "cpu" = 1                                                                                                                                                                                                        "group" = "GroupB"                                                                                                                                                                                               "memory" = 1024                                                                                                                                                                                                },                                                                                                                                                                                                               {                                                                                                                                                                                                                  "count" = 0                                                                                                                                                                                                      "cpu" = 2                                                                                                                                                                                                        "group" = "GroupC"
    "memory" = 2048
  },
])
```

Step 1:
Enumerate ด้วย loop 2 ชั้น ได้ list ของ VM แต่ละเครื่อง พร้อม Property

```
vm_list = tolist([
  {
    "cpu" = 2
    "group" = "GropuA"
    "index" = 1
    "memory" = 2048
    "name" = "GropuA-1"
  },
  {
    "cpu" = 2
    "group" = "GropuA"
    "index" = 2
    "memory" = 2048
    "name" = "GropuA-2"
  },
  {
    "cpu" = 1
    "group" = "GroupB"
    "index" = 1
    "memory" = 1024
    "name" = "GroupB-1"
  },
])
```


Step 2:
แปลง list เป็น map และเพิ่ม Global Index ให้กับแต่ละ VM ฉะนั้นแต่ละ VM จะมีทั้ง Global Index และ local index ของ group ที่ตนเองอยู่นั่นเอง

```
vm_map = {
  "GropuA-1" = {
    "cpu" = 2
    "group" = "GropuA"
    "index" = 1
    "index_all" = 1
    "memory" = 2048
    "name" = "GropuA-1"
  }
  "GropuA-2" = {
    "cpu" = 2
    "group" = "GropuA"
    "index" = 2
    "index_all" = 2
    "memory" = 2048
    "name" = "GropuA-2"
  }
  "GroupB-1" = {
    "cpu" = 1
    "group" = "GroupB"
    "index" = 1
    "index_all" = 3
    "memory" = 1024
    "name" = "GroupB-1"
  }
}
```