Contents

tf-code

Terraform 代码片段

1、变量控制代码是否启用

module "istio" {
  count  = var.istio.enabled ? 1 : 0
  source = "xxxxxx"
}

2、state文件中获取数据

state文件中需要有output,才能使用

data "terraform_remote_state" "global" {
  backend = "local"
  config = {
    path = "../../global/terraform.tfstate"
  }
}

data "terraform_remote_state" "global" {
  backend = "http"
  config = {
    address = "http://git.local.com/api/v4/projects/111/terraform/state/xxxstatefile"
  }
}



locals {
  domain           = data.terraform_remote_state.global.outputs.domain

3、获取terraform当前执行的目录

resource "null_resource" "pwd" {
  triggers = {
    always_run = "${uuid()}"
  }
  provisioner "local-exec" {
    command = "echo ${path.cwd} >> somefile.txt"
  }
}

4、for_each 循环

resource "tencentcloud_dnspod_record" "domain_record_dnspod" {
  for_each = { for k, v in var.domain_record :
    k => {
      type        = v.type,
      record      = v.record,
      sub_domain  = v.sub_domain,
      domain      = v.domain,
      record_line = v.record_line

    }
  }
  domain      = each.value.domain
  record_line = each.value.record_line
  record_type = each.value.type
  value       = each.value.record
  sub_domain  = each.value.sub_domain
}



resource "xxxxx" "xxxx" {
  for_each = {for k,v in var.ack_nodes: k => v if !contains(keys(v), "hello")}
  *****
}

5、contains

# 如果 var.hello.world 有world这个key,就使用对应的值,否则就使用 github 这个默认值
resource "xxxx" "xxx" {
	name = contains(keys(var.hello), "world") ? var.hello.world:"github"
	age = var.age > 50 ? var.age : 18
}

6、merge


data "aliyun_images_image" "image" {
  for_each = merge(var.ack_nodes, var.ecs)

  name_regex                = contains(keys(var.ack_nodes), each.key) ? "Ubuntu 20.*bit$":"${each.value.os}.*bit$"
  architecture              = "x86"
  visibility                = "public"
  most_recent               = true
}

7、concat

拼接和合并多个list

member_names = []
member_names = concat(
      [for i in  nexus_repository_npm_proxy.proxy: i.name],
      [nexus_repository_npm_hosted.local.name],
      )

terraform 内置函数

https://whyliyi.github.io/2020/01/29/terraform-%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0(Built-in-functions).html

可以使用 terraform console 进行调试

# max/min:取最大/最小
> max(100,1)
100
> min(12, 54, 3)
3

# abs:取数字的绝对值
> abs(23)
23
> abs(0)
0
> abs(-12.4)
12.4

# ceil:上取整
> ceil(5)
5
> ceil(5.1)
6

# floor:下取整
> floor(5)
5
> floor(4.9)
4

# log: 取对数
> log(16, 2)
4

# parseint:将字符串转换成对应进制的数字
> parseint("100", 10)
100

> parseint("FF", 16)
255

> parseint("-10", 16)
-16

> parseint("1011111011101111", 2)
48879

# pow:求幂
> pow(3, 2)
9

# signum:求符号
> signum(-13)
-1
> signum(0)
0
> signum(344)
1	

#### 字符串函数
# chomp:删除换行符
> chomp("hello\n\n")
hello

# format:格式化字符串
> format("Hello, %s!", var.name)
Hello, Valentina!

# formatlist:格式化字符串列表
> formatlist("%s, %s!", "Salutations", ["Valentina", "Ander", "Olivia", "Sam"])
[
  "Salutations, Valentina!",
  "Salutations, Ander!",
  "Salutations, Olivia!",
  "Salutations, Sam!",
]

# indent:多行字符串缩进指定字符串数
> "  items: %{indent(2, "[\n  foo,\n  bar,\n]\n")}"
  items: [
    foo,
    bar,
  ]


# join:用指定分隔符连接列表中的字符串
> join(", ", ["foo", "bar", "baz"])
foo, bar, baz

# split:按照指定分隔符分割字符串
> split("+", "1+2+3")
[1, 2, 3,]

# lower:字符串转化为全小写
# upper:字符串转化为全大写


# regex:按照正则表达式匹配字符串,并且返回第一个匹配成功的子字符串
> regex("[a-z]+", "53453453.345345aaabbbccc23454")
aaabbbccc

# regexall:按照正则表达式匹配字符串,并返回匹配的子字符串列表
> regexall("[a-z]+", "1234abcd5678efgh9")
[
  "abcd",
  "efgh",
]

# replace:替换字符串中符合条件的子字符串
> replace("1 + 2 + 3", "+", "-")
1 - 2 - 3

# strrev:字符串逆序
> strrev("hello")
olleh

# substr:字符串分片
> substr("hello world", 1, 4)
ello

# title:单词的首字母大写
> title("hello world")
Hello World

# trim:删除字符串首尾指定字符串
> trim("?!hello?!", "!?")
hello

# trimprefix:删除字符串指定前缀
> trimprefix("helloworld", "hello")
world

# trimsuffix:删除字符串指定后缀
> trimsuffix("helloworld", "world")
hello

# trimspace:删除前后空格
> trimspace("  hello\n\n")
hello




##### 类型转换函数
# tobool:转换成bool类型,仅仅是true、false、”true”、”false”可以转换
# tolist:将参数转化成列表类型
> tolist(["a", "b", 3])
[
  "a",
  "b",
  "3",
]	


# tomap:转换成map类型
> tomap({"a" = "foo", "b" = true})
{
  "a" = "foo"
  "b" = "true"
}

# tonumber:转换成数字
> tonumber(1)
1
> tonumber("1")
1
> tonumber("no")
Error: Invalid function argument

# toset:转换成set类型
> toset(["c", "b", "b", 3])
[
  "b",
  "c",
  "3",
]

# tostring:转换成字符串类型, 只对string、number、bool类型有效
> tostring("hello")
hello
> tostring(1)
1
> tostring(true)
true
> tostring([])
Error: Invalid function argument


# try:计算所有的表达式,并返回第一个计算成功的结果,并且不会抛出任何错误
> local.foo
{
  "bar" = "baz"
}
> try(local.foo.bar, "fallback")
baz
> try(local.foo.boop, "fallback")
fallback



# chunklist 分片
chunklist(list, chunk_size)
> chunklist(["a", "b", "c", "d", "e"], 2)
[
  [
    "a",
    "b",
  ],
  [
    "c",
    "d",
  ],
  [
    "e",
  ],
]


# coalesce 返回第一个不为空的元素
> coalesce("a", "b")
a
> coalesce(["", "b"]...)
b


# coalescelist 返回第一个不为空的list
> coalescelist(["a", "b"], ["c", "d"])
[
  "a",
  "b",
]
> coalescelist([], ["c", "d"])
[
  "c",
  "d",
]


# compact 返回非空的全部元素
> compact(["a", "", "b", null, "c"])
[
  "a",
  "b",
  "c",
]


# concat 合并多个list
> concat(["a", ""], ["b", "c"])
[
  "a",
  "",
  "b",
  "c",
]

# contains 判断是否包含
contains(list, value)

# distinct 转换为字典,去重
> distinct(["a", "b", "a", "c", "d", "b"])
[
  "a",
  "b",
  "c",
  "d",
]

# element 取list 中的索引元素
element(list, index)
> element(["a", "b", "c"], 1)
b

#大于索引的时候取第一个元素
> element(["a", "b", "c"], 3)
a

> element(["a", "b", "c"], length(["a", "b", "c"])-1)
c


# flatten 扁平化合并
> flatten([["a", "b"], [], ["c"]])
["a", "b", "c"]

> flatten([[["a", "b"], []], ["c"]])
["a", "b", "c"]

# lookup 查找
lookup(map, key, default)
> lookup({a="ay", b="bee"}, "a", "what?")
ay
> lookup({a="ay", b="bee"}, "c", "what?")
what?

# range 
range(max)
range(start, limit)
range(start, limit, step)
> range(3)
[
  0,
  1,
  2,
]
 
> range(1, 4)
[
  1,
  2,
  3,
]
 
> range(1, 8, 2)
[
  1,
  3,
  5,
  7,
]

# reverse 反转
> reverse([1, 2, 3])
[
  3,
  2,
  1,
]

# setintersection 获取重复的元素
> setintersection(["a", "b"], ["b", "c"], ["b", "d"])
[
  "b",
]

# setunion set 联合
> setunion(["a", "b"], ["b", "c"], ["d"])
[
  "d",
  "b",
  "c",
  "a",
]

# slice 切片
> slice(["a", "b", "c", "d"], 1, 3)
[
  "b",
  "c",
]

字符串函数

函数名称 函数描述 样例 运行结果
format 字符串格式化 format(“Hello, %s!”, “cloud”) Hello, cloud!
lower 将字符串中的字母转换为小写 lower(“HELLO”) hello
upper 将字符串中的字母转换为大写 upper(“hello”) HELLO
join 使用自定义字符将列表拼接成字符串 join(", “, [“One”, “Two”, “Three”]) One, Two, Three
split 根据分隔符拆分字符串 split(”, “, “One, Two, Three”) [“One”, “Two”, “Three”]
substr 通过偏移量和长度从给定的字符串中提取一个子串 substr(“hello world!”, 1, 4) ello
replace 把字符串中的str1替换成str2 replace(“hello, cloud!”, “h”, “H”) Hello, cloud!

数值计算函数

函数名称 函数描述 样例 运行结果
abs 计算绝对值 abs(-12.4) 12.4
max 计算最大值 max(12, 54, 6)max([12, 54, 6]…) 5454
min 计算最小值 min(12, 54, 6)min([12, 54, 6]…) 66
log 计算对数 log(16, 2) 4
power 计算x的y次幂 power(3, 2) 9

集合函数

函数名称 函数描述 样例 运行结果
element 通过下标从列表中检索对应元素值 element([“One”, “Two”, “Three”], 1) Two
index 返回给定值在列表中的索引,如果该值不存在将报错。 index([“a”, “b”, “c”], “b”) 1
lookup 使用给定的键从映射表中检索对应的值。如果给定的键不存在,则返回默认值。 lookup({IT=“A”, CT=“B”}, “IT”, “G”)lookup({IT=“A”, CT=“B”}, “IE”, “G”) AG
flatten 展开列表中的嵌套元素 flatten([[“a”, “b”], [], [“c”]]) [“a”, “b”, “c”]
keys 返回map中的所有key keys({a=1, b=2, c=3}) [“a”, “b”, “c”]
length 获取列表、映射或是字符串的长度 length([“One”, “Two”, “Three”])length({IT=“A”, CT=“B”})length(“Hello, cloud!”) 3213

类型转化函数

函数名称 函数描述 样例 运行结果
toset 将列表类型转换为集合类型 toset([“One”, “Two”, “One”]) [“One”, “Two”]
tolist 将集合类型转换为列表类型 tolist([“One”, “Two”, “Three”]) [“One”, “Two”, “Three”]
tonumber 将字符串类型转换为数字类型 tonumber(“33”) 33
tostring 将数字类型转换为字符串类型 tostring(33) “33”

编码函数

函数名称 函数描述 样例 运行结果
base64encode 将UTF-8字符串转换为base64编码 base64encode(“Hello, cloud!”) SGVsbG8sIGNsb3VkIQ==
base64decode 将base64编码解码为UTF-8字符串(结果非UTF-8格式会报错) base64decode(“SGVsbG8sIGNsb3VkIQ==”) Hello, cloud!
base64gzip 将UTF-8字符串压缩并转换为base64编码 base64gzip(“Hello, cloud!”) H4sIAAAAAAAA//JIzcnJ11FIzskvTVEEAAAA//8BAAD//wbrhYUNAAAA

哈希和加密函数

函数名称 函数描述 样例 运行结果
sha256 计算字符串的SHA256值(16进制) sha256(“Hello, cloud!”) 0ad167d1e3ac8e9f4e4f7ba83e92d0e3838177e959858631c770caaed8cc5e3a
sha512 计算字符串的SHA512值(16进制) sha512(“Hello, cloud!”) 6eb6ed9fc4edffaf90e742e7697f6cc7d8548e98aa4d5aa74982e5cdf78359e84a3ae9f226313b2dec765bf1ea4c83922dbfe4a61636d585da44ffbd7e900f56
base64sha256 计算字符串的SHA256值,并转换为base64编码 base64sha256(“Hello, cloud!”) CtFn0eOsjp9OT3uoPpLQ44OBd+lZhYYxx3DKrtjMXjo=
base64sha512 计算字符串的SHA512值,并转换为base64编码 base64sha512(“Hello, cloud!”) brbtn8Tt/6+Q50LnaX9sx9hUjpiqTVqnSYLlzfeDWehKOunyJjE7Lex2W/HqTIOSLb/kphY21YXaRP+9fpAPVg==
md5 计算MD5值 md5(“hello world”) 5eb63bbbe01eeed093cb22bb8f5acdc3

文件操作函数

函数名称 函数描述 样例 运行结果
abspath 计算文件的绝对路径 abspath(”./hello.txt") /home/demo/test/terraform/hello.txt
dirname 计算字符串中包含的路径 dirname(“foo/bar/baz.txt”) foo/bar
basename 计算字符串中的文件名 basename(“foo/bar/baz.txt”) baz.txt
file 读取文件并返回文件内容 file("./hello.txt") Hello, cloud!
filebase64 读取文件并返回文件内容的base64编码 filebase64("./hello.txt") SGVsbG8sIGNsb3VkIQ==

其他

减小 terraform 项目目录体积

目录中 provider 的二进制包占主要,在分发项目到其它 Arch 和 OS 的机器运行的时候,可以先将 provider目录删除,然后在压缩并进行分发。