《Terraform 101 从入门到实际》这本小册在南瓜慢说官方网站和GitHub两个中央同步更新,书中的示例代码也是放在GitHub上,不便大家参考查看。
模块的概念
模块化是Terraform实现代码重用的形式。模块能够了解为一个蕴含多个资源的容器模板。封装好之后,能够给大家应用。也能够了解为代码中的函数或办法,它接支出参,通过一些申明式的调用后,输入一些后果变量。
从Terraform的代码层面来看,模块其实就是一个蕴含多个.tf或.tf.json文件的目录。任何一个Terraform我的项目,都是一个目录,所以也都是一个模块,咱们把它称为根模块(Root Module)。而在它目录下的其它模块,都是子模块。咱们能够调用多个模块,也能够屡次调用同一个子模块。在子模块中,也能够调用其它模块。这些特点,与函数无异。
调用模块有两种形式,一种是在以后我的项目定义一个模块,另一种是引入内部的模块。而内部模块的形式也很多种,如Git的仓库、压缩文件等。
定义并应用模块
咱们先来应用第一种形式,援用以后我的项目中的模块。
子模块的性能很简略,创立一个文件,文件名有随机字符串,以防止抵触。写入文件的内容能够通过参数指定。
子模块:
定义入参:创立一个文件叫variables.tf,专门用来定义入参:
variable "prefix" { type = string default = "pkslow" description = "File name prefix"}variable "content" { type = string default = "www.pkslow.com" description = "File content"}
这里输出有两个变量,都是字符串类型,别离是文件名前缀prefix和文件内容context。
定义模块性能,次要配置这个模块用治理的资源,个别会放在main.tf文件中,内容如下:
resource "random_string" "random" { length = 6 lower = true special = false}resource "local_file" "file" { content = var.content filename = "${path.root}/${var.prefix}.${random_string.random.result}.txt"}
这里定义了两个resource,第一个是生成6位的随机字符串。第二个是生成一个文件,第二个resource应用了输出参数,还应用了第一个资源生成的后果。所以第二个resource是依赖于第一个的。输出的变量援用形式为var.xxx
。
定义返回值:
能够不须要返回值,也能够定义一个或多个返回值。创立一个outputs.tf文件,内容如下:
output "file_name" { value = local_file.file.filename}
它返回的是后面第二个resource中的值。
当初,模块random-file曾经定义实现了。当初咱们在根模块调用这个子模块。代码如下:
module "local-file" { source = "./random-file" prefix = "pkslow" content = "Hi guys, this is www.pkslow.com\nBest wishes!"}
这个source是被调用模块的地址。prefix
和content
都是入参,之前曾经定义了。
在根模块也能够定义输入变量:
output "fileName" { value = module.local-file.file_name}
这里间接输入子模块的文件名,也就是子模块的返回变量file_name。
apply
后通过terraform output
查看输入:
$ terraform outputfileName = "./pkslow.B2UwmR.txt"
多个block调用同一个module
咱们说过模块是为了实现代码复用,Terraform容许一个模块被屡次调用。咱们批改根模块的调用代码:
module "pkslow-file" { source = "./random-file" prefix = "pkslow" content = "Hi guys, this is www.pkslow.com\nBest wishes!"}module "larry-file" { source = "./random-file" prefix = "larrydpk" content = "Hi guys, this is Larry Deng!"}
这里两个调用的source都是一样的,都调用了random-file
这个模块,只是入参不同。
根模块的输入也批改一下:
output "pkslowPileName" { value = module.pkslow-file.file_name}output "larryFileName" { value = module.larry-file.file_name}
执行apply
后output输入后果为:
$ terraform outputlarryFileName = "./larrydpk.txoV34.txt"pkslowPileName = "./pkslow.WnJVMm.txt"
循环调用一个module
count形式
屡次调用一个模块还有另一种形式就是循环调用,通过count
来实现,具体如下:
module "pkslow-file" { count = 6 source = "./random-file" prefix = "pkslow-${count.index}" content = "Hi guys, this is www.pkslow.com\nBest wishes!"}
这里会调用6次子模块random-file
,下标索引为count.index
,它是从0开始的索引。
因而,执行后,会生成以下6个文件:
pkslow-0.JBDuhH.txtpkslow-1.Z6QmPV.txtpkslow-2.PlCK5u.txtpkslow-3.a70sWN.txtpkslow-4.UnxYue.txtpkslow-5.8bSNxg.txt
这里根模块的输入就须要批改了,它成了一个List,通过*
援用所有元素:
output "pkslowPileNameList" { value = module.pkslow-file.*.file_name}
for each形式
通过for_each
也能够实现循环调用:
Map的状况:
resource "azurerm_resource_group" "rg" { for_each = { a_group = "eastus" another_group = "westus2" } name = each.key location = each.value}
Set的状况:
resource "aws_iam_user" "the-accounts" { for_each = toset( ["Todd", "James", "Alice", "Dottie"] ) name = each.key}
援用内部模块
除了在本我的项目中定义并援用模块之外,还能够援用内部的模块。在官网的仓库中曾经有十分多的可重用的模块了,能够到下面查找:https://registry.terraform.io...
比方我援用了( https://registry.terraform.io... )这个模块:
module "echo-larry-result" { source = "matti/resource/shell" version = "1.5.0" command = "cat ${module.larry-file.file_name}"}
执行terraform get
会从仓库下载模块:
$ terraform getDownloading matti/resource/shell 1.5.0 for echo-larry-result...- echo-larry-result in .terraform/modules/echo-larry-result- larry-file in random-file- pkslow-file in random-file
在.modules
目录下能够查看模块内容。
这个模块能够执行shell命令,并返回后果。我这里执行的命令是读取之前生成文件的内容。输入调用后果:
output "larryFileResult" { value = module.echo-larry-result.stdout}
执行后果如下:
larryFileName = "./.result/larrydpk.GfgMyh.txt"larryFileResult = "Hi guys, this is Larry Deng!"
模块起源
引入模块的起源很多:
- 本地目录
- Terraform官网仓库
- GitHub或其它Git仓库
- Bitbucket
- HTTP URLs
- S3 Buckets
- GCS Bucket
十分不便。咱们曾经介绍过比拟罕用的前两种了,其它更多细节能够参考:https://www.terraform.io/docs...