Importância de tags para a Comunidade de FinOps

finops day
4 min readOct 28, 2023

--

As tags desempenham um papel fundamental na gestão e organização de recursos na nuvem, seja na AWS, Azure, Google Cloud, ou em outros provedores de serviços em nuvem.

Pensando nisso criamos uma lambda que faz o tagueamento do Aws s3.

Uma breve explicação sobre a lambda:

  1. Automação de Marcação*: A automação é uma prática fundamental da FinOps. Essa função automatiza a marcação de buckets, garantindo que os buckets sejam consistentemente etiquetados com informações relevantes, como o nome do bucket e a equipe (representada pela tag ‘bu’ no código) responsável.
  2. Evita Custos Desnecessários: A marcação adequada dos recursos na AWS é essencial para o gerenciamento de custos. Com as tags corretas, as equipes de FinOps podem rastrear e alocar custos de forma mais eficaz. Além disso, a função garante que os buckets não sejam acidentalmente deixados sem marcação, o que pode levar a custos desnecessários.
  3. Padronização e Consistência: A função ajuda a padronizar as tags em buckets, o que é crucial para a consistência das informações. Isso facilita a análise e o gerenciamento dos recursos de armazenamento.
  4. Escalabilidade: A função é projetada para funcionar em várias contas de destino, tornando-a escalável para organizações que gerenciam muitas contas AWS.
  5. Transparência e Rastreabilidade: A impressão de mensagens informativas fornece transparência sobre as ações realizadas, facilitando a rastreabilidade das operações de marcação.

Explicação detalhada do script:

obs: A função lambda segue a mesma lógica dos artigos anteriores. Para mais detalhes consulte Desligamento Automático das Instâncias EC2.

import boto3
from botocore.exceptions import ClientError

# Função para assumir um papel em uma conta de destino
def assume_role(target_account, role_to_assume_arn):
sts_client = boto3.client('sts')
assumed_role = sts_client.assume_role(RoleArn=role_to_assume_arn, RoleSessionName="AssumeRoleSession")
return assumed_role

# Função para obter as tags de um bucket no S3
def get_bucket_tags(s3_client, bucket_name):
try:
return s3_client.get_bucket_tagging(Bucket=bucket_name)
except ClientError as e:
if e.response['Error']['Code'] == 'NoSuchTagSet':
return {'TagSet': []}

# Função para adicionar ou atualizar uma tag em um conjunto de tags
def add_or_update_tag(tag_set, key, value, bucket_name, target_account):
for tag in tag_set:
if tag['Key'] == key:
tag['Value'] = value
return
tag_set.append({'Key': key, 'Value': value})
print(f"Conta {target_account}, adicionando a tag '{key}:{value}' no bucket {bucket_name}")

# Função principal para marcar os buckets em uma conta de destino
def tag_buckets_in_account(account_id, target_accounts, role_name):
s3 = boto3.client('s3')
buckets_found = False

for target_account in target_accounts:
role_to_assume_arn = f"arn:aws:iam::{target_account}:role/{role_name}"
assumed_role = assume_role(target_account, role_to_assume_arn)
assumed_session = boto3.Session(
aws_access_key_id=assumed_role['Credentials']['AccessKeyId'],
aws_secret_access_key=assumed_role['Credentials']['SecretAccessKey'],
aws_session_token=assumed_role['Credentials']['SessionToken']
)
s3_assumed = assumed_session.client('s3')

response = s3_assumed.list_buckets()
for bucket in response['Buckets']:
bucket_name = bucket['Name']
bucket_tags = get_bucket_tags(s3_assumed, bucket_name)

add_or_update_tag(bucket_tags['TagSet'], 'Name', bucket_name, bucket_name, target_account)

bu_tag_exists = False
for tag in bucket_tags['TagSet']:
if tag['Key'] == 'bu':
bu_tag_exists = True
if tag['Value'] != 'finops':
print(f"Valor anterior da tag 'bu' no bucket {bucket_name}: {tag['Value']}")
tag['Value'] = 'finops'
print(f"Valor da tag 'bu' substituído por 'finops' no bucket {bucket_name}")
buckets_found = True
break

if not bu_tag_exists:
add_or_update_tag(bucket_tags['TagSet'], 'bu', 'finops', bucket_name, target_account)
buckets_found = True

s3_assumed.put_bucket_tagging(Bucket=bucket_name, Tagging={'TagSet': bucket_tags['TagSet']})

if not buckets_found:
print("Não há buckets para taguear")

# Função de entrada do AWS Lambda
def lambda_handler(event, context):
target_accounts = ['AccountID', 'AccountID']
role_name = 'roleStartStop'

current_account = boto3.client('sts').get_caller_identity().get('Account')

tag_buckets_in_account(current_account, target_accounts, role_name)

Funcionamento da Função Lambda:

Essa função Lambda foi projetada para marcar buckets no Amazon S3 em várias contas de destino.

  1. A função começa importando as bibliotecas necessárias e definindo funções auxiliares, como `assume_role` para assumir papéis em contas de destino, `get_bucket_tags` para obter as tags de um bucket e `add_or_update_tag` para adicionar ou atualizar tags.
  2. A função principal, `tag_buckets_in_account`, itera sobre uma lista de contas de destino especificadas na variável `target_accounts`.
  3. Para cada conta de destino, a função assume um papel nessa conta usando `assume_role` para obter credenciais temporárias. Isso permite que a função acesse os recursos na conta de destino de forma segura.
  4. Em seguida, a função lista todos os buckets no Amazon S3 na conta de destino. Para cada bucket encontrado, ela obtém as tags existentes usando `get_bucket_tags`.
  5. A função verifica a existência da tag ‘Name’ no bucket e, se ela não existir ou se tiver um valor diferente, adiciona ou atualiza a tag ‘Name’ com o nome do próprio bucket.
  6. A função verifica a existência da tag ‘bu’ no bucket. Se a tag ‘bu’ não existir, ela a adiciona com o valor ‘finops’. Se a tag ‘bu’ já existir e tiver um valor diferente de ‘finops’, ela o atualiza para ‘finops’.
  7. A função imprime mensagens informativas para cada ação realizada, como a adição ou atualização de tags.
  8. Após processar todos os buckets na conta de destino, a função passa para a próxima conta, se houver.
  9. Finalmente, a função verifica se houve alguma operação realizada em qualquer bucket. Se nenhum bucket foi marcado (adicionado ou atualizado), ela imprime a mensagem “Não há buckets para taguear”.

Em resumo, essa função Lambda desempenha um papel importante no contexto da FinOps, automatizando a marcação de recursos de armazenamento em várias contas AWS. Ela ajuda a melhorar o controle de custos, a transparência e a padronização, promovendo práticas eficazes de gerenciamento financeiro em nuvem.

Agradecimentos:

Um agradecimento especial a Antonio de Abreu e Rodrigo Ferradas pela valiosa contribuição e insights compartilhados. Seus conhecimentos têm sido essenciais para guiar a comunidade nas melhores práticas e estratégias.

Esperamos que isso ajude!

--

--