В цьому пості трохи подивимось на типи даних, які можемо використовувати в Terraform, щоб простіше розібратись з наступним постом – Terraform: цикли count, for_each та for.
Документація – Type Constraints та Types and Values.
Маємо наступні типи поділені на групи:
- Primitive Types:
string
: послідовність Unicode символів, простий текстnumber
: числові значенняbool
: true або false
- Complex Types:
- Collection Types:
list
: список – тип структури для зберігання простої колекції значень одного типу, доступних по індексамmap
: колекція key:value значень одного типуset
: аналогічнаlist
, але без індексів та сортування
- Structural Types:
object
: для зберігання значені різних типів даних – набір іменованих атрибутів, кожен з власним типом данихtuple
: послідовність елементів, кожен з власним типом даних, з індексами як уlist
- Collection Types:
Зміст
Primitive types
Найпростіший тип, в якому можемо зберігати тільки одне значення певного типу.
string
Приклад:
variable "var_string" { type = string default = "a string" } output "string" { value = var.var_string }
Результат очевидний:
... Outputs: string = "a string"
number
Аналогічно, але для integer значень:
variable "var_number" { type = number default = 1 } output "number" { value = var.var_number }
Результат:
... Outputs: number = 1
bool
Використовується для Conditional Expressions:
variable "var_bool" { type = bool default = true } output "number" { value = var.var_bool ? "True" : "False" }
Результат:
... Outputs: number = "True"
Або створення ресурсу, якщо умова дійсна:
resource "local_file" "file" { count = var.var_bool ? 1 : 0 filename = "file.txt" content = var.var_string }
Collection Types
list
Послідовність значень одного типу з індексами, починаючи з нуля.
При створенні list можна або не вказувати тип (default == any
), або обмежити одним певним типом:
variable "var_list_any" { type = list default = ["a string", 10] } variable "var_list_string" { type = list(string) default = ["first string", "second string"] } resource "local_file" "file" { filename = "file-${var.var_list_any[1]}.txt" content = var.var_list_string[0] } output "list_any" { value = var.var_list_any } output "list_string" { value = var.var_list_string }
Результат:
... Outputs: list_any = tolist([ "a string", "10", ]) list_string = tolist([ "first string", "second string", ])
І файл:
$ cat file-10.txt first string
В list
можна використовувати інші типи даних – інші list
, map
тощо.
При цьому в одному list
можуть бути різні типи примітивів (string
, number
, bool
), але однаковий тип для інших типів, тобто:
variable "var_list_any" { type = list default = ["a", true, 1] } variable "var_list_lists" { type = list default = [ ["a", "b"], ["c", "d"] ] } output "list_any" { value = var.var_list_any } output "list_lists" { value = var.var_list_lists }
Результат:
... Outputs: list_any = tolist([ "a", "true", "1", ]) list_lists = tolist([ [ "a", "b", ], [ "c", "d", ], ])
Зі списками можемо використовувати цикли, наприклад:
variable "var_list_any" { type = list default = ["a string", 10] } variable "var_list_string" { type = list(string) default = ["first string", "second string"] } resource "local_file" "file" { for_each = toset(var.var_list_any) filename = "file-${each.key}.txt" content = each.value } output "list_string" { value = [ for a in var.var_list_string : upper(a)] }
Результат:
... Outputs: list_string = [ "FIRST STRING", "SECOND STRING", ]
Та файли:
$ ls -1 file-10.txt 'file-a string.txt' $ cat file-a\ string.txt a string
map
Значення у формі key:value з доступом до значення по імені ключа:
variable "var_map" { type = map default = { "one" = "first", "two" = "second" } } output "map_one" { value = var.var_map["one"] } output "map_two" { value = var.var_map["two"] }
Також в outputs можемо вивести атрибут, тобто value = var.var_map.one
.
Результат:
... Outputs: map_one = "first" map_two = "second"
Також з map
можемо використати lookup()
для пошуку значення по ключу:
output "map_lookup" { value = lookup(var.var_map, "one", "None") }
Результат:
... Outputs: map_lookup = "first" map_one = "first" map_two = "second"
Або більш складний приклад – вибір кількості інстансів за ціною в залежності від типу:
variable "instance_cost" { type = map default = { "t3.medium" = "0.04USD", "t3.large" = "0.08USD", } } variable "instance_number" { type = map default = { "0.04USD" = 2, "0.08USD" = 1, } } output "instances_count" { value = lookup(var.instance_number, var.instance_cost["t3.medium"], 0) }
Результат:
... Outputs: instances_count = 2
map
також може включати в себе list
або інший map
, але всі об’єкти мають бути одного типу (тобто, не можна мати map
в якому будуть і list
, і другий map
):
variable "var_map_of_maps" { type = map default = { "out-map-key-1" = { "in-map-key-1" = "inner map 1 key one", "in-map-key-2" = "inner map 1 inner key two", }, "out-map-key-2" = { "in-map-key-1" = "inner map 2 key one", "in-map-key-2" = "inner map 2 key two", }, } } output "map_of_maps" { value = var.var_map_of_maps }
Результат:
... Outputs: map_of_maps = tomap({ "out-map-key-1" = { "in-map-key-1" = "inner map 1 key one" "in-map-key-2" = "inner map 1 inner key two" } "out-map-key-2" = { "in-map-key-1" = "inner map 2 key one" "in-map-key-2" = "inner map 2 key two" } })
set
Послідовність значень одного або різних типів як в list
, але без індексів та сортування:
variable "var_set_any" { type = set(any) default = ["string", 1] } variable "var_set_string" { type = set(string) default = ["string1", "string2"] } output "set_any" { value = var.var_set_any } output "set_string" { value = var.var_set_string }
Результат:
... ... Outputs: set_any = toset([ "1", "string", ]) set_string = toset([ "string1", "string2", ])
Як і list
або map
, set
може мати вкладені типи:
variable "var_set_lists" { type = set(list(any)) default = [ ["a", "b"], ["c", "d"] ] } output "set_any" { value = var.var_set_lists }
Результат:
... set_any = toset([ tolist([ "a", "b", ]), tolist([ "c", "d", ]), ])
Structural Types
object
На відміну від map
та list
, object
є структурним типом, який може мати значення різних типів, в тому числі включати в себе типи list
та map
.
Схож на Struct в C або Golang:
variable "var_object" { type = object({ name = string, id = number, data = list(string) data_map = map(any) }) default = { name = "one", id = 10, data = ["first", "second"], data_map = { "one" = "first", "two" = "second" } } } output "object" { value = var.var_object } output "object_map" { value = var.var_object.data_map }
Результат:
... Outputs: object = { "data" = tolist([ "first", "second", ]) "data_map" = tomap({ "one" = "first" "two" = "second" }) "id" = 10 "name" = "one" } object_map = tomap({ "one" = "first" "two" = "second" })
tuple
Подібний до object
, але з індексами замість імен ключів:
variable "var_tuple" { type = tuple ([ string, number, list(string), map(any) ] ) default = [ "one", 10, ["first", "second"], { "one" = "first", "two" = "second" } ] } output "tuple" { value = var.var_tuple } output "tuple_map" { value = var.var_tuple[3] }
Результат:
Outputs: tuple = [ "one", 10, tolist([ "first", "second", ]), tomap({ "one" = "first" "two" = "second" }), ] tuple_map = tomap({ "one" = "first" "two" = "second" })
В наступному пості подивимось на цикли.
Посилання по темі
- Exploring Map, List, Set, and Object Datatypes in Terraform
- How to use Terraform variables
- How to Use Terraform Variables (Locals, Input, Output, Environment)