terraform-google-modules / terraform-google-project-factory

Creates an opinionated Google Cloud project by using Shared VPC, IAM, and Google Cloud APIs
https://registry.terraform.io/modules/terraform-google-modules/project-factory/google
Apache License 2.0
826 stars 535 forks source link

Can't create project with Shared VPC in other project #362

Closed vlantier closed 4 years ago

vlantier commented 4 years ago

My code:

module "project" {
  source  = "terraform-google-modules/project-factory/google//modules/shared_vpc"
  version = "~> 7.0.0"

  name                    = var.project
  random_project_id       = "false"
  org_id                  = data.terraform_remote_state.core.outputs.organization["id"]
  folder_id               = data.terraform_remote_state.core.outputs.folder["id"]
  billing_account         = data.terraform_remote_state.core.outputs.organization["billing_account_id"]
  shared_vpc              = data.terraform_remote_state.core.outputs.project_id
  default_service_account = "delete"
  auto_create_network     = false
  lien                    = true

  shared_vpc_subnets = [
    google_compute_subnetwork.env.self_link,
  ]

  activate_apis = [
    "container.googleapis.com",
    "compute.googleapis.com",
    "cloudbilling.googleapis.com"
  ]
}

As we can see I'm using the shared_vpc submodule as mentioned in other issues but the erros are way more enormous.

Warning: External references from destroy provisioners are deprecated

  on .terraform/modules/project.project-factory.gcloud_delete/terraform-google-modules-terraform-google-gcloud-55b927a/main.tf line 176, in resource "null_resource" "run_command":
 176:     command = <<-EOT
 177:     PATH=${local.gcloud_bin_abs_path}:$PATH
 178:     ${var.destroy_cmd_entrypoint} ${var.destroy_cmd_body}
 179:     EOT

Destroy-time provisioners and their connection configurations may only
reference attributes of the related resource, via 'self', 'count.index', or
'each.key'.

References to other resources during the destroy phase can cause dependency
cycles and interact poorly with create_before_destroy.

(and 25 more similar warnings elsewhere)

Error: Invalid count argument

  on .terraform/modules/project/terraform-google-modules-terraform-google-project-factory-9e4b202/modules/core_project_factory/main.tf line 110, in resource "null_resource" "check_if_shared_vpc_subnets_contains_items_with_invalid_name":
 110:   count = length(
 111:     compact(null_resource.shared_vpc_subnet_invalid_name.*.triggers.name),
 112:   ) == 0 ? 0 : 1

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

Error: Invalid count argument

  on .terraform/modules/project/terraform-google-modules-terraform-google-project-factory-9e4b202/modules/core_project_factory/main.tf line 307, in resource "google_project_iam_member" "controlling_group_vpc_membership":
 307:   count = var.shared_vpc_enabled && length(compact(var.shared_vpc_subnets)) == 0 ? local.shared_vpc_users_length : 0

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

Error: Invalid count argument

  on .terraform/modules/project/terraform-google-modules-terraform-google-project-factory-9e4b202/modules/core_project_factory/main.tf line 323, in resource "google_compute_subnetwork_iam_member" "service_account_role_to_vpc_subnets":
 323:   count    = var.shared_vpc_enabled && length(compact(var.shared_vpc_subnets)) > 0 ? length(var.shared_vpc_subnets) : 0

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

Error: Invalid count argument

  on .terraform/modules/project/terraform-google-modules-terraform-google-project-factory-9e4b202/modules/core_project_factory/main.tf line 347, in resource "google_compute_subnetwork_iam_member" "group_role_to_vpc_subnets":
 347:   count = var.shared_vpc_enabled && length(compact(var.shared_vpc_subnets)) > 0 && var.manage_group ? length(var.shared_vpc_subnets) : 0

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

Error: Invalid count argument

  on .terraform/modules/project/terraform-google-modules-terraform-google-project-factory-9e4b202/modules/core_project_factory/main.tf line 370, in resource "google_compute_subnetwork_iam_member" "apis_service_account_role_to_vpc_subnets":
 370:   count = var.shared_vpc_enabled && length(compact(var.shared_vpc_subnets)) > 0 ? length(var.shared_vpc_subnets) : 0

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

Error: Invalid count argument

  on .terraform/modules/project/terraform-google-modules-terraform-google-project-factory-9e4b202/modules/core_project_factory/main.tf line 459, in resource "google_compute_subnetwork_iam_member" "gke_shared_vpc_subnets":
 459:   count    = local.gke_shared_vpc_enabled && length(compact(var.shared_vpc_subnets)) != 0 ? length(var.shared_vpc_subnets) : 0

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
morgante commented 4 years ago

Sorry for the issue, looks like the issue is with:

  shared_vpc_subnets = [
    google_compute_subnetwork.env.self_link,
  ]

As a workaround, could you try commenting out the project and creating the subnet first then creating the project?

As a long term fix, we should add a shared_vpc_subnets_length variable to the shared-vpc module and the core project factory modules. Then:

  1. Update the shared_vpc module to pass it through directly
  2. Update the other modules to pass through the computed value (length(shared_vpc_subnets)).
vlantier commented 4 years ago

The workaround worked. Thanks! We'll be waiting for the fix

adrian-gierakowski commented 4 years ago

@morgante I've encountered this problem today for the second time. Last time I've worked around it by doing a targeted apply (as you suggested here), but this time this looked into the code and got it working by removing compact from all occurrences of compact(var.shared_vpc_subnets) and commenting out subnet name validation. It's a bit of a bummer that trying to make sure people don't make mistakes when typing in subnet names makes it more difficult to use the module in the way terraform is intended to be used. Would you consider removing the validation hack?

rjerrems commented 4 years ago

Hi @adrian-gierakowski - I am currently looking at a fix for this now and have discussed the validation with @morgante . At this point in time we are looking to remove that code as it complicates the module and only really has the benefit of surfacing a failure that would occur anyway a little earlier

mattcary commented 4 years ago

+1

I have the same problem when setting shared_vpc from another project:

module "project_hmt_prod_cluster_service" { source = "terraform-google-modules/project-factory/google" version = "~> 7.0.0" .... snip ...

This line is the problem:

shared_vpc = module.project_hmt_prod_cluster_host_prod.project_id }

I guess count and for_each are just very limiting in terraform.

morgante commented 4 years ago

@mattcary Your use case can be solved by using the shared_vpc submodule:

module "project_hmt_prod_cluster_service" {
  source = "terraform-google-modules/project-factory/google//modules/shared_vpc"
  version = "~> 7.0.0"
}

Can you give that a try?

mattcary commented 4 years ago

That works!

Thanks for the tip.