Reparto de costos

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Arquitectura

Cost Sentry es un conjunto de secuencias de comandos y configuraciones que te permiten cerrar recursos cuando se exceden los presupuestos de Facturación de Google Cloud.

Esta secuencia de comandos consta de los siguientes componentes :

  • Eventos - Cola - Pub/Sub
  • Facturación - Controles de costos - Presupuestos
  • Eventos - Manejo de eventos - Cloud Functions
  • Compute - VM - Compute Engine
  • Compute - Sin servidores - Cloud Run

Esta secuencia de comandos configurará un presupuesto, una cola de mensajes y Cloud Function para administrar todo esto. Luego, inicia una VM de muestra y un servicio respaldado por un contenedor administrado por el sistema.


Comenzar

Haga clic en el siguiente vínculo para obtener una copia del código fuente en Cloud Shell. Una vez ahí, un solo comando iniciará una copia de la aplicación en funcionamiento en tu proyecto.

Abrir en Cloud Shell

Ver código fuente en GitHub


Componentes de Cost Sentry

La arquitectura de Cost Sentry usa varios productos. A continuación, se enumeran los componentes, junto con más información sobre los componentes, incluidos los vínculos a videos relacionados, documentación del producto y explicaciones interactivas.
Video Documentos Explicaciones
Google Cloud Pub/Sub Google Cloud Pub/Sub es un bus de mensajería que permite integrar aplicaciones en distintos servicios de distintos componentes de la nube en un sistema integrado.
Presupuestos de facturación Los presupuestos de facturación te permiten recibir notificaciones y tomar medidas cuando tu facturación supera los límites que estableciste.
Cloud Functions Cloud Functions es una plataforma de servicio que te permite detectar las cargas de archivos de Cloud Storage y ejecutar código para crear miniaturas de ellas.
Compute Engine Compute Engine es la tecnología virtual de Google Cloud. Con él, puede iniciar muchas configuraciones diferentes de VM que se ajusten a sus necesidades informáticas.
Cloud Run Cloud Run te permite ejecutar aplicaciones en un contenedor, pero sin servidores, sin tener que configurar la cantidad de instancias, procesadores o memoria. Sube un contenedor y obtén una URL.

Secuencias de comandos

La secuencia de comandos de instalación usa un ejecutable escrito en go y las herramientas de la CLI de Terraform para tomar un proyecto vacío y, luego, instalar la aplicación en él. El resultado debe ser una aplicación en funcionamiento y una URL para la dirección IP de balanceo de cargas.

./main.tf

Habilitar servicios

Los servicios de Google Cloud están inhabilitados en un proyecto de forma predeterminada. Para usar Cost Sentry, activa los siguientes servicios:

  • Presupuestos de facturación: Haga un seguimiento de la facturación y administre las alertas de facturación.
  • Cloud Build: Crea imágenes de contenedor y, luego, impleméntalas en Cloud Run.
  • Compute Engine: Implementa máquinas virtuales y servicios de herramientas de redes, como el balanceo de cargas.
  • Cloud Functions: responde a eventos de la plataforma de servicio
  • Cloud Run: Aloja contenedores en un entorno sin servidores y proporciona URL para acceder a la aplicación.
variable "gcp_service_list" {
        description = "The list of apis necessary for the project"
        type        = list(string)
        default = [
            "cloudresourcemanager.googleapis.com",
            "cloudbilling.googleapis.com",
            "billingbudgets.googleapis.com",
            "cloudbuild.googleapis.com",
            "compute.googleapis.com",
            "cloudfunctions.googleapis.com",
            "storage.googleapis.com",
            "run.googleapis.com"
        ]
}

resource "google_project_service" "all" {
    for_each           = toset(var.gcp_service_list)
    project            = var.project_number
    service            = each.key
    disable_on_destroy = false
}

Crear canal de Pub/Sub

Crea un canal de Pub/Sub para detectar eventos de presupuesto de facturación y responder con Cloud Functions

resource "google_pubsub_topic" "costsentry" {
    name = "${var.basename}-billing-channel"
    project    = var.project_number
}

Crea el servicio de Cloud Run para aplicarlo

Crea un servicio de muestra de Cloud Run en el que se ejecutará la aplicación de facturación.

resource "google_cloud_run_service" "app" {
    name     = "${var.basename}-run-service"
    location = var.region
    project  = var.project_id

    metadata {
        labels = {"${var.label}"=true}
    }

    template {
        spec {
            containers {
                image = "us-docker.pkg.dev/cloudrun/container/hello"
            }
        }

        metadata {
            annotations = {
                "autoscaling.knative.dev/maxScale" = "1000"
                "run.googleapis.com/client-name"   = "terraform"
            }
        }
    }
    autogenerate_revision_name = true
    depends_on = [google_project_service.all]
}

Crear instancia de VM

Crea una instancia de muestra de Compute Engine en la que se ejecutará la aplicación.

resource "google_compute_instance" "example" {
    name         = "${var.basename}-example"
    machine_type = "n1-standard-1"
    zone         = var.zone
    project      = var.project_id
    tags                    = ["http-server"]
    labels = {"${var.label}"=true}

    boot_disk {
        auto_delete = true
        device_name = "${var.basename}-example"
        initialize_params {
            image = "family/debian-10"
            size  = 200
            type  = "pd-standard"
        }
    }

    network_interface {
        network = "default"
        access_config {
        // Ephemeral public IP
        }
    }

    depends_on = [google_project_service.all]
}

Cree un presupuesto

Crea un presupuesto para supervisar los gastos en tus proyectos.

provisioner "local-exec" {
    command = <<-EOT
    gcloud beta billing budgets create --display-name ${var.basename}-budget \
    --billing-account ${var.billing_account} --budget-amount ${var.budgetamount} \
    --all-updates-rule-pubsub-topic=projects/${var.project_id}/topics/${var.basename}-billing-channel
    EOT
}

Crea una cuenta de servicio y configura permisos

Crea una cuenta de servicio para las llamadas de Cloud Function.

resource "google_service_account" "functions_accounts" {
    account_id   = local.safunctionuser
    description  = "Service Account for the costsentry to run as"
    display_name = local.safunction
    project      = var.project_number
}

Configurar permisos

El siguiente comando establece funciones y permisos de IAM que permiten a Cloud Build implementar los servicios requeridos.

La serie de comandos implementa lo siguiente: Otorga permiso a la cuenta de servicio de Cloud Functions para administrar Cloud Run. Otorga permiso a la cuenta de servicio de Cloud Functions para detener instancias de Compute Engine. Otorga permiso a la cuenta de servicio de Cloud Build para que actúe en nombre de la cuenta de servicio de Compute.

variable "build_roles_list" {
        description = "The list of roles that fucntions needs for"
        type        = list(string)
        default = [
            "roles/run.admin",
            "roles/compute.instanceAdmin",
            "roles/iam.serviceAccountUser"
        ]
}

resource "google_project_iam_member" "allbuild" {
    for_each   = toset(var.build_roles_list)
    project    = var.project_number
    role       = each.key
    member     = "serviceAccount:${google_service_account.functions_accounts.email}"
    depends_on = [google_project_service.all,google_service_account.functions_accounts]
}

Implementa una Cloud Function

El siguiente comando implementa una función de Cloud Functions que desactiva recursos cuando se activa una alerta.

resource "google_storage_bucket" "function_bucket" {
    name     = "${var.project_id}-function-deployer"
    project  = var.project_number
    location = var.location
}

resource "null_resource" "cloudbuild_function" {
    provisioner "local-exec" {
        command = <<-EOT
        cp code/function/function.go .
        cp code/function/go.mod .
        zip index.zip function.go
        zip index.zip go.mod
        rm go.mod
        rm function.go
        EOT
    }

    depends_on = [
        google_project_service.all
    ]
}

resource "google_storage_bucket_object" "archive" {
    name   = "index.zip"
    bucket = google_storage_bucket.function_bucket.name
    source = "index.zip"
    depends_on = [
        google_project_service.all,
        google_storage_bucket.function_bucket,
        null_resource.cloudbuild_function
    ]
}

resource "google_cloudfunctions_function" "function" {
    name    = var.basename
    project = var.project_id
    region  = var.region
    runtime = "go116"
    service_account_email = google_service_account.functions_accounts.email
    available_memory_mb   = 128
    source_archive_bucket = google_storage_bucket.function_bucket.name
    source_archive_object = google_storage_bucket_object.archive.name
    entry_point           = "LimitUsage"
    event_trigger {
        event_type = "google.pubsub.topic.publish"
        resource   = google_pubsub_topic.costsentry.name
    }

    environment_variables = {
        GOOGLE_CLOUD_PROJECT = var.project_id
        LABEL= var.label
    }

    depends_on = [
        google_storage_bucket.function_bucket,
        google_storage_bucket_object.archive,
        google_project_service.all
    ]
}

Conclusión

Una vez ejecutado, debería tener una solución de control de costos en ejecución en tu proyecto. Además, debes tener todo el código para modificar o extender esta solución a fin de que se ajuste a tu entorno.