Search code examples
google-cloud-platformgoogle-bigqueryterraformterraform-provider-gcp

Bigquery Multiple Tables access with Terraform with dynamic table name


I am trying to create multiple table access using a local list and pass values into a single resource block:

locals {
   map_of_all_tables = [
     {
     "table_name" : "table1"
     "dataset_id" : "dataset_id1"
     "table_id"   : "table_id1"
     },
     {
     "table_name" : "table2"
     "dataset_id" : "dataset_id2"
     "table_id"   : "table_id2"
     }
   ]
 }
resource "google_bigquery_table_iam_member" "access" {
   count = contains(var.table_name_list, local.map_of_all_tables[*].table_name) ? <(no. of matching tables)> : 0
   project = "test-project1"
   dataset_id = locals.map_of_all_tables[<indexOfMatchingTable>].dataset_id #dataset_id of matching table name
   table_id = locals.map_of_all_tables[<indexOfMatchingTable>].table_id #table_id of matching table name
   role = "roles/bigquery.dataViewer"
   member = "user:${var.user_email}"
 }

If the var.table_name_list contains any number of tables which matches the table name in the local list, it should create the resource "access[]" for each of these tables using the dataset ids and table ids from the list for these particular tables. Is this possible in Terraform? Any help would be appreciated. Thanks!


Solution

  • If I understand your question correctly, you have a list of tables in var.table_name_list var for which access needs to be given. All the tables are present in local.map_of_all_tables local variable & you want to filter it against var.table_name_list.

    I'm assuming above scenarios as you haven't told how var.table_name_list looks like..

    locals {
      map_of_all_tables = [
        {
          "table_name" : "table1"
          "dataset_id" : "dataset_id1"
          "table_id" : "table_id1"
        },
        {
          "table_name" : "table2"
          "dataset_id" : "dataset_id2"
          "table_id" : "table_id2"
        },
        {
          "table_name" : "table3"
          "dataset_id" : "dataset_id3"
          "table_id" : "table_id3"
        }
      ]
    
      ## this will filter
      table_access_list = [for table in local.map_of_all_tables : table if contains(var.table_name_list, table.table_name)]
    
    }
    
    ## assuming the var like below
    variable "table_name_list" {
      type    = list(any)
      default = ["table1", "table2"]
    }
    
    ## output displaying the filtered tables
    output "table_access_list" {
        value = local.table_access_list
    }
    

    Then, you could iterate over the local.table_access_list var to grant access only to desired tables.

    resource "google_bigquery_table_iam_member" "access" {
       for_each = {
          for table_access in local.table_access_list : table_access.table_name => table_access
       }
       project = "test-project1-${each.value.table_name}"
       dataset_id = local.table_access_list[each.value.table_name].dataset_id #dataset_id of matching table name
       table_id = local.table_access_list[each.value.table_name].table_id #table_id of matching table name
       role = "roles/bigquery.dataViewer"
       member = "user:${var.user_email}"
    }