英文:
Terraform depend existing module resource on newly created resources
问题
这可以看作是一个关于Terraform的“通用”问题。
我有一个模块(vm-instances)用于创建我的虚拟机。这个模块有一个名为boot_volume_key_id的变量,如果存在的话,它具有KMS密钥的id。如果设置了一个本地变量create_kms_key,则会在另一个配置文件中创建这个密钥。我正在使用新创建的KMS密钥来更新现有的boot_volume,为了将这个KMS密钥用于启动卷,我创建了一个管理启动卷的身份策略。oci_kms_key在oci_identity_policy的语句中被引用。例如,简化的配置文件如下:
kms.tf
resource "oci_kms_key" "boot_volume_key"{
  count = local.create_kms_key ? 1 : 0
  ...
}
resource "oci_identity_policy" "boot_volume"{
  count = local.create_kms_key ? 1 : 0
  ...
  statement =  [
     Allow ... where target.key.id = ${oci_kms_key.boot_volume_key.0.id}
  ]
}
main.tf
module "instances" {
  source = "./module/vm-instances"
  ...
  boot_volume =  local.create_kms_key ? oci_kms_key.boot_volume_key.0.id : null
}
问题:第一次terraform apply后,我得到了404-NotAuthorizedOrNotFound UpdateVolumeKMS,但在第二次应用后,它可以正常工作。我认为这是因为身份策略需要一些时间来“运行”。
我该如何避免这个问题?我已经看过了像depends_on和lifecycle元块中的ignore_changes等选项。
- 使用
depends_on的问题是,如果我让整个vm-instances模块依赖于身份策略,当我运行terraform plan时,似乎我的实例将被重新创建,这是我不想要的。 - 使用
lifecycle的ignore_changes的问题是,当我在配置文件中引入KMS密钥时,我的虚拟机将不会被更新。 - Terraform的
time_sleep会不必要地减慢Terraform配置。 
英文:
This can be viewed as a "generic" Terraform question.
I have a module (vm-instances) used to create my virtual machines. This module has a variable boot_volume_key_id, which has the id of the KMS key id if it exists. This key is created in another configuration file if a local variable create_kms_key is set.
I'm using the newly created KMS key to update the boot_volume of my exisiting, and in order to use this KMS key for the boot volume a identity policy for managing the boot volume is created. The oci_kms_key is referenced in a statment in the oci_identity_policy E.g simplified configuration files:
kms.tf
resource "oci_kms_key" "boot_volume_key"{
  count = local.create_kms_key ? 1 : 0
  ...
}
resource "oci_identity_policy" "boot_volume"{
  count = local.create_kms_key ? 1 : 0
  ...
  statement =  [
     Allow ... where target.key.id = ${oci_kms_key.boot_volume_key.0.id}
  ]
}
main.tf
module "instances" {
  source = "./module/vm-instances"
  ...
  boot_volume =  local.create_kms_key ? oci_kms_key.boot_volume_key.0.id : null
}
Problem: I get a 404-NotAuthorizedOrNotFound UpdateVolumeKMS after first terraform apply, however this works after second apply. I believe this is because the identity policy takes some time to be "functioning".
How can I avoid this problem? I've looked at options like depends_on and lifecycle-metablock ignore_changes.
- Problem with using 
depends_onis if I depend my entirevm-instancesmodule on the identity policy, when I runterraform planit seems like my instances are gonna get recreated, something I do not want. - Problem with 
lifecycle'signore_changesis that my virtual machines won't get updated when I introduce the KMS key into the configuration file. - Terraform 
time_sleepslows down Terraform configuration unecessary. 
答案1
得分: 1
看起来oci_identity_policy可能需要多达10秒:
通常,新策略在10秒内生效。
所以,即使您使用depends_on设置了显式依赖关系,或者只是使用了oci_identity_policy.boot_volume的属性,您仍需要等待那段时间。
我建议要么在OCI提供程序的存储库中提交问题,以便他们在提供程序中实施这个“就绪”检查,要么使用像time_sleep这样的解决方法:
resource "oci_identity_policy" "boot_volume" {
  count = local.create_kms_key ? 1 : 0
  ...
}
resource "time_sleep" "wait_for_identity_policy" {
  depends_on = [oci_identity_policy.boot_volume]
  create_duration = "15s"
}
resource "SOMETHING" "next" {
  depends_on = [time_sleep.wait_for_identity_policy]
}
<details>
<summary>英文:</summary>
Looks like [`oci_identity_policy`][1] can take up to 10seconds: 
> New policies take effect typically within 10 seconds.
So indeed even if you set an explicit dependency with `depends_on` or have an implicit one by just using attributes from `oci_identity_policy.boot_volume` you would still need to wait for that duration.
I suggest either filing an issue in OCI provider's repository so they implement this "readiness" check in the provider, or using workarounds like [`time_sleep`][2]:
    resource "oci_identity_policy" "boot_volume"{
      count = local.create_kms_key ? 1 : 0
      ...
    }
    resource "time_sleep" "wait_for_identity_policy" {
      depends_on = [oci_identity_policy.boot_volume]
    
      create_duration = "15s"
    }
    
    resource "SOMETHING" "next" {
      depends_on = [time_sleep.wait_for_identity_policy]
    }
  [1]: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_policy
  [2]: https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep
</details>
				通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论