Terraform is not waiting for the full module creation within foreach. Instead of finishing entire module creation in one iteration it is creating first resource from the module for every list element, then iterates over the list and creates second module, and so on.
Also I use parallelism=1 option when running the apply: terraform apply -parallelism=1
#templates/iam.tf
variable "project_id2" {}
variable "project_id" {}
variable "user" {}
variable "role" {}
resource "google_project_iam_member" "first_me" {
project = var.project_id2
role = var.role
member = "user:${var.user}"
}
resource "google_project_iam_member" "then_me" {
project = var.project_id
role = var.role
member = "user:${var.user}"
depends_on = [
google_project_iam_member.first_me
]
}
resource "time_sleep" "wait_seconds" {
create_duration = "11s"
depends_on = [google_project_iam_member.then_me]
}
resource "null_resource" "sleep_after_project_import" {
depends_on = [
time_sleep.wait_seconds,
google_project_iam_member.then_me
]
}
# ---
# ./main.tf
locals {
roles_for_bindings = [
"roles/accessapproval.invalidator",
"roles/actions.Viewer",
"roles/serviceconsumermanagement.tenancyUnitsAdmin",
]
}
module "role_binding_sleep_test" {
source = "./templates/iam"
for_each = toset(local.test)
project_id = "some_project_id"
project_id2 = "some_project_id2"
role = each.key
user = "[email protected]"
}
Logs
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.first_me: Creation complete after 9s [id=some_project_id2/roles/accessapproval.invalidator/user:[email protected]]
module.role_binding_sleep_test["roles/actions.Viewer"].google_project_iam_member.first_me: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].google_project_iam_member.first_me: Creation complete after 9s [id=some_project_id2/roles/actions.Viewer/user:[email protected]]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.first_me: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.first_me: Creation complete after 9s [id=some_project_id2/roles/serviceconsumermanagement.tenancyUnitsAdmin/user:[email protected]]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.then_me: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.then_me: Creation complete after 9s [id=some_project_id1/roles/accessapproval.invalidator/user:[email protected]]
module.role_binding_sleep_test["roles/actions.Viewer"].google_project_iam_member.then_me: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].google_project_iam_member.then_me: Creation complete after 9s [id=some_project_id1/roles/actions.Viewer/user:[email protected]]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.then_me: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.then_me: Creation complete after 10s [id=some_project_id1/roles/serviceconsumermanagement.tenancyUnitsAdmin/user:[email protected]]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].time_sleep.wait_seconds: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].time_sleep.wait_seconds: Still creating... [10s elapsed]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].time_sleep.wait_seconds: Creation complete after 11s [id=2023-12-04T13:22:47Z]
module.role_binding_sleep_test["roles/actions.Viewer"].time_sleep.wait_seconds: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].time_sleep.wait_seconds: Still creating... [10s elapsed]
module.role_binding_sleep_test["roles/actions.Viewer"].time_sleep.wait_seconds: Creation complete after 11s [id=2023-12-04T13:22:59Z]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].time_sleep.wait_seconds: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].time_sleep.wait_seconds: Still creating... [10s elapsed]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].time_sleep.wait_seconds: Creation complete after 11s [id=2023-12-04T13:23:10Z]
module.role_binding_sleep_test["roles/actions.Viewer"].null_resource.sleep_after_project_import: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].null_resource.sleep_after_project_import: Creation complete after 0s [id=111111]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].null_resource.sleep_after_project_import: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].null_resource.sleep_after_project_import: Creation complete after 0s [id=111112]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].null_resource.sleep_after_project_import: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].null_resource.sleep_after_project_import: Creation complete after 0s [id=111113]
Logs I was expecting:
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.first_me: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.first_me: Creation complete after 9s [id=some_project_id2/roles/accessapproval.invalidator/user:[email protected]]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.then_me: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].google_project_iam_member.then_me: Creation complete after 9s [id=some_project_id1/roles/accessapproval.invalidator/user:[email protected]]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].time_sleep.wait_seconds: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].time_sleep.wait_seconds: Still creating... [10s elapsed]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].time_sleep.wait_seconds: Creation complete after 11s [id=2023-12-04T13:22:47Z]
module.role_binding_sleep_test["roles/accessapproval.invalidator"].null_resource.sleep_after_project_import: Creating...
module.role_binding_sleep_test["roles/accessapproval.invalidator"].null_resource.sleep_after_project_import: Creation complete after 0s [id=111111]
# now 1st foreach iteration for role should end and next start
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.first_me: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.first_me: Creation complete after 9s [id=some_project_id2/roles/serviceconsumermanagement.tenancyUnitsAdmin/user:[email protected]]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.then_me: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].google_project_iam_member.then_me: Creation complete after 10s [id=some_project_id1/roles/serviceconsumermanagement.tenancyUnitsAdmin/user:[email protected]]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].time_sleep.wait_seconds: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].time_sleep.wait_seconds: Still creating... [10s elapsed]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].time_sleep.wait_seconds: Creation complete after 11s [id=2023-12-04T13:23:10Z]
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].null_resource.sleep_after_project_import: Creating...
module.role_binding_sleep_test["roles/serviceconsumermanagement.tenancyUnitsAdmin"].null_resource.sleep_after_project_import: Creation complete after 0s [id=111112]
# now 2nd foreach iteration for role should end and next start
module.role_binding_sleep_test["roles/actions.Viewer"].google_project_iam_member.then_me: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].google_project_iam_member.then_me: Creation complete after 9s [id=some_project_id1/roles/actions.Viewer/user:[email protected]]
module.role_binding_sleep_test["roles/actions.Viewer"].time_sleep.wait_seconds: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].time_sleep.wait_seconds: Still creating... [10s elapsed]
module.role_binding_sleep_test["roles/actions.Viewer"].time_sleep.wait_seconds: Creation complete after 11s [id=2023-12-04T13:22:59Z]
module.role_binding_sleep_test["roles/actions.Viewer"].null_resource.sleep_after_project_import: Creating...
module.role_binding_sleep_test["roles/actions.Viewer"].null_resource.sleep_after_project_import: Creation complete after 0s [id=111113]
When you use
countorfor_eachin Terraform, the meaning is to declare zero or more independent instances of the same module or resource. Terraform therefore assumes it can perform operations on those independent instances concurrently, or in any sequential order.If your instances are not actually independent of one another -- that is, if any one of them must be acted on before another for the result to be correct -- then
for_eachis not a suitable tool to use. Instead, you'll need to declare multiplemoduleblocks and explain the relationships between them by having the arguments in one block refer to the output values from the other.Dependencies in Terraform are between configuration blocks, not the multiple instances that they can potentially declare. Any time you need to describe a dependency between two objects, they will need to be declared as two separate configuration blocks.