地图资源的 Terraform 导入

Posted

技术标签:

【中文标题】地图资源的 Terraform 导入【英文标题】:Terraform Import of map resources 【发布时间】:2021-12-06 13:20:03 【问题描述】:

我有一个标识现有 s3 存储桶的映射变量:

resource "aws_s3_bucket" "bucket" 
  for_each = var.s3_replication
  bucket   = each.value.source
  #other configuration


variable "s3_replication" 
  description = "Map of buckets to replicate"
  type        = map
  default = 
    logs = 
      source = "logs_bucket",
      destination = "central_logs_bucket"
    ,
    security = 
      source = "cloudtrail_bucket",
      destination = "central_security_bucket"
    
  

由于这些存储桶已经存在,我正在尝试导入它们,然后将配置应用到它们以更新资源。不幸的是,我无法弄清楚如何对这些进行 terraform 导入。我试过了:

terraform import aws_s3_bucket.bucket["logs"] logs_bucket
terraform import aws_s3_bucket.bucket[logs] logs_bucket
terraform import aws_s3_bucket.bucket[0] logs_bucket
terraform import aws_s3_bucket.bucket[0].source logs_bucket
terraform import aws_s3_bucket.bucket[0[source]] logs_bucket

所有失败并出现不同的错误。关于如何导入地图上列出的现有资源的任何想法?

【问题讨论】:

【参考方案1】:

terraform import 子命令依赖于资源命名空间内映射键中的字符串,这些字符串是第一类表达式,这会导致 shell 解释器出现问题,其中资源不是第一类表达式,因为它们不是 Terraform DSL。您可以通过将整个资源名称转换为文字字符串来解决此问题:

terraform import 'aws_s3_bucket.bucket["logs"]' logs_bucket

这将解决您的问题。

【讨论】:

这需要以某种方式定位“源”吗?看起来它仍在出错:错误: 第 1 行的表达式无效:(源代码不可用)预期表达式的开头,但找到了无效的表达式标记。错误:variables.tf 第 18 行所需变量没有值:18:变量“s3_replication” 未设置根模块输入变量“s3_replication”,并且没有默认值。使用 -var 或 -var-file 命令行参数为该变量提供值。 谢谢,你的语法是正确的,我只需要 -var-file=path 指向 tfvars 文件【参考方案2】:

在进行 import 之前,我建议先进行 terraform plan。计划的输出如下所示:

Terraform will perform the following actions:

  # aws_s3_bucket.bucket["logs"] will be created
  + resource "aws_s3_bucket" "bucket" 
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "logs_bucket"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + versioning 
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        
    

  # aws_s3_bucket.bucket["security"] will be created
  + resource "aws_s3_bucket" "bucket" 
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "cloudtrail_bucket"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + versioning 
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        
    

Plan: 2 to add, 0 to change, 0 to destroy.

有了这个计划,我们可以看到将要创建的资源可以引用为aws_s3_bucket.bucket["logs"]aws_s3_bucket.bucket["security"]。我们可以按如下方式导入它们,而不是 apply

重击:

terraform import 'aws_s3_bucket.bucket["security"]' cloudtrail-bucket
terraform import 'aws_s3_bucket.bucket["logs"]' logs-bucket

Windows CMD:

terraform import 'aws_s3_bucket.bucket[\"security\"]' cloudtrail-bucket
terraform import 'aws_s3_bucket.bucket[\"logs\"]' logs-bucket

【讨论】:

谢谢,这是正确的语法。我只是犯了丢失-var-file=path 的错误。添加解决了问题【参考方案3】:

发布的答案中的语法是正确的。我的代码只是因为找不到 varsfile 而出错。我需要添加 -var-file= path to tfvars 。所以最终的语法看起来像:

terraform import -var-file= path to tfvars 'aws_s3_bucket.bucket["logs"]' logs_bucket

【讨论】:

以上是关于地图资源的 Terraform 导入的主要内容,如果未能解决你的问题,请参考以下文章

存储在 aws 机密管理器中的 Azure 机密

Terraform - 迭代嵌套地图

Terraform 导入现有资源

将现有 Azure 资源导入本地 Terraform 状态文件

使用 Terraform 导入 Azure 上的现有资源

将现有资源导入 Terraform 状态文件时出错