A missão pelo custo a nível de recursos no Google Cloud
Contornando limitações do Export de Custos para o BigQuery através de labels e do Cloud Asset Inventory
Quando você começa a acompanhar seus custos de cloud, é normal olhar para visões macro. Primeiro você olha para o custo total, o custo por serviço, o custo por sku, o custo por conta/projeto/assinatura, ou alguma combinação entre essas dimensões.
Entretanto, conforme sua conta cresce, você começa a perder a visão de variações de valores menores.
Vale notar que quando uma empresa opera em datacenters, é comum não se preocupar com variações de consumo no dia a dia. Afinal, organizações que precisam de elasticidade, operam com capacidade ociosa e o uso adicional não reflete num aumento de despesas. Já na cloud, basicamente tudo que é usado é cobrado, e quase tudo o que se deixa de usar, deixa de ser cobrado.
Numa conta de cerca de R$ 1 milhão por mês, é relativamente fácil ignorar uma recurso novo custando R$ 10 mil, um valor que provavelmente faz parte da variação regular da sua conta, mas que ainda assim pode ser relevante para seu time.
Quando você passa a olhar o custo a nível de recurso, o jogo muda.
Imagine que um time possui dos recursos, Recurso 1 e Recurso 2, do mesmo tipo. Assuma que:
- Recurso 1 custava consistentemente cerca de R$ 5 mil por mês.
- Recurso 2 custava consistentemente cerca de R$ 7 mil por mês.
- Em abril, o time decidiu desligar Recurso 2
- “Do nada”, também em abril, Recurso 1 passou a custar cerca de R$ 10 mil por mês
Nesse cenário, provavelmente será do interesse da sua organização que alguém entenda se o aumento de custo do Recurso 1 foi justificado. É possível que o aumento tenha feito parte do processo de remoção do Recurso 2, mas é possível que não. Se você só olha o custo total, pode perder a oportunidade de identificar e tratar um incidente de custos.
Um dos principais benefícios do acompanhamento granular de custos é evitar que otimizações, economias, e variações sazonais mascarem um aumento indevido e expressivo do custo de algum recurso.
AWS, Azure e Google Cloud: custo a nível recurso
Se você já trabalhava com FinOps na Azure ou na AWS, pode ter se frustrado com seu primeiro contato com o export do Billing do Google Cloud. Para obter os custos de um recurso específico, no export da Azure, você possui o campo InstanceId. No export da AWS, você habilita o campo ResourceId no CUR (Cost and Usage Reports). Já no Google Cloud, não possui neca.
Mas e aí, como fazer?
“Mede o que é mensurável e torna mensurável o que não o é.” — Galileu
Se você quer ter uma visão de custos a nível de recursos, no Google Cloud, existem algumas opções.
Para serviços como Compute Engine, Cloud Functions, Cloud Run, Cloud SQL, Cloud Spanner e App Engine, você pode habilitar a exportação de dados detalhada para o BigQuery. Porém, se você quiser uma visão detalhada de alguns outros serviços, como por exemplo Cloud Storage, você precisará aplicar labels nos recursos.
E o que é uma label?
Da doc, uma label é um par chave-valor que te ajuda a organizar seus recursos do Google Cloud. A parte mais importante é que as labels são encaminhadas para o Billing do Google Cloud, e você poderá fazer o breakdown de custos por label. Se para cada recurso você tiver uma label como custom_resource_id:{identificador_único_do_recurso}
, conseguirá ter a visibilidade de custos por recurso para os serviços suportados.
A maneira mais simples de aplicar as labels é “na mão”, considerando o nome de cada recurso.
Para aplicar labels identificadoras de recursos nos seus buckets do Cloud Storage, você pode pensar que é simplesmente rodar um script que pegue o nome do bucket e colocar em uma label, dado que nomes de buckets são únicos:
for bucket in $(gsutil ls)
do
# Removendo "gs://"
custom_resource_id=${bucket/'gs://'/''}
# Removendo "/"
custom_resource_id=${custom_resource_id/'/'/''}
# Aplicando a label
gsutil label ch -l custom_resource_id:$custom_resource_id $bucket
done
Entretanto, provavelmente irá encontrar um erro. O problema é que as restrições para o nome de um bucket são diferentes das restrições para o valor de uma label
Por exemplo, valores de labels não aceitam “.” e possuem no máximo 63 caracteres. Você pode ficar tentado a contornar as restrições escrevendo um script como o seguinte:
for bucket in $(gsutil ls)
do
# Removendo "gs://"
custom_resource_id=${bucket/'gs://'/''}
# Removendo "/"
custom_resource_id=${custom_resource_id/'/'/''}
# Substitindo "." por "_"
custom_resource_id=${custom_resource_id//'.'/'_'}
# Pegando apenas os 64 primeiros caracteres
custom_resource_id=${custom_resource_id:0:63}
# Aplicando a label
gsutil label ch -l custom_resource_id:$custom_resource_id $bucket
done
O problema é que agora podemos ter dois buckets com um mesmo valor de label, o que impede de identificar o custo exato do recurso, como era a proposta.
Uma forma mais robusta: Serviço de Labels
Se você não quer correr o risco de tratar o custo de vários recursos como o de um único, não há muito o que fazer: você precisará construir um serviço para a aplicação de labels. Vamos aqui mostrar como você pode fazer isso de maneira simples e rápida. Algumas etapas:
1. Determinar os recursos do Google Cloud que seu serviço de labels irá suportar
Para cada tipo de recurso do Google Cloud que escolher, você irá criar um script/método que aplica labels naquele tipo de recurso. Naturalmente, é válido começar pelos tipo de recurso que sua organização mais consome.
Vamos definir a chave da label a ser aplicada como custom_resource_id.
2. Criar export agendado dos recursos do Cloud Asset Inventory
Para ter centralizado em algum lugar “todos” os recursos de Google Cloud que sua organização possui, a melhor maneira é agendar o export de recursos do Cloud Asset Inventory (CAI) para o BigQuery. Com ele, você poderá ter metadados de todos os seus recursos que são suportados pelo CAI em uma única tabela.
3. Criar id para cada recurso
Agora, você precisa criar um id para cada recurso existente, que seja compatível com valores de labels do Google Cloud.
A maneira mais fácil de fazer isso é criando uma tabela em algum banco que possua uma coluna com auto incremento.
Mas, se não for possível utilizar um banco de outro serviço já existente (em geral não é recomendável), e não quiser subir um banco para algo tão simples, você pode fazer uma “gambiarrinha” com o BigQuery.
Crie a tabela custom_resource_labels:
CREATE TABLE project.dataset.custom_resource_labels (
custom_resource_id INT64 OPTIONS(description="O id numérico gerado para o recurso"),
google_resource_id STRING OPTIONS(description="O id do recurso, preenchido com o campo 'name' gerado pelo Cloud Asset Inventory"),
resource_type STRING OPTIONS(description="O tipo do recurso, preenchido com o campos 'asset_type' gerado pelo Cloud Asset Inventory")
)
Para popular o campo campo custom_resource_id, você pode puxar os recursos do export do CAI que ainda não existem nessa tabela, gerar o número da linha com ROW_NUMBER(), somar com MAX(customer_resource_id), e inserir na tabela.
Os outros campos você puxa diretamente do export do CAI, como na descrição da tabela.
4. Aplicar a label custom_resource_id
Agora, com as tabelas atualizadas do id de recursos e do cloud asset inventory, você pode criar Cloud Functions ou jobs do Batch que apliquem a label com o id criado, em todo recurso que não possua a label ou que possua o valor diferente do esperado.
Tá, então agora tenho o custo por recurso?
Infelizmente, não. Existem recursos e serviços que não suportam labels (por exemplo, Cloud Logging), e recursos que embora suportem, não tem seu valor propagado para o Billing do GCP, como tabelas no BigQuery.
Nesses casos, seu controle será uma estimativa. Falando de tabelas do BigQuery, você pode utilizar o INFORMATION SCHEMA de STORAGE como base.
Agora é esperar os próximos desenvolvimentos do export detalhado de custos para o BigQuery.
Se você tem uma ideia de como melhorar a visibilidade de custos, ou qualquer necessidade sobre produtos do Google, abra uma issue no IssueTracker. Se essa ideia de alguma forma ajude a melhorar a prática FinOps, compartilhe a issue com a comunidade, para outros interessados votarem e escalarem para seus Account Teams.
Quer publicar seu conteúdo no blog FinOps Brazil? Convidamos você para dividir sua experiência! Clique aqui e saiba como ajudar na missão de difundir a prática de FinOps. : )