terraform-google-kubernetes-engine
terraform-google-kubernetes-engine copied to clipboard
A null value cannot be used as the collection in a 'for' expression.
When using the private-cluster module with 'add_cluster_firewall_rules' as true, the following error is produced during the terraform plan stage if using separate statefile for subnets:
on main.tf line 60, in locals:
60: cluster_alias_ranges_cidr = var.add_cluster_firewall_rules ? { for range in toset(data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range) : range.range_name => range.ip_cidr_range } : {}
|----------------
| data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range is null
A null value cannot be used as the collection in a 'for' expression.
Hi @jgfincore Can you confirm the existence of secondary ip ranges on that subnet? Additionally, if you can post your config for this module, that would be great!
So, we're using terragrunt. The gke module is dependent an a vpc and subnet module. Those network modules 'plan' just fine, it is only gke which fails with the error above. If I apply, it all works fine -- but the gke module failing on 'plan' stage creates issues in our workflow.
I'll try to clean up and post a excerpt from the gke module and get it up here shortly
We are getting this error with terraform destroy
:
Error: Iteration over null value
on .terraform/modules/gke/terraform-google-kubernetes-engine-10.0.0/modules/beta-private-cluster-update-variant/main.tf line 72, in locals:
72: cluster_alias_ranges_cidr = var.add_cluster_firewall_rules ? { for range in toset(data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range) : range.range_name => range.ip_cidr_range } : {}
|----------------
| data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range is null
A null value cannot be used as the collection in a 'for' expression.
As a workaround, you can try setting add_cluster_firewall_rules = false
.
The real fix would be something like:
cluster_alias_ranges_cidr = (var.add_cluster_firewall_rules && data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range != null) ? { for range in toset(data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range) : range.range_name => range.ip_cidr_range } : {}
We are seeing this as well( terraform 12.29). Behavior is a little strange, we have tested multiple scenarios. Our goal is to add a second vpc and cluster together, we cannot do that directly.
-
Empty state, empty project, try to create vpc with 2 subnets(and secondary ranges) and 2 corresponding clusters with
add_cluster_firewall_rules = true
: works fine -
State has vpc with 1 subnet and 1 cluster, try to add subnet and cluster (with
add_cluster_firewall_rules = true
) together: fails with error mentioned above -
State has vpc with 1 subnet and 1 cluster, try to add subnet and cluster (with
add_cluster_firewall_rules = false
) together: works(as expcted) can enable firewall rules after creation -
State has vpc with 2 subnets and 1 cluster, try to add second cluster: works(as expected)
Is there a way to use the reference to the secondary range rather than use data?
@robertb724 Do you mind sharing your Terraform config? I'm really curious why (2) is failing.
Hey! I just encountered the same problem. I am using the network module to create a VPC and I supply that to the gke (beta-private-cluster) module. I'd like to use add_cluster_firewall_rules
to make sure Istio's admission controller will work fine in the private cluster.
My guess: it uses data to get the secondary range and it fails, because it is not yet created. Is there a way to make sure it uses the supplied subnetwork instead of querying the data?
As a workaround, you can try setting
add_cluster_firewall_rules = false
.The real fix would be something like:
cluster_alias_ranges_cidr = (var.add_cluster_firewall_rules && data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range != null) ? { for range in toset(data.google_compute_subnetwork.gke_subnetwork[0].secondary_ip_range) : range.range_name => range.ip_cidr_range } : {}
Had the same error with terraform destroy
, adding the condition check for the for loop (real fix) fixes it for me
Same problem here. To work around this issue, I created separate firewall rules :(
I did some digging into this. In particular with 0.13 there is a change in how data sources are evaluated (https://www.terraform.io/docs/language/data-sources/index.html#data-resource-behavior,https://github.com/hashicorp/terraform/issues/27583). To workaround these limitations and use add_cluster_firewall_rules
, we can either
- apply subnets in a separate configurations, then the data source will be able to read subnet data
- if subnets and GKE has to be created in one config, source the subnet name from a computed attribute like the
self_link
. This will force the data source to defer read to apply time
The original comment in this issue seems to have happened because the networks config had just been planned and not applied. Hence during GKE plan, the data source was unable read the subnet.