Skip to content

Instantly share code, notes, and snippets.

@ihommani
Last active November 4, 2023 14:15
Show Gist options
  • Select an option

  • Save ihommani/dbbcb8c5ba74ac1029d9000a44598793 to your computer and use it in GitHub Desktop.

Select an option

Save ihommani/dbbcb8c5ba74ac1029d9000a44598793 to your computer and use it in GitHub Desktop.
Terraform Breadth first search algorithm on GCP
# Context: Given a GCP organisation node (the organisation itself or one of its subfolder) I need to get all the gcp project ids under this node, flattened in a single list.
# Terraform lacks of support to run trough graph structures like a tree.
# The below code is a breadth first search run. Depth first search would require recursivity, smthg that I didn't find on HCL.
# Last but not least, once I managed to get a working code after one hour of several tries I found the terraform resource which encapsulate what I needed first.
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/cloud_asset_resources_search_all#argument-reference
provider "google" {
user_project_override = true
billing_project = <TO-REPLACE>
}
provider "google-beta" {
user_project_override = true
billing_project = <TO-REPLACE>
}
locals {
#parent_node = "organizations/<TO-REPLACE>"
parent_node = "folders/<TO-REPLACE>"
}
data "google_folders" "folders_level_0" {
parent_id = local.parent_node
}
data "google_folders" "folders_level_1" {
for_each = toset(data.google_folders.folders_level_0.folders.*.name)
parent_id = each.value
}
data "google_folders" "folders_level_2" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_1).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_3" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_2).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_4" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_4).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_5" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_4).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_6" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_5).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_7" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_5).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_8" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_5).*.folders : v.*.name]))
parent_id = each.value
}
data "google_folders" "folders_level_9" {
for_each = toset(flatten([for v in values(data.google_folders.folders_level_5).*.folders : v.*.name]))
parent_id = each.value
}
locals {
folder_names = flatten(
[
[local.parent_node],
toset(data.google_folders.folders_level_0.folders.*.name),
toset(flatten([for v in values(data.google_folders.folders_level_1).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_2).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_3).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_4).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_5).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_6).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_7).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_8).*.folders : v.*.name])),
toset(flatten([for v in values(data.google_folders.folders_level_9).*.folders : v.*.name])),
]
)
}
data "google_projects" "my-org-projects" {
for_each = toset(local.folder_names)
filter = "parent.id:${split("/", each.value)[1]}"
}
locals {
projects_list = flatten(values(data.google_projects.my-org-projects).*.projects).*.project_id
}
output "projects_list" {
value = length(local.projects_list)
}
# VS
data "google_cloud_asset_resources_search_all" "cloud_build_projects" {
provider = google-beta
scope = local.parent_node
# https://cloud.google.com/asset-inventory/docs/supported-asset-types
asset_types = [
"cloudresourcemanager.googleapis.com/Project"
]
}
locals {
projects = [
for v in
[
for v in data.google_cloud_asset_resources_search_all.cloud_build_projects.results : tostring(v.name)
]
: split("projects/", v)[1]
]
}
output "projects_list_2" {
value = length(local.projects)
}
# project_list1 and 2 are equal in the end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment