《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是被调用模块的地址。prefixcontent都是入参,之前已经定义了。

在根模块也可以定义输出变量:

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

《Terraform 101 从入门到实践》 第三章 Modules模块化的更多相关文章

  1. Python:从入门到实践--第三章--列表简介--练习

    #1.将一些朋友的姓名存储在一个列表中,并将其命名为friends.依次访问该列表中的每个元素,从而将每个朋友的姓名都打印出来. #2.继续使用1中的列表,为每人打印一条消息,每条消息包含相同的问候语 ...

  2. #Python编程从入门到实践#第三章笔记

      列表简介 ​​​1.什么是列表 列表:由一系列按也顶顺序排列的元素组成.元素之间可以没有任何关系. 列表:用方括号[]表示,并用逗号分隔其中元素.名称一般为复数 2.访问元素 (1)列表是有序集合 ...

  3. python 从入门到实践 第三章

    在第3章,你将学习如何在被称为列表的变量中存储信息集,以及如何通过遍历列表来操作其中的信息 写注释 # 代码越长 标识好代码的重要性 越来越重要要求习惯:在代码中编写清晰,简洁的注释开始研究更复杂的主 ...

  4. #Python编程从入门到实践#第四章笔记

    #Python编程从入门到实践#第四章笔记   操作列表 ​​​1.遍历列表 使用for循环,遍历values列表 for value in values: print(value) 2.数字列表 使 ...

  5. ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区 1 软件安装 1.1 安装前准备 请确认已经收到来自Esri中国( ...

  6. D3.js的v5版本入门教程(第三章)—— 选择元素和绑定数据

    D3.js的v5版本入门教程(第三章) 在D3.js中,选择元素和绑定元素是最基本的内容,也是很重要的内容,等你看完整个教程后你会发现,这些D3.js教程都是在选择元素和绑定元素的基础上展开后续工作的 ...

  7. python编程:从入门到实践----第六章>字典

    一.一个简单的字典:alien_0存储外星人的颜色和点数,使用print打印出来 alien_0 = {'color': 'green','points': 5} print(alien_0['col ...

  8. python编程:从入门到实践----第五章>if 语句

    一.一个简单示例 假设有一个汽车列表,并想将其每辆汽车的名称打印出来.遇到汽车名‘bmw’,以全大写打印:其他汽车名,首字母大写 cars=['audi','bmw','subaru','toyota ...

  9. python编程:从入门到实践----第四章>操作列表

    一.遍历整个列表 1-1.假设有一个魔术师名单,需要将其中每个魔术师的名字都打印出来. # 用for循环来打印魔术师名单中的名字 magicians=['alice','david','carolin ...

  10. Docker 入门到实践(三)Docker 安装

    注意:不要在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker. 一.准备工作 系统要求 Docker CE 支持一下版本的 Ubuntu 操作系统 Cosmic 18 ...

随机推荐

  1. Java安全之反序列化(1)

    序列化与反序列化 概述 Java序列化是指把Java对象转换为字节序列的过程:这串字符可能被储存/发送到任何需要的位置,在适当的时候,再将它转回原本的 Java 对象,而Java反序列化是指把字节序列 ...

  2. 洛谷P4168 蒲公英 分块处理区间众数模板

    题面. 许久以前我还不怎么去机房的时候,一位大佬好像一直在做这道题,他称这道题目为"大分块". 其实这道题目的思想不只可以用于处理区间众数,还可以处理很多区间数值相关问题. 让我们 ...

  3. Web安全Day1 - SQL注入、漏洞类型

    Web安全Day1 - SQL注入.漏洞类型 1. SQL注入 1.1 漏洞简介 1.2 漏洞原理 1.3 漏洞危害 2. SQL漏洞类型 2.1 区分数字和字符串 2.2 内联SQL注入 2.3 报 ...

  4. webrtc编译,不使用内置boringssl,使用openssl的

    前言 在项目开发过程中,会遇到使用https.TLS.DTLS等场景,这些第三方库一般会使用openssl作为加密套件.例如,qt中加密套件就会使用openssl,但是webrtc会默认使用borin ...

  5. [C# 中的序列化与反序列化](.NET 源码学习)

    [C# 中的序列化与反序列化](.NET 源码学习) 关键词:序列化(概念与分析)    三种序列化(底层原理 源码)    Stream(底层原理 源码)    反射(底层原理 源码) 假如有一天我 ...

  6. 基于echarts的带流动光效的折线图-lowline-for-echarts使用记录

    起源 在技术群看到有人问这个react插件,带着好奇心看了一下. 标题:基于echarts的带流动光效的折线图 - 掘金 网址:https://juejin.cn/post/7090566240233 ...

  7. 教你用JavaScript实现随机点名

    案例介绍 欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用JavaScript相关知识,做一个随机点名的案例.你可以通过点击开始按钮控制上方名字的闪动,点击停止按钮可以随机选定一个名 ...

  8. 【Java SE】Day02 数据类型转换、运算符、方法入门

    一.数据类型转换 1.自动转换 取值范围小在运算时会提升为取值范围大的类型 byte+int=int int+double=double 转换规则:byte.short.char-->int-- ...

  9. 【大数据-课程】高途-天翼云侯圣文-Day1:互联网大数据揭秘(大数据介绍&MR实现双十一举牌)

    一.大厂职级 P7:年薪百万 二.大数据发展 1.职业路线和岗位角色 2.大数据行业发展 三.大数据的位置 1.热门行业 大数据承上启下 2.三者关系 啤酒和尿不湿:启发可以放在一块 3.大数据作用 ...

  10. 【离线数仓CDH版本】即席查询工具(Presto、Druid、Kylin)、CDH数仓、Impala查询

    1.即席查询 一.Presto 大数据量.秒级.多数据源的查询引擎[支持各种数据源work的内存级查询] 由coordinator和多个work构成,work对应不同数据源Catalog 特点:基于内 ...