James
James

Reputation: 1055

How to skip creation of Terraform module resources, If GCP folder already exists?

I'm using Terraform v1.1.0.

I would like to skip both google_folder module resources creation if the GCP Folder structure already exists.

google_folder.department1
google_folder.child_folders

The problem is that I only need to run them once for the first GCP folder structure creation, even though I trigger the project module many times.

terraform/envs/main.tf

variable "folder_name" {
  description = "The numeric ID of the folder this project should be created under"
  default     = "Folder C"
}

module "gcp_project" {
  source      = "../modules/project"
  project_id  = var.project_id
  folder_name = var.folder_name
}

terraform/modules/project/main.tf

variable "folder_list" {
    description = "Folders list"
    type        = list(string)
    default     = ["Folder A", "Folder B", "Folder C", "Folder D"]
}

# Top-level folder under an organization.
resource "google_folder" "department1" {
  display_name = "Department 1"
  parent       = "organizations/1234567"
}

# Sub-level folders under the Department 1 folder.
resource "google_folder" "child_folders" {
  count        = length(var.folder_list)
  display_name = element(var.folder_list, count.index)
  parent       = google_folder.department1.name
}

resource "google_project" "my_project" {
  name       = "My Project"
  project_id = "your-project-id"
  folder_id       = var.folder_name
}

Also, I tried to use the data.google_active_folder but I got the following error in the first creation of the top-level parent folder under the organization (Department 1)

ERROR Folder not found

How can I solve this issue?

Upvotes: 1

Views: 2135

Answers (2)

Jake Nelson
Jake Nelson

Reputation: 2063

Good practice: Bootstrapping is a challenging case, manually import it after the fact as others suggests, then it's consistent and in state.

Workaround if you're often deploying organisations:

Lil' disclaimer: I haven't tried this but it seems like it would work.

You can use the folders data source to read all the folders into a list and perform a check to see if it already exists.

data "google_folders" "my-org-folders" {
  parent_id = "organizations/${var.organization_id}"
}

resource "google_folder" "a_folder" {
  display_name = "bob"
  parent       = google_folder.department1.name
} if google_folders.my-org-folders.folders[*].name == "bob"

The huge downside to this is that it looks like your resource would be create from Terraform if they looked at the console and then saw the name match the one in code. People could potentially try linking projects to this resource which wouldn't exist! This is why it's good to import it and define it in code if it already exists.

Again, never tried this, come back and let me know how you go and I'll update my answer or remove it.

Upvotes: 1

manuiade
manuiade

Reputation: 11

Consider that the best way to accomplish this would be to use a dedicated module for your folders and subfolders, which you will call once.

Apart from that, if you want to keep your module structure you can work around the problem for example adding to your module a boolean flag, which creates the folder when it is set to true, otherwise skips those resource creation.

A practical example could be this:

terraform/envs/main.tf

variable "folder_name" {
  description = "The numeric ID of the folder this project should be created under"
  default     = "Folder C"
}

module "gcp_project" {
  source      = "../modules/project"
  project_id  = var.project_id
  folder_name = var.folder_name
  create_folders = true
}

terraform/modules/project/main.tf

variable "folder_list" {
    description = "Folders list"
    type        = list(string)
    default     = ["Folder A", "Folder B", "Folder C", "Folder D"]
}

variable "create_folders" {
    description = "If true creates folder resources, otherwise skip them"
    type        = bool
    default     = false
}

# Top-level folder under an organization.
resource "google_folder" "department1" {
  count = var.create_folders == true ? 1 : 0
  display_name = "Department 1"
  parent       = "organizations/1234567"
}

# Sub-level folders under the Department 1 folder.
resource "google_folder" "child_folders" {
  count        = var.create_folders == true ? length(var.folder_list) : 0
  display_name = element(var.folder_list, count.index)
  parent       = google_folder.department1.name
}

resource "google_project" "my_project" {
  name       = "My Project"
  project_id = "your-project-id"
  folder_id       = var.folder_name
}

The other times, you will call your module with false and you will skip folder creation.

Upvotes: 1

Related Questions