POC Terraform + Bucket + BigQuery 💾

En este artículo veremos como crear un bucket en GCP con fuentes de datos que se van a utilizar para crear un flujo en con google BigQuery, todo utilizando terraform.

Para está POC se requiere una cuenta de Google Cloud, si no tienes una puedes crearla y te regalan 300 USD de crédito. https://cloud.google.com/

Esté tutorial puede llegar a generar un costo mínimo por lo cual se requiere tener especial cuidado en destruir los artefactos creados.

Ya con una cuenta en google es necesario tener un proyecto y una cuenta de servicio para que pueda ser usada por terraform. https://cloud.google.com/compute/docs/access/service-accounts?hl=es-419

Bien, por ahora no usaremos un backend bucket para guardar nuestro tf state pero bien se podría incluir.

Entonces la estructura de nuestro proyecto quedaría como se muestra en el diagrama:

  1. Crear un bucket y cargarle un archivo .csv
  2. Crear la definición de BigQuery
  3. Crear una tabla con los datos de nuestro archivo .csv
  4. Crear una vista basada en la tabla anterior con un filtro (SQL Query)
  5. Crear una vista con información de BigQuery public dataset https://cloud.google.com/bigquery/public-data

Nuestro proyecto de terraform lo puedes ver acá: https://github.com/xRegner/GCP-Terraform-Dataset

.
├── README.md
├── bucket-sample-gcp-xtian
│ ├── bucket.tf
│ ├── output.tf
│ └── variables.tf
└── datasets-sample-gcp-xtian
├── data
│ └── sheet-t.csv
├── main.tf
├── teradata-307123-aea8bdd5e41f.json
├── terraform.tfvars
└── variables.tf

Básicamente en una carpeta vamos a poner a manera de modulo la creación de nuestro bucket con el archivo .csv que se encuentra dentro de la carpeta datasets-sample-gcp-xtian > data > sheet-t.csv

Una vez que nuestro bucket fue creado y aprovisionado con el archivo vamos a sacar la ruta privada de ese csv para que nuestro dataset pueda ir a buscar la info, esto se puede ver el archivo output.tf

output "bucketurl" {
  value = google_storage_bucket.my_bucket_xtian_pro.url
}

output "file_name" {
  value = google_storage_bucket_object.topsecret_info.name
}

La carpeta datasets-sample-gcp-xtian contiene el main.tf que va a crear todos los componentes y se describe a continuación:

provider "google" {

  credentials = file("aquí debes poner la ruta de tu cuenta de servicio en .json ")
  project     = var.project_id
  region      = var.region
  zone        = var.zone
}

# Aquí importamos el módulo y le pasamos las variables del nombre de nuestro bucket

module "bucket_info" {
  source      = "../bucket-sample-gcp-xtian"
  bucket_name = var.bucket_name

}

# en esta sección definimos nuestro BigQuery

resource "google_bigquery_dataset" "bigqry_rhdw" {
  dataset_id                  = "teradatadts"
  friendly_name               = "test-dtaset"
  description                 = "Nuestro super dataset de tipo tabla"
  location                    = "US"
  default_table_expiration_ms = 3600000

  labels = {
    env = "default"
  }
}

# En esta sección estamos creando un schema vacío de datos y nuestra tabla se llama tabla1

resource "google_bigquery_table" "default" {
  dataset_id          = google_bigquery_dataset.bigqry_rhdw.dataset_id
  table_id            = "Tabla1"
  deletion_protection = false

  time_partitioning {
    type = "DAY"
  }

  labels = {
    env = "default"
  }

  schema = <<EOF
[
  {
    "name": "permalink",
    "type": "STRING",
    "mode": "NULLABLE",
    "description": "The Permalink"
  },
  {
    "name": "state",
    "type": "STRING",
    "mode": "NULLABLE",
    "description": "State where the head office is located"
  }
]
EOF

}

#Aquí creamos la tabla que se llena desde el archivo que depositamos en el bucket 

resource "google_bigquery_table" "sheet" {
  dataset_id          = google_bigquery_dataset.bigqry_fidw.dataset_id
  table_id            = "secret-data"
  deletion_protection = false

  schema = <<EOF
[
  {
    "name": "id",
    "type": "STRING",
    "mode": "NULLABLE",
    "description": "el id de los paises"
  },
  {
    "name": "Country",
    "type": "STRING",
    "mode": "NULLABLE",
    "description": "algunos paises de ejemplo"
  },
    {
    "name": "Quote",
    "type": "INTEGER",
    "mode": "NULLABLE",
    "description": "monto de venta"
  }
]
EOF




  external_data_configuration {
    autodetect    = true
    source_format = "CSV"

    source_uris = [
      "${module.bucket_info.bucketurl}/${module.bucket_info.file_name}",
    ]
  }
}


# Aquí creamos la view de la tabla anteriormente creada 

resource "google_bigquery_table" "public" {
  deletion_protection = false
  dataset_id          = google_bigquery_dataset.bigqry_rhdw.dataset_id
  table_id            = "view-pro"

  view {
    query          = "SELECT * FROM `teradata-307123.teradatadts.secret-data` WHERE Country = 'Mexico'"
    use_legacy_sql = false
  }

  depends_on = [
    google_bigquery_table.sheet,
  ]
}

# Finalmente creamos una vista a partir de los datos públicos que tiene google

resource "google_bigquery_table" "publicdataset" {
  deletion_protection = false
  dataset_id          = google_bigquery_dataset.bigqry_rhdw.dataset_id
  table_id            = "view-pro-public"

  view {
    query          = "SELECT EXTRACT(YEAR FROM creation_date) AS Year, EXTRACT(MONTH FROM creation_date) AS Month, COUNT(*) AS Number_of_Questions, ROUND(100 * SUM(IF (answer_count > 0, 1, 0)) / COUNT(*), 1) AS Percent_Questions_with_Answers FROM `bigquery-public-data.stackoverflow.posts_questions` GROUP BY Year, Month HAVING  Year > 2009 AND Year < 2016 ORDER BY Year"
    use_legacy_sql = false
  }

  depends_on = [
    google_bigquery_dataset.bigqry_fidw,
  ]
}



output "uris" {
  value = google_bigquery_table.sheet.external_data_configuration[0].source_uris
}



Los siguientes pasos son simplemente hacer:

#Dentro de la carpeta que contiene el archivo main:

terraform init
terraform plan
terraform apply -auto-approve

Y eso es todo.

Conclusión:

Con terraform podemos armar un flujo de datos inicial definiendo así un estado deseado de trabajo y a la vez construir una estructura que puede ser consumida por herramientas de visualización como Data studio, Tableau, Microstrategy etc, esta es una simple POC pero definitivamente puede ser la base de un proyecto complejo de aprovisionamiento de datos + infraestructura como código.

Espero te sirva esta información.
Christian Regner

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *