【问题标题】:Dynamic/Static Resource Mapping (Terraform)动态/静态资源映射(Terraform)
【发布时间】:2021-10-28 13:18:15
【问题描述】:

无法解决问题并希望在此处由社区运行它。它可能是直截了当的,我正在努力寻找答案。

我正在创建 KMS 密钥、S3 存储桶、KMS 别名。

我正在使用本地映射来使用其他变量建立一些变量,因此 variables.tf 并不适合。我的主要问题是 ?????下面。

如何将一个资源映射到另一个资源中的特定返回值?因此,例如,某些存储桶上只会使用某些密钥。我将如何在资源中创建一个检查,以便仅为其创建的每个存储桶分配一个我想要的 KMS 密钥。

locals {
  buckets = {
    "1" = { 
      name    = "1", 
      kms_key = false 
    },
    "2" = { 
      name    = "2", 
      kms_key = false 
    },
    "3"     = { 
      name    = "3", 
      kms_key = false 
    },
    "4"     = { 
      name    = "4", 
      kms_key = false 
    },
    "5"        = { 
      name    = "5", 
      kms_key = false 
    },
    "6"          = { 
      name    = "6", 
      kms_key = false 
    }
  }
  keys = {
    "1"     = {
      description = "1"
      alias       = "alias/1-key"
    },
    "il5"      = {
      description = "2"
      alias       = "alias/2-key"
    },
    "ebs"      = {
      description = "3"
      alias       = "alias/3-key"
    }
  }
}

resource "aws_kms_key" "key" {
  for_each = local.keys

  description             = each.value.description
  enable_key_rotation     = true
  deletion_window_in_days = 30
}

resource "aws_kms_alias" "this" {
  for_each = local.keys

  name          = each.value.alias
  target_key_id = ??????
}

resource "aws_s3_bucket" "bucket" {
  for_each = local.buckets

  bucket = each.value.name
  acl    = "private"

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm     = "aws:kms"
        kms_master_key_id = ??????
      }
    }
  }

我在想这样的事情吗?是的,我得到语法是无效的,只是在没有完全理解如何做的情况下给出我想要完成的想法。

server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm     = "aws:kms"
        kms_master_key_id = {
            if this bucket = this key,
            if this bucket = this key,
            if this bucket = this key,
            etc
        }
      }
    }
  }

任何帮助都会很棒。

【问题讨论】:

    标签: amazon-web-services amazon-s3 terraform infrastructure-as-code


    【解决方案1】:

    你可以尝试设置each.key

    这是一个例子

    locals {
      buckets = {
        "1" = {
          name    = "1",
          kms_key = false
        },
        "2" = {
          name    = "2",
          kms_key = false
        }
      }
      keys = {
        "1" = {
          description = "1"
          alias       = "alias/1-key"
        },
        "2" = {
          description = "2"
          alias       = "alias/2-key"
        }
      }
    }
    
    resource "aws_kms_key" "key" {
      for_each = local.keys
    
      description             = each.value.description
      enable_key_rotation     = true
      deletion_window_in_days = 30
    }
    
    resource "aws_kms_alias" "this" {
      for_each = local.keys
    
      name          = each.value.alias
      target_key_id = aws_kms_key.key[each.key].id
    }
    
    resource "aws_s3_bucket" "bucket" {
      for_each = local.buckets
    
      bucket = each.value.name
      acl    = "private"
    
      server_side_encryption_configuration {
        rule {
          apply_server_side_encryption_by_default {
            sse_algorithm     = "aws:kms"
            kms_master_key_id = aws_kms_key.key[each.key].id
          }
        }
      }
    }
    

    它有效,但前提是 locals.bucketslocals.keys 具有相同的键名 (1,2,3,etc)

    【讨论】:

    • 不确定那会做我想做的事。本质上,我正在创建 6 个存储桶和 3 个 KMS 密钥/别名。仅将特定密钥分配给其中几个存储桶,并将另一个密钥分配给其他几个。只是不确定如何动态分配这些值并像那样动态映射它们。我宁愿不必为每个桶创建一个密钥,并将密钥静态分配给桶。
    【解决方案2】:

    我建议从稍微调整初始数据结构开始,以便桶和键之间的关系是明确的:

    locals {
      buckets = tomap({
        "1" = { 
          name    = "1" 
          kms_key = "1" 
        }
        "2" = { 
          name    = "2" 
          kms_key = null
        }
        "3" = { 
          name    = "3"
          kms_key = "il5"
        }
        "4" = { 
          name    = "4" 
          kms_key = null 
        }
        "5" = { 
          name    = "5" 
          kms_key = null
        }
        "6" = { 
          name    = "6" 
          kms_key = "ebs"
        }
      })
      keys = {
        "1"     = {
          description = "1"
          alias       = "alias/1-key"
        },
        "il5"      = {
          description = "2"
          alias       = "alias/2-key"
        },
        "ebs"      = {
          description = "3"
          alias       = "alias/3-key"
        }
      }
    }
    

    在这里,我将每个存储桶的kms_key 属性更改为local.keysnull 的查找键,以指示此存储桶根本没有键。

    KMS 密钥及其别名是使用chaining between resources 的好情况,这意味着将资源上表示的值用作另一个for_each

    resource "aws_kms_key" "key" {
      for_each = local.keys
    
      description             = each.value.description
      enable_key_rotation     = true
      deletion_window_in_days = 30
    }
    
    resource "aws_kms_alias" "this" {
      for_each = aws_kms_key.key
    
      name          = local.keys[each.key].alias
      target_key_id = each.value.id
    }
    

    以这种方式声明关系明确表明每个键应该有一个别名,这对人类(可以看到预期的关系)和 Terraform 都有帮助,它可以看到它应该期望添加别名/与他们的钥匙同时被移除。

    然后留下 S3 存储桶及其与上面声明的 KMS 密钥的可选连接:

    resource "aws_s3_bucket" "bucket" {
      for_each = local.buckets
    
      bucket = each.value.name
      acl    = "private"
    
      dynamic "server_side_encryption_configuration" {
        for_each = each.value.kms_key[*]
        content {
          rule {
            apply_server_side_encryption_by_default {
              sse_algorithm     = "aws:kms"
              kms_master_key_id = aws_kms_key.key[server_side_encryption_configuration.value].id
            }
          }
        }
      }
    }
    

    在这种情况下,我使用dynamic block 有条件地为具有非空kms_key 值的桶生成server_side_encryption_configuration 块。这也将[*] splat 运算符用于treat each.value.kms_key as if it were a list,它将为null 生成一个空列表或为非空字符串生成一个元素列表。

    content 块内,server_side_encryption_configuration.value 是来自for_each 的值,因此each.value.kms_key 直接是键名值。这些字符串应该与local.keys 中的键相关联,因此与aws_kms_key.key 中的键相关,因此我们可以为每个选定的键查找动态选择的ID。

    【讨论】:

      猜你喜欢
      • 2014-04-13
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多