模块 — 边界比复用更靠前
一句话总结
模块不是缩短代码的装置,而是限制变化扩散的半径的装置。
为什么需要这个?
假设把同一堆栈制作成dev·stage·prod。一开始复制三套目录最快。实际上很快。问题是6个月后。在prod中急忙放的一个设置在dev中没有,在stage中有一半放进去。三套目录现在变成了各自不同的生物,要找到“只有在prod中出现的问题”的原因,必须把三张文件并排放在一起diff。
在这里,真的不可能认为成本是重复的。必须改变三次的事实,以及即使错过三次中一次也不会有人知道的事实。模块将这个问题颠覆为“实现是一套,输入只有三套”。那么,改变就发生在一个地方,环境之间的差异不是代码,而是通过值表现出来。
怎么行动
模块就是这样.tf是包含文件的目录。没有特殊的语法,只有惯例。
| 文件 | 角色 |
|---|---|
variables.tf |
这个模块接收的输入。模块的公开API |
main.tf |
实现。在外面不能看到的部分 |
outputs.tf |
向外输出的值。模块的返回值 |
分为三个文件的原因不是因为喜好,而是阅读顺序。第一次看到别人的模块时,人们想知道的是“放什么会得到什么”,实现是其次。
有四种记忆的性格。
**第一,模块是胶囊。**模块内的资源不能从外面直接引用。module.primary.local_file.box.filename没有相同的地址。要把值拿出来,必须output必须通过。虽然看起来很麻烦,但多亏了这个限制,即使更改模块内的资源名称也不会破坏使用它的一方。
**第二,地址变了。**模块内资源的状态地址在module.<호출이름>.附加前缀。叠加的话module.bundle.module.left.local_file.box像这样不断积累。重组即意味着地址变更这一事实与3部作品的状态手术联系起来。
第三,提供商注入根。在子模块内provider如果放置块,使用该模块的一方无法更改提供商设置,更糟糕的是无法在代码中删除该模块调用。要破坏资源需要提供商设置,因为该设置存在于消失的模块中。所以模块中required_providers只留万,实际设置放在根目录。
第四,多次调用同一个源代码。 如果想增加实例,复制模块目录,就会回到最初的复制问题。module "primary"哇module "secondary"像一样source只改变名字来呼叫才是正确答案。
在现场相遇的样子
**第一,分组的标准是“一起变吗”。**按资源种类分组的话(都是vpc模块,都是iam模块)表面上看起来很整洁,但实际的变更总是发生在多个模块上。应该把一起出生一起死亡的东西束缚在一个模块里。状态文件的分组标准也一样——爆炸半径和apply时间是标准,而不是文件夹美学。
**第二,验证在模块边界进行最便宜。**如果错误值进入模块内,错误会从下面的资源中产生。variable的validation用块在入口处阻止的话,错误信息上会直接写上“哪个模块的哪个变量为什么被拒绝”。调试时间会相差好几倍。
**第三,模块有版本。**本地相对路径在学习和单个存储库中方便,但如果是多个团队使用的模块,就需要注册表和版本固定。否则,别人的一个提交会改变我们的prod计划。
什么时候制作模块,隐藏到哪里?
虽然学习说模块是为了重复使用而制作的,但实际上当出现第二个使用场所时 制作是正确的。只在一个地方使用的模块只会让你打开一个文件。
**制作得早的模块一定被错误抽象化。**只知道第一个使用处的要求就制作了。 因为这个原因。如果出现第二个使用处,增加一个变量,在第三个又增加一个,然后 变量成为四十个个人模块。那个时刻的模块没有隐藏的东西,所以存在。 没有理由。
**好的模块包含决定。**不是束缚资源,而是“在我们组织中这种类型的 应该包含“这样做”的判断。开启加密,将日志发送到哪里, 标签这样贴上,决定备份几天,在外面只贴几个。 暴露。
变量越少越好,只让通过的变量就不好。 里面的资源属性保持原样 如果向外发送的变量很多的话,那个模块就是薄壳。那样的话,把模块 删除并直接使用资源比较容易阅读。
固定并上传版本。用注册表或git标签抓住版本,使用处是那个
明确版本。ref=main放在那里的话,在修改模块的瞬间没有人计划的
变更会传播到所有使用处。
module "db" {
source = "git::https://git.example.com/tf-modules.git//rds?ref=v2.3.0"
...
}
**叠加最多到两个阶段。**如果变成模块内的模块内的模块,哪个变量会到哪里 没有人能追踪是否被传递。超过价格的代码只会增加,计划 读的时候,资源地址变长了,看不到有什么变化。
输出是合同。因为使用者依赖于该输出,所以如果改名字,所有使用者都会 破碎。只拿出必要的东西,名字不是内心的实现,而是外面的意义。 做。
下次实习要做的事情
filebox将这样的小子模块输入、实现、输出三个文件,将相同的源代码primary·secondary用两个名字呼叫。直接确认模块内资源的状态地址如何变化,在模块内建立再次呼叫模块的嵌套结构。最后通过变量验证在模块边界拒绝错误的值,将三个模块的输出汇总成一个地图。