How-To: Como implementar Quota Monitoring Solution (QMS) para Google Cloud en 60 min
Al momento de utilizar un producto por primera vez, Google Cloud emplea quotas sobre los recursos para restringir su cantidad de uso que es posible utilizar por defecto. Cada quota representa un recurso contable específico, como las llamadas de API a un servicio en particular o la cantidad de núcleos de cómputo utilizados simultáneamente por un Proyecto.
Ejemplo: Cantidad de Cloud Routers por VPC — Total 5
Las quotas se aplican por una variedad de razones, que incluyen:
- Para proteger a los usuarios de Google Cloud evitando picos imprevistos en el uso y servicios sobrecargados.
- Para ayudarle a administrar los recursos. Por ejemplo, puede establecer sus propios límites en el uso del servicio mientras desarrolla y prueba sus aplicaciones y así evitar costos inesperados provenientes de algún peak de uso de recursos.
Dado que estas quotas son parte de los puntos a considerar al momento de implementar alguna carga de trabajo en la nube, es importante contar con la visibilidad adecuada y así evitar problemas o situaciones imprevistas al momento de ejecutar un despliegue.
La información de quotas puede ser obtenida de diferentes formas: a través de la Consola de Google Cloud o utilizando la línea de comandos gcloud , en donde también se pueden crear, en forma manual, Alertas en Cloud Monitoring que enviarán notificaciones cuando algún recurso alcance el límite de la quota.
1. Que provee la solución de QMS?
La solución de QMS ofrece beneficios para administradores cloud, que requieren visibilidad de las quotas de los Proyectos, Carpetas u Organizaciones en Google Cloud. QMS ofrece una vista centralizada del uso y alertas para esas quotas.
En resumen, la solución entrega:
- Agregación de quotas automatizada en todos los Proyectos, Carpetas u Organizaciones de los que el usuario decida obtener visibilidad.
- Frecuencia de escaneo definida, que puede ser modificada de acuerdo a la necesidad de actualización de datos por parte del administrador.
- Un tablero con visibilidad del uso reciente de recursos para todos los Proyectos en el caso de Organizaciones.
- Alertas preconfiguradas, de acuerdo a un límite general de uso de quotas (Ejemplo:. 75% de uso).
- Implementación a través de Terraform lo que facilita y agiliza su adopción.
2. Arquitectura Técnica
El siguiente diagrama muestra la arquitectura de la solución, que puede ser desplegada en minutos siguiendo las instrucciones de la guía de implementación.
El template de terraform provisiona los siguientes recursos en su proyecto de Google cloud.
- Cloud Scheduler
- Cloud Functions
- Pub/Sub
- BigQuery
- Data Studio
- Cloud Monitoring — Metricas Customizadas y Alertas
3. Proceso de Despliegue
A continuación, ejecutaremos el proceso de despliegue a través de la CLI de Google Cloud, basándonos en la guía oficial de despliegue.
3.1. Pre-requisitos
- Proyecto host
- Objetivo ( Organización, Carperta o Proyecto)
- Rol de “Project Owner” en el Proyecto Host
- Google Cloud SDK
- Terraform >= 0.14.6
3.2. Cofiguración Inicial
a. En la consola local crear un directorio para descargar la solución y guardar las credenciales:
mkdir quota-monitoring-dashboard
cd quota-monitoring-dashboard
b. Configurar el Proyecto por defecto en la CLI
gcloud config set project <Proyecto Host>
c. Actualizar los componentes de la CLI
gcloud components update
En caso que este comando presente un error seguir las instrucciones entregadas por la CLI para realizar la actualización
d. Es importante mencionar que Cloud Scheduler depende de la aplicación desplegada en App Engine, así que es necesario crear una App Engine en la región en la que desees alojar la solución. Para propósitos de este blog utilizaremos “us-central1”, la lista de regiones la puedes consultar en este link:
gcloud create app region=us-central1
e. Tomar nota de la región elegida, dado que la utilizaremos al momento de desplegar nuestro Terraform con la solución de QMS
3.3. Crear una cuenta de Servicio
a. Para ejecutar las siguientes expresiones regulares necesitarás crear las siguientes variables de ambiente:
export DEFAULT_PROJECT_ID=$(gcloud config get-value core/project 2> /dev/null)
export SERVICE_ACCOUNT_ID="sa-"$DEFAULT_PROJECT_ID
export DISPLAY_NAME="sa-"$DEFAULT_PROJECT_ID
b. Crear la cuenta de servicio:
gcloud iam service-accounts create $SERVICE_ACCOUNT_ID --description="Service Account to scan quota usage" --display-name=$DISPLAY_NAME
3.4 Entregar roles y permisos a la cuenta de servicio
La cuenta de servicio necesitará diversos roles para ejecutar las funciones y obtener los datos a través de los Cloud Functions en el Proyecto Host.
- BigQuery Data Editor
- BigQuery Job User
- Cloud Functions Admin
- Cloud Scheduler Admin
- Pub/Sub Admin
- Service Account User
- Service Usage Admin
- Storage Admin
- Cloud Asset Viewer
- Compute Network Viewer
- Compute Viewer
- Notification Channel Editor
- Alert Policy Editor
- Viewer
- Metric Writer
- Logs Configuration Writer
- Log Writer
- Security Admin
a. Para asignar los roles se debe ejecutar el siguiente comando:
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/bigquery.dataEditor" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/bigquery.jobUser" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/cloudfunctions.admin" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/cloudscheduler.admin" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/pubsub.admin" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/iam.serviceAccountUser" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/storage.admin" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/serviceusage.serviceUsageAdmin" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/cloudasset.viewer" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/compute.networkViewer" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/compute.viewer" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/monitoring.notificationChannelEditor" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/monitoring.alertPolicyEditor" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/logging.configWriter" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/logging.logWriter" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/monitoring.viewer" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/monitoring.metricWriter" --condition=None
gcloud projects add-iam-policy-binding $DEFAULT_PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/iam.securityAdmin" --condition=None
Luego de entregar los roles generales, es necesario decidir cuál es el Objetivo.
- Proyecto (por defecto estos permisos fueron otorgados por el paso anterior)
- Carpeta
- Organización
Opcional
Si solo requieres monitorear una Carpeta o una Organización, exporta su ID como variable de ambiente y luego aplica los roles para cada opción, como se ilustra a continuación:
Opción 1 — Monitoreo de Carpeta.
export TARGET_FOLDER_ID=<target folder id like 41807409XXX>
a. Roles
gcloud alpha resource-manager folders add-iam-policy-binding $TARGET_FOLDER_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/cloudasset.viewer"
gcloud alpha resource-manager folders add-iam-policy-binding $TARGET_FOLDER_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/compute.networkViewer"
gcloud alpha resource-manager folders add-iam-policy-binding $TARGET_FOLDER_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/compute.viewer"
gcloud alpha resource-manager folders add-iam-policy-binding $TARGET_FOLDER_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/resourcemanager.folderViewer"
gcloud alpha resource-manager folders add-iam-policy-binding $TARGET_FOLDER_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/monitoring.viewer"
Opción 2 — Monitoreo de Organización
export TARGET_ORG_ID=<target org id ex. 38659473572>
a. Roles
gcloud organizations add-iam-policy-binding $TARGET_ORG_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/cloudasset.viewer" --condition=None
gcloud organizations add-iam-policy-binding $TARGET_ORG_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/compute.networkViewer" --condition=None
gcloud organizations add-iam-policy-binding $TARGET_ORG_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/compute.viewer" --condition=None
gcloud organizations add-iam-policy-binding $TARGET_ORG_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/resourcemanager.folderViewer" --condition=None
gcloud organizations add-iam-policy-binding $TARGET_ORG_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/resourcemanager.organizationViewer" --condition=None
gcloud organizations add-iam-policy-binding $TARGET_ORG_ID --member="serviceAccount:$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com" --role="roles/monitoring.viewer" --condition=None
3.5 Descargar codigo fuente
a. Clonar el repositorio de QMS
git clone https://github.com/google/quota-monitoring-solution.git quota-monitorings-solution
b. Ingresar al directorio de terraform
cd ./quota-monitorings-solution/terraform/example
3.6 Descargar la llave de la cuenta de servicio.
Dado que Terraform utiliza una cuenta de servicio para desplegar sus templates sobre Google Cloud, la cuenta de servicio se encuentra en el Proyecto Host que alojará los servicios de QMS:
gcloud iam service-accounts keys create key.json \
--iam-account=$SERVICE_ACCOUNT_ID@$DEFAULT_PROJECT_ID.iam.gserviceaccount.com
Recuerda que la llave de la cuenta de servicio puede ser descargada solo una vez.
3.7 Configurar Terraform
a. Verificar que en el directorio ~/quota-monitoring-solution/terraform/example se encuentran los siguientes archivos.
- key.json
- main.tf
- variables.tf
- terraform.tfvars
b. Abrir terraform.tfvars en el editor favorito para cambiar las variables necesarias
vi terraform.tfvars
o
nano terraform.tfvars
Los parametros a configurar son:
/*
Copyright 2022 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
# Update values
project_id = "ID_DE_PROYECTO_HOST"
region = "REGION_DE_DESPLIEGE_APP_ENGINE"
service_account_email = "CUENTA_DE_SERVICIO"
folders = "[ID_DE_CARPETA]"
organizations = "[ID_DE_ORGANIZACION]"
alert_log_bucket_name = "NOMBRE_DEL_BUCKET_DE_LOGS"
notification_email_address = "EMAIL_DE_NOTIFICACION"
threshold = "LIMITE_DE_ALERTA"
- En el caso de “Folders” y “Organizations” , se debe especificar uno u otro segun se requiera monitorear una Carpeta u Organización respectivamente, manteniendo los paréntesis cuadrados.
- Para el “alert_log_bucket_name” es un nombre randomico de un bucket que aloja los logs, favor considerar que este nombre debe ser único.
- Threshold es el límite en el cual quiero que QMS me alerte en caso de aumento de uso de quota, ej. 70%,80%,etc. es un entero de 1 a 100
c. Ir al directorio qms/modules
cd ../modules/qms/
Editar el archivo main.tf
vi main.tf
En la linea 19, columna 44 encontrarán la variable de version de qms “var.qms_version” cambiar el valor por defecto a “main”
locals {
expanded_region = var.region == "us-central" || var.region == "europe-west" ? "${var.region}1" : var.region
use_github_release = var.qms_version != "main" ? true : false
}
Luego retornar al directorio ../terraform/example
cd ../../example/
3.8 Ejecutar Terraform
a. Ejecutar los siguientes comandos de terraform
terraform init
terraform plan
terraform apply
Enter a value: yes
Este comando habilitará todas las APIs necesarias para el despliegue y creará los recursos correspondientes.
En caso que el comando de terraform falle, es posible que sea por timeout al momento de crear los recursos. Bajo esta condicion favor ejecutar nuevamente “terraform.plan” & “terraform apply”.
3.9 Testing
a. En Cloud Scheduler click en “Run Now”, el estatus cambia a “Running” por un momento.
b. Para verificar la existencia, es posible revisar en BigQuery la tabla de los datos de QMS.
3.10 Dashboard de Data Studio
a. Revisar el acceso a Data Studio dashboard template, si este link no es accesible puedes un correo a quota-monitoring-solution@google.com para compartir el dashboard a utilizar en QMS.
b. Crear una copia del template desde el icono de 3 puntos en la barra superior a la derecha, click “Make a Copy”
c. Click en “Copy Report”
d. Esto creará una copia del reporte y lo abrirá en modo editor, en caso que esto no suceda click en el boton “edit” en la esquina superior derecha.
e. El el panel de “Data” seleccionar cualquier campo y hacer click en “Edit Data Source”
f. En esta query, reemplazar,
- Id del proyecto host
- Id del Dataset
- Nombre de la tabla
Esto hará match con el despliegue ya realizado, verificar que la query se ejecuta correctamente y luego hacer click en el boton “Reconnect”
SELECT
project_id,
added_at,
region,
quota_metric,
CASE
WHEN CAST(quota_limit AS STRING) ='9223372036854775807' THEN 'unlimited'
ELSE
CAST(quota_limit AS STRING)
END AS str_quota_limit,
SUM(current_usage) AS current_usage,
ROUND((SAFE_DIVIDE(CAST(SUM(current_usage) AS BIGNUMERIC), CAST(quota_limit AS BIGNUMERIC))*100),2) AS current_consumption,
SUM(max_usage) AS max_usage,
ROUND((SAFE_DIVIDE(CAST(SUM(max_usage) AS BIGNUMERIC), CAST(quota_limit AS BIGNUMERIC))*100),2) AS max_consumption
FROM
(
SELECT
*,
RANK() OVER (PARTITION BY project_id, region, quota_metric ORDER BY added_at DESC) AS latest_row
FROM
`[YOUR_PROJECT_ID].quota_monitoring_dataset.quota_monitoring_table`
) t
WHERE
latest_row=1
AND current_usage IS NOT NULL
AND quota_limit IS NOT NULL
AND current_usage != 0
AND quota_limit != 0
GROUP BY
project_id,
region,
quota_metric,
added_at,
quota_limit
Click en “Done”
g. Una vez que el datasource esta configurado, ya puede hacer uso del dashoard con los datos de quota de tu proyecto, carpeta u organización.
3.11 Alertas
Las alertas pueden ser configuradas para ser enviadas por los siguientes servicios,
- Slack
- PagerDuty
- SMS
- Webhooks
3.11.1 Configuración de Slack
Para configurar las notificaciones hacia un canal de Slack, debe tener el rol de “Monitoring Notification Chanel Editor” en el proyecto Host.
3.11.2 Crear Canal de Notificación y Politicas de Alerta
Para crear un canal de notificación en Cloud Monitoring pueden consultar la siguiente documentación que indica como realizarlo paso a paso a traves de la consola de Google Cloud.
En el caso de politicas de alerta favor referirse a la siguiente documentación pública.
Este blog esta basado en la solución “Quota Monitoring Solution” de Google Cloud