Terraform needs to lookup resource as complete objects containing all instances in order to be able to index them in expressions. When the number of instances is large, this can make expression evaluation take considerably longer.
locals {
users = yamldecode(file("../users.yaml"))
}
resource "null_resource" "user" {
for_each = local.users
triggers = {
name = each.key
groups = join(",", each.value)
}
}
resource "null_resource" "user_group" {
for_each = local.users
triggers = {
name = null_resource.user[each.key].triggers.name
groups = join(",", each.value)
}
}
Original comment below:
This issue seems to be exacerbated to an extreme degree by the use of for_each.
@eriksw Thanks for detailed notes and the test case!
I've encountered similar issue while trying to create a large number of users (~1k) in AWS - after some experiments I ended up with another test case demonstrating performance issue with certain usage of for_each
- https://github.com/mlosev/tf-for_each-performance-test
The issue manifests for both Terraform 0.12.29 and 0.13.0 - it takes Terraform an order of magnitude longer (i.e. 10x+) to plan "slow" configuration versus "fast" configuration for the same number of users and groups (~1000) and empty local state (i.e. Terraform wants to create all resources)
The key difference between configuration is
--- users-0.13-fast/main.tf 2020-08-26 11:06:16.000000000 +0100
+++ users-0.13-slow/main.tf 2020-08-26 11:06:26.000000000 +0100
@@ -15,7 +15,7 @@
for_each = local.users
triggers = {
- name = each.key
+ name = null_resource.user[each.key].triggers.name
groups = join(",", each.value)
}
}
On my laptop, the difference in plan time is as follows:
Plan: 2100 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
300.20 real 467.68 user 19.38 sys
Plan: 2100 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
2.71 real 7.77 user 1.66 sys
This is quite unexpected behaviour for Terraform, especially considering that there are no API calls involved with null_resource
in this case...
PS. I also tried -parallelism=100
(just in case) for "slow" configuration, and it didn't change anything time-wise.
Originally posted by @mlosev in #18981 (comment)
eriksw, srinathrangaramanujam, horjulf, mhvelplund, kstormp and 41 morezeqk and benoittoulme
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4