命名约定
至少应该没有理由不遵循这些约定 :)
请注意,实际的云资源通常对允许的名称有限制。 例如,有些资源不能包含破折号,有些资源必须采用驼峰式大小写。 本书中的约定指的是 Terraform 名称本身。
- 1.在任何地方(资源名称、数据源名称、变量名称、输出等)使用
_
(下划线) 而不是-
(破折号)。 - 2.非常适合使用小写字母和数字(即使支持 UTF-8)。
- 1.不要在资源名称中重复资源类型(既不要部分,更不要完全):
resource "aws_route_table" "public" {}
resource "aws_route_table" "public_route_table" {}
resource "aws_route_table" "public_aws_route_table" {}
- 2.如果没有更多的描述性和通用名称可用,或者如果资源模块创建这种类型的单个资源,资源名称应该被命名为
this
(例如,在AWS VPC module 中有一个类型为aws_nat_gateway
的资源和多个类型为aws_route_table
的资源,所以aws_nat_gateway
应该命名为this
,并且aws_route_table
应该有更具描述性的名称——比如private
,public
,database)
。 - 3.始终使用单数名词作为名称。
- 4.在参数值内部和值将显示给人类的地方,使用
-
(例如,在 RDS 实例的 DNS 名称内部)。 - 5.将参数
count
/for_each
包含在资源或数据源块中作为顶部的第一个参数,并在其后用换行符分隔。 - 6.包括参数
tags,
如果资源支持,作为最后一个真正的参数,如果需要,后面是depends_on
和lifecycle
。所有这些都应该用一个空行分隔。 - 7.
在参数count
/for_each
中使用条件时,首选布尔值而不是使用length
或其他表达式。
main.tf
resource "aws_route_table" "public" {
count = 2
vpc_id = "vpc-12345678"
# ... remaining arguments omitted
}
resource "aws_route_table" "private" {
for_each = toset(["one", "two"])
vpc_id = "vpc-12345678"
# ... remaining arguments omitted
}
main.tf
resource "aws_route_table" "public" {
vpc_id = "vpc-12345678"
count = 2
# ... remaining arguments omitted
}
main.tf
resource "aws_nat_gateway" "this" {
count = 2
allocation_id = "..."
subnet_id = "..."
tags = {
Name = "..."
}
depends_on = [aws_internet_gateway.this]
lifecycle {
create_before_destroy = true
}
}
main.tf
resource "aws_nat_gateway" "this" {
count = 2
tags = "..."
depends_on = [aws_internet_gateway.this]
lifecycle {
create_before_destroy = true
}
allocation_id = "..."
subnet_id = "..."
}
outputs.tf
resource "aws_nat_gateway" "that" { # Best
count = var.create_public_subnets ? 1 : 0
}
resource "aws_nat_gateway" "this" { # Good
count = length(var.public_subnets) > 0 ? 1 : 0
}
- 1.不要在资源模块中重新造轮子:使用你正在使用的资源的“参数参考”部分中定义的变量
name,description
和default
。 - 2.对变量验证的支持相当有限(例如,无法访问其他变量或进行查找)。 相应地计划,因为在许多情况下此功能是无用的。
- 3.当type是
list(...)
或map(...)
,在变量名中使用复数形式。 - 4.在变量块中排序键,比如:
description
,type
,default
,validation
。 - 5.始终包括对所有变量的
description
,即使你认为它很明显(将来你会需要它)。 - 6.优先使用简单类型(
number
,string
,list(...)
,map(...)
,any
) 而不是像object()
这样的特定类型,除非您需要对每个键都有严格的约束。 - 7.如果map的所有元素都具有相同的类型(例如
string
)或可以转换为它(例如number
类型可以转换为string
),则使用特定类 型,如map(map(string))
。 - 8.使用类型
any
来禁用从某个深度开始或者在支持多个类型时的类型验证。 - 9.值
{}
有时是一个map,有时是一个对象。使用tomap(...)
制作map,因为没有办法制作对象。
使输出在其范围之外保持一致且易于理解(当用户使用模块时,它返回的值的类型和属性应该很明显)。
- 1.输出的名称应该描述它包含的属性,并且不像你通常想要的那样自由。
- 2.输出名称的良好结构类似于
{name}_{type}_{attribute}
,其中:- 1.
{name}
是没有提供者前缀的资源或数据源名称。aws_subnet
的{name}是subnet
,aws_vpc
的{name}
是vpc
- 2.
{type}
是一种资源来源 - 3.
{attribute}
是输出返回的属性 - 4.
- 3.
- 4.
- 5.始终包括所有输出的
description
,即使你认为它很明显。 - 6.避免设置
sensitive
参数, 除非您完全控制此输出在所有模块的所有位置的使用。 - 7.更喜欢
try()
(自 Terraform 0.13 起可用)而不是element(concat(...))
(0.13 之前版本的旧方法)。
最多返回一个安全组ID:
outputs.tf
output "security_group_id" {
description = "The ID of the security group"
value = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
}
当有多个相同类型的资源时,
this
在输出名称中应省略:outputs.tf
output "this_security_group_id" {
description = "The ID of the security group"
value = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
}
outputs.tf
output "rds_cluster_instance_endpoints" {
description = "A list of all cluster instance endpoints"
value = aws_rds_cluster_instance.this.*.endpoint
}
Last modified 1mo ago