首页IT科技terribly中文翻译(《Terraform 101 从入门到实践》 第三章 Modules模块化)

terribly中文翻译(《Terraform 101 从入门到实践》 第三章 Modules模块化)

时间2025-08-05 06:43:36分类IT科技浏览7569
导读:《Terraform 101 从入门到实践》这本小册在南瓜慢说官方网站和GitHub两个地方同步更新,书中的示例代码也是放在GitHub上,方便大家参考查看。...

《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 output fileName = "./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 output larryFileName = "./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.txt pkslow-1.Z6QmPV.txt pkslow-2.PlCK5u.txt pkslow-3.a70sWN.txt pkslow-4.UnxYue.txt pkslow-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/browse/modules

比如我引用了( https://registry.terraform.io/modules/matti/resource/shell/latest )这个模块:

module "echo-larry-result" { source = "matti/resource/shell" version = "1.5.0" command = "cat ${module.larry-file.file_name}" }

执行terraform get会从仓库下载模块:

$ terraform get Downloading 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/language/modules/sources.html

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
java中引用的概念(Java方法引用)