《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")<<EOTwww.pkslow.comaEOT

格式化输入:

> 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/lang...

汇合类函数

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"}

URL:

> 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/lang...

> 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"

IP:

> cidrsubnet("172.16.0.0/12", 4, 2)"172.18.0.0/16"

更多请参考官网。