首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态/静态资源映射(Terraform)

动态/静态资源映射(Terraform)
EN

Stack Overflow用户
提问于 2021-08-29 12:51:01
回答 2查看 196关注 0票数 0

在弄清楚一些事情上有困难,并想在这里的社区中运行它。这可能是直截了当的,我正在努力寻找答案。

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

我使用局部变量映射来建立一些使用其他变量的变量,所以variables.tf并不是很合适。我的主要问题由?如下所示。

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

代码语言:javascript
运行
复制
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 = ??????
      }
    }
  }

我在想像这样的事情?是的,我知道语法是无效的,只是给出了一个想法,我试图在没有完全理解如何做到这一点的情况下完成。

代码语言:javascript
运行
复制
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
        }
      }
    }
  }

任何帮助都是最好的。

EN

回答 2

Stack Overflow用户

发布于 2021-08-29 14:23:50

您可以尝试设置each.key

下面是一个例子

代码语言:javascript
运行
复制
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)

票数 0
EN

Stack Overflow用户

发布于 2021-08-30 17:16:14

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

代码语言:javascript
运行
复制
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.keys中的查找关键字,或者更改为null,以指示该存储桶没有任何关键字。

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

代码语言:javascript
运行
复制
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都很有帮助,Terraform可以看到它应该期望在添加/删除别名的同时添加/删除它们的键。

然后剩下S3存储桶和它们与上面声明的KMS密钥的可选连接:

代码语言:javascript
运行
复制
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块。这也对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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68973076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档