4

《Terraform 101 从入门到实践》 Functions函数 - 南瓜慢说

 1 year ago
source link: https://www.cnblogs.com/larrydpk/p/17113383.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站GitHub两个地方同步更新,书中的示例代码也是放在GitHub上,方便大家参考查看。


Terraform的函数

Terraform为了让大家在表达式上可以更加灵活方便地进行计算,提供了大量的内置函数(Function)。目前并不支持自定义函数,只能使用Terraform自带的。使用函数的格式也很简单,直接写函数名+参数即可。如下面的函数为取最大值:

> max(34, 45, 232, 25)
232

这里把函数单独列成一章不是因为它很难理解,而因为它很常用,值得把这些函数梳理一下,以便查询使用吧。

数值计算函数

绝对值abs:

> abs(5)
5
> abs(-3.1415926)
3.1415926
> abs(0)
0

返回大于等于该数值的最小整数:

> ceil(3)
3
> ceil(3.1)
4
> ceil(2.9)
3

小于等于该数值的最大整数:

> floor(6)
6
> floor(6.9)
6
> floor(5.34)
5

对数函数:

> log(16, 2)
4
> log(9, 3)
2.0000000000000004

指数函数:

> pow(6, 2)
36
> pow(6, 1)
6
> pow(6, 0)
1

最大值、最小值:

> max(2, 98,  75, 4)
98
> min(2, 98,  75, 4)
2

字符串转换成整数,第二个参数为进制:

> parseint("16", 10)
16
> parseint("16", 16)
22
> parseint("FF", 16)
255
> parseint("1010", 2)
10

信号量函数:

> signum(6)
1
> signum(-6)
-1
> signum(0)
0

字符串函数

删去换行,在从文件中读取文本时非常有用:

> chomp("www.pkslow.com")
"www.pkslow.com"
> chomp("www.pkslow.com\n")
"www.pkslow.com"
> chomp("www.pkslow.com\n\n")
"www.pkslow.com"
> chomp("www.pkslow.com\n\n\r")
"www.pkslow.com"
> chomp("www.pkslow.com\n\n\ra")
<<EOT
www.pkslow.com

a
EOT

格式化输出:

> format("Hi, %s!", "Larry")
"Hi, Larry!"

> format("My name is %s, I'm %d", "Larry", 18)
"My name is Larry, I'm 18"

> format("The reuslt is %.2f", 3)
"The reuslt is 3.00"

> format("The reuslt is %.2f", 3.1415)
"The reuslt is 3.14"

> format("The reuslt is %8.2f", 3.1415)
"The reuslt is     3.14"

遍历格式化列表:

> formatlist("My name is %s, I'm %d %s.", ["Larry", "Jeremy", "Tailor"], [18, 28, 33], "in 2022")
tolist([
  "My name is Larry, I'm 18 in 2022.",
  "My name is Jeremy, I'm 28 in 2022.",
  "My name is Tailor, I'm 33 in 2022.",
])

参数可以是List,还可以是单个变量。

字符串连接:

> join(".", ["www", "pkslow", "com"])
"www.pkslow.com"
> join(", ", ["Larry", "Pkslow", "JJ"])
"Larry, Pkslow, JJ"

大小写字母转换:

> lower("Larry Nanhua DENG")
"larry nanhua deng"
> upper("Larry Nanhua DENG")
"LARRY NANHUA DENG"

首字母大写:

> title("larry")
"Larry"
> replace("www.larrydpk.com", "larrydpk", "pkslow")
"www.pkslow.com"
> replace("hello larry", "/la.*y/", "pkslow")
"hello pkslow"
> split(".", "www.pklow.com")
tolist([
  "www",
  "pklow",
  "com",
])
> strrev("pkslow")
"wolskp"
> substr("Larry Deng", 0, 5)
"Larry"
> substr("Larry Deng", -4, -1)
"Deng"

去除头尾某些特定字符,注意这里只要有对应字符就会删除:

> trim("?!what?!!!!!", "?!")
"what"
> trim("abaaaaabbLarry Dengaab", "ab")
"Larry Deng"

去除头尾特定字符串,注意与上面的区别:

> trimsuffix("?!what?!!!!!", "!!!")
"?!what?!!"
> trimprefix("?!what?!!!!!", "?!")
"what?!!!!!"

去除头尾的空格、换行等空串:

> trimspace(" Larry Deng \n\r")
"Larry Deng"

正则匹配,下面的例子是匹配第一个和匹配所有:

> regex("[a-z\\.]+", "2021www.pkslow.com2022larry deng 31415926")
"www.pkslow.com"
> regexall("[a-z\\.]+", "2021www.pkslow.com2022larry deng 31415926")
tolist([
  "www.pkslow.com",
  "larry",
  "deng",
])

更多正则匹配语法可参考:https://www.terraform.io/language/functions/regex

集合类函数

alltrue:判断列表是否全为真,空列表直接返回true。只能是bool类型或者对应的字符串。

> alltrue([true, "true"])
true
> alltrue([true, "true", false])
false
> alltrue([])
true
> alltrue([1])
╷
│ Error: Invalid function argument
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ Invalid value for "list" parameter: element 0: bool required.

anytrue:判断列表是否有真,只要有一个为真就返回true。空列表为false。

> anytrue([true])
true
> anytrue([true, false])
true
> anytrue([false, false])
false
> anytrue([])
false

chunklist分片:根据分片数来对列表进行切分。

> chunklist(["www", "pkslow", "com", "Larry", "Deng"], 3)
tolist([
  tolist([
    "www",
    "pkslow",
    "com",
  ]),
  tolist([
    "Larry",
    "Deng",
  ]),
])

coalesce返回第一个非空元素:

> coalesce("", "a", "b")
"a"
> coalesce("", "", "b")
"b"

coalescelist返回第一个非空列表:

> coalescelist([], ["pkslow"])
[
  "pkslow",
]

从字符串列表里把空的去掉:

> compact(["", "www", "", "pkslow", "com"])
tolist([
  "www",
  "pkslow",
  "com",
])

concat连接多个列表:

> concat([1, 2, 3], [4, 5, 6])
[
  1,
  2,
  3,
  4,
  5,
  6,
]

contains判断是否存在某个元素:

> contains(["www", "pkslow", "com"], "pkslow")
true
> contains(["www", "pkslow", "com"], "Larry")
false

distinct去除重复元素:

> distinct([1, 2, 2, 1, 3, 8, 1, 10])
tolist([
  1,
  2,
  3,
  8,
  10,
])

element获取列表的某个元素:

> element(["a", "b", "c"], 1)
"b"
> element(["a", "b", "c"], 2)
"c"
> element(["a", "b", "c"], 3)
"a"
> element(["a", "b", "c"], 4)
"b"

flatten把内嵌的列表都展开成一个列表:

> flatten([1, 2, 3, [1], [[6]]])
[
  1,
  2,
  3,
  1,
  6,
]

index获取列表中的元素的索引值:

> index(["www", "pkslow", "com"], "pkslow")
1

keys获取map的所有key值:

> keys({name="Larry", age=18, webSite="www.pkslow.com"})
[
  "age",
  "name",
  "webSite",
]

values获取map的value值:

> values({name="Larry", age=18, webSite="www.pkslow.com"})
[
  18,
  "Larry",
  "www.pkslow.com",
]

length获取字符串、列表、Map等的长度:

> length([])
0
> length(["pkslow"])
1
> length(["pkslow", "com"])
2
> length({pkslow = "com"})
1
> length("pkslow")
6

lookup(map, key, default)根据key值在map中找到对应的value值,如果没有则返回默认值:

> lookup({name = "Larry", age = 18}, "age", 1)
18
> lookup({name = "Larry", age = 18}, "myAge", 1)
1

matchkeys(valueslist, keyslist, searchset)对key值进行匹配。匹配到key值后,返回对应的Value值。

> matchkeys(["a", "b", "c", "d"], [1, 2, 3, 4], [2, 4])
tolist([
  "b",
  "d",
])

merge合并Map,key相同的会被最后的覆盖:

> merge({name = "Larry", webSite = "pkslow.com"}, {age = 18})
{
  "age" = 18
  "name" = "Larry"
  "webSite" = "pkslow.com"
}
> merge({name = "Larry", webSite = "pkslow.com"}, {age = 18}, {age = 13})
{
  "age" = 13
  "name" = "Larry"
  "webSite" = "pkslow.com"
}

one取集合的一个元素,如果为空则返回null;如果只有一个元素,则返回该元素;如果多个元素,则报错:

> one([])
null
> one(["pkslow"])
"pkslow"
> one(["pkslow", "com"])
╷
│ Error: Invalid function argument
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ Invalid value for "list" parameter: must be a list, set, or tuple value with either zero or one elements.
╵

range生成顺序列表:

range(max)
range(start, limit)
range(start, limit, step)

> range(3)
tolist([
  0,
  1,
  2,
])
> range(1, 6)
tolist([
  1,
  2,
  3,
  4,
  5,
])
> range(1, 6, 2)
tolist([
  1,
  3,
  5,
])

reverse反转列表:

> reverse([1, 2, 3, 4])
[
  4,
  3,
  2,
  1,
]

setintersection对set求交集:

> setintersection([1, 2, 3], [2, 3, 4], [2, 3, 6])
toset([
  2,
  3,
])

setproduct列出所有组合可能:

> setproduct(["Larry", "Harry"], ["Deng", "Potter"])
tolist([
  [
    "Larry",
    "Deng",
  ],
  [
    "Larry",
    "Potter",
  ],
  [
    "Harry",
    "Deng",
  ],
  [
    "Harry",
    "Potter",
  ],
])

setsubtract:set的减法

> setsubtract([1, 2, 3], [3, 4])
toset([
  1,
  2,
])

# 求不同
> setunion(setsubtract(["a", "b", "c"], ["a", "c", "d"]), setsubtract(["a", "c", "d"], ["a", "b", "c"]))
[
  "b",
  "d",
]

setunion:set的加法

> setunion([1, 2, 3], [3, 4])
toset([
  1,
  2,
  3,
  4,
])

slice(list, startindex, endindex)截取列表部分,包括startindex,但不包括endindex:

> slice(["a", "b", "c", "d", "e"], 1, 4)
[
  "b",
  "c",
  "d",
]

sort对列表中的字符串进行排序,要注意如果输入的是数字,会先转化为字符串再排序:

> sort(["larry", "pkslow", "com", "deng"])
tolist([
  "com",
  "deng",
  "larry",
  "pkslow",
])
> sort([3, 6, 1, 9, 12, 79, 22])
tolist([
  "1",
  "12",
  "22",
  "3",
  "6",
  "79",
  "9",
])

sum求和:

> sum([3, 1.2, 9, 17.3, 2.2])
32.7

transpose对Map的key和value进行换位:

> transpose({"a" = ["1", "2"], "b" = ["2", "3"]})
tomap({
  "1" = tolist([
    "a",
  ])
  "2" = tolist([
    "a",
    "b",
  ])
  "3" = tolist([
    "b",
  ])
})

zipmap根据key和value的列表按一对一关系生成Map:

> zipmap(["age", "name"], [18, "Larry Deng"])
{
  "age" = 18
  "name" = "Larry Deng"
}

Base64:

> base64encode("pkslow")
"cGtzbG93"
> base64decode("cGtzbG93")
"pkslow"
> textencodebase64("pkslow", "UTF-8")
"cGtzbG93"
> textdecodebase64("cGtzbG93", "UTF-8")
"pkslow"

csv文本解析:

> csvdecode("seq,name,age\n1,larry,18\n2,pkslow,3\n3,Jeremy,29")
tolist([
  {
    "age" = "18"
    "name" = "larry"
    "seq" = "1"
  },
  {
    "age" = "3"
    "name" = "pkslow"
    "seq" = "2"
  },
  {
    "age" = "29"
    "name" = "Jeremy"
    "seq" = "3"
  },
])

Json解析:

> jsonencode({"name"="Larry", "age"=18})
"{\"age\":18,\"name\":\"Larry\"}"
> jsondecode("{\"age\":18,\"name\":\"Larry\"}")
{
  "age" = 18
  "name" = "Larry"
}
> urlencode("Larry Deng/a/:/./@")
"Larry+Deng%2Fa%2F%3A%2F.%2F%40"

YAML:

> yamlencode({"a":"b", "c":"d"})
"a": "b"
"c": "d"

> yamlencode({"foo":[1, 2, 3], "bar": "baz"})
"bar": "baz"
"foo":
- 1
- 2
- 3

> yamlencode({"foo":[1, {"a":"b","c":"d"}, 3], "bar": "baz"})
"bar": "baz"
"foo":
- 1
- "a": "b"
  "c": "d"
- 3
> yamldecode("hello: world")
{
  "hello" = "world"
}

> yamldecode("true")
true

> yamldecode("{a: &foo [1, 2, 3], b: *foo}")
{
  "a" = [
    1,
    2,
    3,
  ]
  "b" = [
    1,
    2,
    3,
  ]
}

文件处理:

获取绝对路径:

> abspath(path.root)
"/Users/larry"

获取路径中的目录,或者是文件名:

> dirname("/home/larry/soft/terraform")
"/home/larry/soft"
> dirname("/home/larry/soft/terraform/")
"/home/larry/soft/terraform"
> basename("/home/larry/soft/terraform")
"terraform"
> basename("/home/larry/soft/terraform/")
"terraform"

判断文件是否存在,并获取文件内容:

> fileexists("/Users/larry/.bash_profile")
true
> file("/Users/larry/.bash_profile")
> filebase64("/Users/larry/.bash_profile")

根据模式匹配所有文件:

> fileset("/Users/larry", "*.bash*")
toset([
  ".bash_history",
  ".bash_profile",
  ".bash_profile.backup",
])

templatefile(path, vars)模板化文件:指定文件和变量,把变量值替换掉模板中的变量。

获取当前时间,并格式化显示,格式请参考:https://www.terraform.io/language/functions/formatdate

> formatdate("YYYY-MM-DD hh:mm:ss / D MMMM YYYY", timestamp())
"2022-03-05 08:25:48 / 5 March 2022"
> formatdate("EEEE, DD-MMM-YY hh:mm:ss ZZZ", "2018-01-02T23:12:01Z")
"Tuesday, 02-Jan-18 23:12:01 UTC"

时间加减:

> timeadd(timestamp(), "24h")
"2022-03-06T08:28:52Z"
> timeadd(timestamp(), "-24h10m")
"2022-03-04T08:19:08Z"

支持的单位有:"ns", "us" (or "µs"), "ms", "s", "m", and "h".

> md5("www.pkslow.com")
"97e164b60faf4d7875c2a8a5bc3f2245"

UUID:

> uuid()
"049bf418-15d1-e034-28db-92945067dcf6"
> cidrsubnet("172.16.0.0/12", 4, 2)
"172.18.0.0/16"

更多请参考官网。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK