使用terraform for loop编写干式代码?

使用terraform for loop编写干式代码?,terraform,Terraform,我对terraform非常陌生,有一项任务落在我身上,要我创建2个AWS KMS密钥。 因此,我正在这样做: resource "aws_kms_key" "ebs_encryption_key" { description = "EBS encryption key" ... omitted for brevity ... tags = merge(map( "Name

我对terraform非常陌生,有一项任务落在我身上,要我创建2个AWS KMS密钥。 因此,我正在这样做:

resource "aws_kms_key" "ebs_encryption_key" {
  description              = "EBS encryption key"
  ... omitted for brevity ...

  tags = merge(map(
        "Name", format("%s-ebs-encryption-key", var.name_prefix),
        "component", "kms",
        "dataclassification","low",
        ), var.extra_tags)
}

resource "aws_kms_alias" "ebs_encryption_key" {
  name                 = format("alias/%s-ebs-encryption-key", var.name_prefix)
  target_key_id        = aws_kms_key.ebs_encryption_key.key_id
}

# Repeated code!
resource "aws_kms_key" "rds_encryption_key" {
  description              = "RDS encryption key"
  ... omitted for brevity ...

  tags = merge(map(
        "Name", format("%s-rds-encryption-key", var.name_prefix),
        "component", "kms",
        "dataclassification","low",
        ), var.extra_tags)
}

resource "aws_kms_alias" "rds_encryption_key" {
  name                 = format("alias/%s-rds-encryption-key", var.name_prefix)
  target_key_id        = "${aws_kms_key.rds_encryption_key.key_id}"
}
正如您所看到的,这两个代码块之间的唯一区别是ebs和rds?
如何使用for循环来避免重复代码块?

这似乎是一个小型模块的候选,该模块封装了声明密钥和关联别名的详细信息,因为密钥和别名通常在系统中一起声明

模块本身看起来像这样:

variable "name" {
  type = string
}

variable "description" {
  type = string
}

variable "tags" {
  type = map(string)
}

resource "aws_kms_key" "main" {
  description = var.description
  # ...

  tags = var.tags
}

resource "aws_kms_alias" "main" {
  name          = "alias/${var.name}"
  target_key_id = aws_kms_key.main.key_id
}

output "key_id" {
  value = aws_kms_key.main.key_id
}

output "alias_name" {
  value = aws_kms_alias.main.name
}
正如在这里写的,这个模块感觉有点傻,因为这里没有太多的东西不是仅仅从变量中派生出来的,但是我假设在你的例子中,为了简洁起见,你想要避免重复的有趣的东西被省略了,这将代替。。。在我的例子中

然后,调用模块可以包含一个模块块,每个模块块使用_创建模块的两个实例,系统地设置参数以填充其输入变量:

module "kms_key" {
  for_each = {
    kms = "KMS"
    ebs = "EBS"
  }

  name        = "${var.name_prefix}-${each.key}-encryption-key"
  description = "${each.value} Encryption Key"
  tags = merge(
    var.extra_tags,
    {
      Name               = "${var.name_prefix}-${each.key}-encryption-key"
      component          = "kms"
      dataclassification = "low"
    },
  )
}
由于此处的for_each map具有密钥kms和ebs,因此其结果将是声明资源实例,该实例在计划中应具有以下地址:

module.kms\u key[kms].aws\u kms\u key.main module.kms\u key[kms].aws\u kms\u alias.main module.kms\u key[ebs].aws\u kms\u key.main module.kms\u key[ebs].aws\u kms\u alias.main 由于它们由映射键标识,因此将来可以向该映射添加新的键,以创建新的键/别名对,而不会干扰现有的键/别名对

如果需要在调用模块的其他位置使用密钥ID或别名,则可以通过该调用模块的module.kms_key中公开的输出访问它们:

module.kms\u key[kms].key\u id module.kms\u key[kms]。别名\u name module.kms\u key[ebs].key\u id module.kms\u key[ebs]。别名\u name
这似乎是一个小型模块的候选,该模块封装了声明密钥和关联别名的详细信息,因为密钥和别名通常在系统中一起声明

模块本身看起来像这样:

variable "name" {
  type = string
}

variable "description" {
  type = string
}

variable "tags" {
  type = map(string)
}

resource "aws_kms_key" "main" {
  description = var.description
  # ...

  tags = var.tags
}

resource "aws_kms_alias" "main" {
  name          = "alias/${var.name}"
  target_key_id = aws_kms_key.main.key_id
}

output "key_id" {
  value = aws_kms_key.main.key_id
}

output "alias_name" {
  value = aws_kms_alias.main.name
}
正如在这里写的,这个模块感觉有点傻,因为这里没有太多的东西不是仅仅从变量中派生出来的,但是我假设在你的例子中,为了简洁起见,你想要避免重复的有趣的东西被省略了,这将代替。。。在我的例子中

然后,调用模块可以包含一个模块块,每个模块块使用_创建模块的两个实例,系统地设置参数以填充其输入变量:

module "kms_key" {
  for_each = {
    kms = "KMS"
    ebs = "EBS"
  }

  name        = "${var.name_prefix}-${each.key}-encryption-key"
  description = "${each.value} Encryption Key"
  tags = merge(
    var.extra_tags,
    {
      Name               = "${var.name_prefix}-${each.key}-encryption-key"
      component          = "kms"
      dataclassification = "low"
    },
  )
}
由于此处的for_each map具有密钥kms和ebs,因此其结果将是声明资源实例,该实例在计划中应具有以下地址:

module.kms\u key[kms].aws\u kms\u key.main module.kms\u key[kms].aws\u kms\u alias.main module.kms\u key[ebs].aws\u kms\u key.main module.kms\u key[ebs].aws\u kms\u alias.main 由于它们由映射键标识,因此将来可以向该映射添加新的键,以创建新的键/别名对,而不会干扰现有的键/别名对

如果需要在调用模块的其他位置使用密钥ID或别名,则可以通过该调用模块的module.kms_key中公开的输出访问它们:

module.kms\u key[kms].key\u id module.kms\u key[kms]。别名\u name module.kms\u key[ebs].key\u id module.kms\u key[ebs]。别名\u name
谢谢你的回答。还有一个问题。我需要ebs密钥从模块输出,作为参数传递给另一个模块。输出子句是什么样子的?谢谢你的回答。还有一个问题。我需要ebs密钥从模块输出,作为参数传递给另一个模块。输出子句是什么样子的?