Análise de custo

Arquitetura

Análise de custo é um conjunto de scripts e configurações que permitem encerrar recursos quando os orçamentos do Google Cloud Billing são excedidos.

Esse script é composto pelos seguintes componentes :

  • Eventos: fila - Pub/Sub
  • Faturamento - Controles de custo - Orçamentos
  • Eventos – Processamento de eventos – Cloud Functions
  • Computação - VMs - Compute Engine
  • Computação sem servidor: Cloud Run

Este script vai configurar um orçamento, uma fila de mensagens e uma função do Cloud para gerenciar tudo isso. Em seguida, ele ativa uma VM de amostra e um serviço com suporte de contêiner gerenciado pelo sistema.


Comece já

Clique no link a seguir para copiar o código-fonte no Cloud Shell. Depois, um único comando ativará uma cópia de trabalho do aplicativo no seu projeto.

Abrir no Cloud Shell

Ver código-fonte no GitHub (em inglês)


Componentes da Sentry de custo

A arquitetura Cost Sentry usa vários produtos. Veja a seguir os componentes e mais informações sobre eles, incluindo links para vídeos relacionados, documentação do produto e tutoriais interativos.
Video Documentos Tutoriais
Google Cloud Pub/Sub O Google Cloud Pub/Sub é um barramento de mensagens para integrar aplicativos em diferentes serviços, em diferentes componentes da nuvem, em um sistema integrado.
Orçamentos de faturamento Com os orçamentos de faturamento, você pode receber notificações e tomar providências quando o faturamento ultrapassar os limites definidos.
Cloud Functions O Cloud Functions é uma plataforma de serviços de funções que permite detectar uploads de arquivos do Cloud Storage e executar código para criar miniaturas deles.
Compute Engine O Compute Engine é a tecnologia virtual do Google Cloud. Com ele, é possível ativar várias configurações diferentes de VM para atender às suas necessidades de computação.
Cloud Run Com o Cloud Run, é possível executar aplicativos em um contêiner, mas sem servidor, sem a necessidade de configurar o número de instâncias, processadores ou memória. Faça upload de um contêiner e receba um URL.

Scripts

O script de instalação usa um executável escrito em go e ferramentas da CLI do Terraform para pegar um projeto vazio e instalar o aplicativo nele. A saída será um aplicativo em funcionamento e um URL para o endereço IP de balanceamento de carga.

./main.tf

Ativar serviços

Os serviços do Google Cloud são desativados em um projeto por padrão. Para usar o Cost Sentry, ative os seguintes serviços:

  • Orçamentos de faturamento: acompanhe o faturamento e gerencie alertas.
  • Cloud Build: crie imagens de contêiner e implante no Cloud Run.
  • Compute Engine: implemente máquinas virtuais e serviços de rede, como balanceamento de carga.
  • Cloud Functions: responda a eventos da plataforma de serviços.
  • Cloud Run: hospeda contêineres em um ambiente sem servidor e disponibiliza URLs para acessar o aplicativo.
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
}

Criar canal do Pub/Sub

Cria um canal do Pub/Sub para detectar eventos de orçamento de faturamento e responder com o Cloud Functions

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

Crie o serviço do Cloud Run para aplicar

Criar um serviço de amostra do Cloud Run em que será aplicada a aplicação do faturamento.

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]
}

Criar instância da VM

Crie uma instância de amostra do Compute Engine para executar a aplicação.

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]
}

Crie um orçamento.

Cria um orçamento para monitorar os gastos nos seus projetos.

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
}

Criar uma conta de serviço e definir permissões

Cria uma conta de serviço para as chamadas de função do Cloud.

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
}

Definir permissões

O comando a seguir define os papéis e as permissões do IAM que autorizam o Cloud Build a implantar os serviços necessários.

A série de comandos implementa o seguinte: Concede permissão à conta de serviço da função do Cloud para gerenciar o Cloud Run. Concede permissão à conta de serviço da função do Cloud para interromper instâncias do Compute Engine. Concede permissão à conta de serviço do Cloud Build para agir em nome da conta de serviço do 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]
}

Implantar uma Função do Cloud

O comando a seguir implanta uma Função do Cloud que desativa recursos quando um alerta é acionado.

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
    ]
}

Conclusão

Depois da execução, você terá uma solução de controle de custos em execução no projeto. Além disso, é preciso ter todo o código para modificar ou estender essa solução para se adequar ao seu ambiente.