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

Posted

技术标签:

【中文标题】动态/静态资源映射(Terraform)【英文标题】:Dynamic/Static Resource Mapping (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
        
      
    
  

任何帮助都会很棒。

【问题讨论】:

【参考方案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。

【讨论】:

以上是关于动态/静态资源映射(Terraform)的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot自定义静态资源映射

SpringBoot web静态资源映射

springboot静态资源文件的映射

SpringBoot2---静态资源映射规则

SpringBoot:静态资源映射定制404配置icon

5.对静态资源映射的规则