Terragrunt通过for_each循环导入资源



我正在用for_each循环创建一个GCP桶,并希望将现有桶导入到我的地形状态

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# google_storage_bucket.buckets["a-test-test-test"] will be created
+ resource "google_storage_bucket" "buckets" {
+ bucket_policy_only          = (known after apply)
+ force_destroy               = false
+ id                          = (known after apply)
+ location                    = "US"
+ name                        = "a-test-test-test"
+ project                     = "xxx"
+ self_link                   = (known after apply)
+ storage_class               = "STANDARD"
+ uniform_bucket_level_access = false
+ url                         = (known after apply)
+ versioning {
+ enabled = true
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
~ urls = [
- "gs://a-test-test-test",
+ (known after apply),
]
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
google_storage_bucket.buckets["a-test-test-test"]: Creating...
Error: googleapi: Error 409: You already own this bucket. Please select another name., conflict

资源已经存在但没关系,我可以直接导入,问题是如何

因为像这样运行

MacBook-Pro% terragrunt import google_storage_bucket.buckets a-test-test-test
...
Acquiring state lock. This may take a few moments...
google_storage_bucket.buckets: Importing from ID "a-test-test-test"...
google_storage_bucket.buckets: Import prepared!
Prepared google_storage_bucket for import
google_storage_bucket.buckets: Refreshing state... [id=a-test-test-test]
Import successful!

似乎可以工作,但是它错误地导入了

terragrunt state list
...
google_storage_bucket.buckets

显示在我的状态,但它应该是这样的

google_storage_bucket.buckets["a-test-test-test"]

因为如果我现在运行apply -它说要删除google_storage_bucket.buckets并创建google_storage_bucket.buckets["a-test-test-test"]

google_storage_bucket.buckets: Refreshing state... [id=a-test-test-test]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# google_storage_bucket.buckets will be destroyed
- resource "google_storage_bucket" "buckets" {
- bucket_policy_only          = false -> null
- default_event_based_hold    = false -> null
- force_destroy               = false -> null
- id                          = "a-test-test-test" -> null
- labels                      = {} -> null
- location                    = "US" -> null
- name                        = "a-test-test-test" -> null
- project                     = "xxx" -> null
- requester_pays              = false -> null
- self_link                   = "https://www.googleapis.com/storage/v1/b/a-test-test-test" -> null
- storage_class               = "STANDARD" -> null
- uniform_bucket_level_access = false -> null
- url                         = "gs://a-test-test-test" -> null
- versioning {
- enabled = true -> null
}
}
# google_storage_bucket.buckets["a-test-test-test"] will be created
+ resource "google_storage_bucket" "buckets" {
+ bucket_policy_only          = (known after apply)
+ force_destroy               = false
+ id                          = (known after apply)
+ location                    = "US"
+ name                        = "a-test-test-test"
+ project                     = "xxx"
+ self_link                   = (known after apply)
+ storage_class               = "STANDARD"
+ uniform_bucket_level_access = false
+ url                         = (known after apply)
+ versioning {
+ enabled = true
}
}
Plan: 1 to add, 0 to change, 1 to destroy.
Changes to Outputs:
+ urls = [
+ (known after apply),
]
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

有关于如何导入到terragrunt中的for_each的想法吗?

我试过

terragrunt import google_storage_bucket.buckets a-test-test-test
terragrunt import google_storage_bucket.buckets.a-test-test-test a-test-test-test
terragrunt import google_storage_bucket.buckets["a-test-test-test"] a-test-test-test
terragrunt import google_storage_bucket.buckets["a-test-test-test"] a-test-test-test

和noone工作只是留下我与错误

zsh: no matches found: google_storage_bucket.buckets["a-test-test-test"]

,而第一个选项terragrunt import google_storage_bucket.buckets a-test-test-test,导入(即。工作),但不是正确的方式


地形代码如下:

inputs = {
project_id  = "${local.project_id}"
{
name                        = "a-test-test-test"
location                    = "US"
}
}
locals {
buckets        = {for b in jsondecode(var.buckets) : b.name => b }
}
variable "buckets" {
description = "The name of the bucket."
}
resource "google_storage_bucket" "buckets" {
for_each      = local.buckets
name          = each.key
project       = var.project_id
location      = each.value.location

导入完整的实例地址(包括实例键索引部分)是正确的方法,但这里的技巧是确定绕过shell语法的最佳方法,以便必要的字符可以到达Terraform。

对于unix风格的shell,我通常建议将地址放在单引号中以禁用元字符解释,如:

terragrunt import 'google_storage_bucket.buckets["a-test-test-test"]' a-test-test-test

我对zsh没有太多的经验,但是从参考其部分文档的副本中,我得到的印象是,上面的zsh语法也是有效的。如果上面的方法不起作用,可能值得尝试使用不同的shell,例如bash,看看是否会得到不同的结果。

虽然你特别提到了zsh,但为了完整起见,我还会注意到在Windows上的规则略有不同:在传统的Windows命令行语法下不支持单引号,因此不幸的是,我们必须在Windows命令提示符中运行Terraform时转义引号:

terragrunt import google_storage_bucket.buckets["a-test-test-test"] a-test-test-test
重要的是地址中的引号字符"通过shell传递给Terraform,这样Terraform就可以成功地将参数解析为资源地址语法。

我使用Terraform模块内的数据来避免从Terragrunt调用变量的问题在main.tf

data "azurerm_resource_group" "k8s" {
name = var.resource_group_name
}

在terragrunt.hcl

resource_group_name = "rgpazewsmlit-sandbox-xxxxx"

最新更新