命名约定

一般约定

至少应该没有理由不遵循这些约定 :)

请注意,实际的云资源通常对允许的名称有限制。 例如,有些资源不能包含破折号,有些资源必须采用驼峰式大小写。 本书中的约定指的是 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_onlifecycle。所有这些都应该用一个空行分隔。

  7. 在参数count / for_each中使用条件时,首选布尔值而不是使用 length或其他表达式。

resource(资源)代码示例

count / for_each的使用

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
}

tags(标签)的放置

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     = "..."
}

count(计数)条件

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
}

Variables(变量)

  1. 不要在资源模块中重新造轮子:使用你正在使用的资源的“参数参考”部分中定义的变量 name,descriptiondefault

  2. 对变量验证的支持相当有限(例如,无法访问其他变量或进行查找)。 相应地计划,因为在许多情况下此功能是无用的。

  3. 当type是list(...)map(...),在变量名中使用复数形式。

  4. 在变量块中排序键,比如:descriptiontypedefaultvalidation

  5. 始终包括对所有变量的description,即使你认为它很明显(将来你会需要它)。

  6. 优先使用简单类型(numberstringlist(...)map(...)any) 而不是像object()这样的特定类型,除非您需要对每个键都有严格的约束。

  7. 如果map的所有元素都具有相同的类型(例如string)或可以转换为它(例如number类型可以转换为string),则使用特定类型,如map(map(string))

  8. 使用类型any来禁用从某个深度开始或者在支持多个类型时的类型验证。

  9. {}有时是一个map,有时是一个对象。使用tomap(...) 制作map,因为没有办法制作对象。

Outputs(输出)

使输出在其范围之外保持一致且易于理解(当用户使用模块时,它返回的值的类型和属性应该很明显)。

  1. 输出的名称应该描述它包含的属性,并且不像你通常想要的那样自由。

  2. 输出名称的良好结构类似于{name}_{type}_{attribute},其中:

    1. {name}是没有提供者前缀的资源或数据源名称。aws_subnet{name}是subnetaws_vpc{name}vpc

    2. {type} 是一种资源来源

    3. {attribute}是输出返回的属性

    4. 参见示例 See examples.

  3. 如果输出返回一个带有插值函数和多个资源的值,{name}{type} 应该尽可能通用(this 作为前缀应该省略), 参见示例 See example

  4. 如果返回值是一个列表,它应该有一个复数名称。 参见示例 See example

  5. 始终包括所有输出的description,即使你认为它很明显。

  6. 避免设置sensitive参数, 除非您完全控制此输出在所有模块的所有位置的使用。

  7. 更喜欢try()(自 Terraform 0.13 起可用)而不是 element(concat(...))(0.13 之前版本的旧方法)。

output(输出)代码示例

最多返回一个安全组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 updated