O blog da AWS
Incluindo tags em recursos AWS de forma automatizada usando AWS Config, Amazon EventBridge e AWS Lambda
Por Ricardo Marques, Senior Solution Architect, DNB – LATAM
Neste blog post, você aprenderá a construir uma solução para identificar recursos AWS criados na sua conta sem tags obrigatórias e fazer a inclusão das tags de forma automática.
Uma das maneiras mais eficientes de se controlar custos ou identificar os donos de recursos criados nas contas AWS é fazendo o uso de tags. Uma boa prática é definir tags que identifiquem departamentos, centro de custos ou unidade de negocio e inserir essas tags nos recursos AWS no momento da sua criação. Entretanto muitas vezes os times de desenvolvimento acabam fazendo a criação de recursos sem essas tags, o que aumenta a dificuldade em fazer o gerenciamento dos recursos criados.
Existem algumas formas de se evitar a criação de alguns recursos sem tags específicas com uso de Tag Policies ou Service Control Policie (SCP), ambos no AWS Organization, entretanto alguns tipos recursos ainda não são cobertos pelos serviços acima e demandam outras maneiras de se controlar a existência das tags.
Arquitetura da solução
A criação de tags obrigatórias de forma automática em recursos AWS é executado seguindo o fluxo abaixo. Esse fluxo inclui regras criadas no AWS Config e Amazon EventBridge, uma função AWS Lambda e uma API do serviço Resource Groups.
Seguindo os passos do fluxo nesse post, você criará uma regra no AWS Config para detectar recursos criados sem uma ou mais tags específicas, uma regra no Amazon EventBridge para ser executada quando algum recurso sem tag for detectado, uma função AWS Lambda para obter o ARN no recurso e executar a API do serviço Resource Groups que irá inserir a tag no recurso.
A solução permite inserir tag no tipos de recursos existentes nesse link:
https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/supported-services.html
Figura 1 – Desenho da solução
Passos do fluxo de execução
- Um usuário cria uma instância de Amazon EC2 sem a tag desejada.
- O AWS Config detecta a criação do recurso sem a tag desejada e o classifica como não compatíveis.
- Uma regra do Amazon EventBridge é acionada e faz a execução de uma AWS Lambda.
- A AWS Lambda obtém o ARN do recurso no AWS Config.
- A AWS Lambda executa a API do serviço Resource Groups passando o ARN e a Tag a ser criada.
Configuração da solução
Siga os passos abaixo para configurar a solução para inclusão de tags em recursos não compatíveis de forma automatizada.
Passo 1: Crie uma regra no AWS Config
Crie uma nova regra no AWS Config para identificar recursos criados sem a tag desejada e os classificar como não compatíveis. Para criar a regra, acesso o serviço e no menu lateral esquerdo, clique em Regras e depois no botão Adicionar Regra.
Você será direcionado para a tela Especificar tipo de regra, use as configurações abaixo:
- Em Selecionar tipo de regra, escolha Adicionar regra gerenciada da AWS.
- Em Regras gerenciadas pela AWS, escolha required-tags.
- Clique em Próximo.
Figura 2 – Tela Especificar tipo de regra
Na tela Configurar regra, use as configurações abaixo:
Na seção Detalhes:
- No campo Nome, coloque required-tags
- No campo Descrição, coloque uma descrição.
Na seção Gatilho:
- Para Escopo das mudanças, escolha Todas as alterações.
Na seção Parâmetros:
- Para o campo Chave, coloque tag1Key para a primeira tag e tag1Value para o valor da primeira tag.
- Para o campo Valor, coloque CostCenter para o valor da chave tag1Key e deixe em branco para a chave tag1Value
- Clique em Próximo.
Caso queira incluir mais tags, clique no botão Adicionar outra linha.
Figura 3 – Tela Configurar regra no Config
Na tela Analisar e criar, clique no botão Adicionar regra.
Depois da criação da regra, o AWS Config irá executar a avaliação dos recursos e exibir se eles estão compatíveis ou não. Essa verificação poderá demorar alguns minutos até ser executada.
Abaixo podemos ver o resultado da verificação e a lista com recursos identificados sem a tag CostCenter.
Figura 4 – Tela Regra required-tags
Passo 3: Crie uma função AWS Lambda.
Para inserirmos as tags nos recursos AWS que foram classificados como não compatíveis, criaremos uma função AWS Lambda que será executada por uma regra no Amazon EventBridge. Essa função AWS Lambda receberá o Id e o tipo do recurso AWS, fará uma pesquisa no AWS Config para obter o ARN do recurso e por fim fará a inserção da tag usando a API do serviço Resource Groups.
Para fazer a criação entre no serviço AWS Lambda, clique no botão Criar Função e use as configurações abaixo:
- Deixei a opção Criar do zero
- No campo Nome da função, insira o nome lambda-put-tag.
- No campo Tempo de execução, selecione Python 3.9.
- Em Arquitetura, selecione arm64.
- Deixe todos os outros campos sem alterá-los e clique em Criar função.
Após a criação será exibida a tela com as configurações da função AWS Lambda, na aba código, substitua o código da janela lambda_function pelo código abaixo e clique no botão Deploy.
import json
import boto3
client = boto3.client('resourcegroupstaggingapi')
conf = boto3.client('config')
def lambda_handler(event, context):
successesResources = []
FailedResources = []
typeComplient = event["typeComplient"]
if typeComplient == "NON_COMPLIANT":
resourcesArn = getARN(event["resourceType"],event["resourceId"])
tags = event["requiredTags"]
for arn in resourcesArn:
try:
numberARN = json.loads(arn)
response = client.tag_resources(ResourceARNList = [numberARN["arn"]], Tags = tags)
successesResources.append(arn)
except Exception as e:
errorMsg = str(e)
FailedResources.append({'ResourceArn': arn , "error": errorMsg})
out = {
"SuccessesResources": successesResources,
"FailedResources": FailedResources
}
return out
def getARN(resourceType, resourceID):
try:
query = "SELECT arn WHERE resourceId='" + resourceID + "' AND resourceType='" + resourceType + "'"
resp = conf.select_resource_config(Expression=query)['Results']
return resp
except Exception as e:
errorMsg = str(e)
FailedResources.append({'ResourceArn': arn , "error": errorMsg})
Clique na aba Configuração, no menu lateral esquerdo clique em Configuração geral e clique no botão Editar. Use as configurações abaixo:
- No campo memória, altere o valor para 512.
- No campo Tempo limite, altere o valor para 1 min e 0
- Clique em Salvar.
Agora iremos incluir as permissões necessárias para a função AWS Lambda poder acessar os serviços necessários para efetuar a inclusão das tags.
Ainda na aba Configuração, clique em Permissões no menu lateral esquerdo, na seção Papel de execução, clique no nome da função.
Será aberta a tela com a configuração da função IAM com as políticas de permissões de execução da função AWS Lambda. Nessa função IAM já existirá uma política com permissão para criação de logs, adicione as políticas abaixo nessa função IAM. Para saber como incluir políticas em uma função do IAM, clique nesse link: https://docs.aws.amazon.com/pt_br/IAM/latest/UserGuide/access_policies_manage-edit.html
Inclua as políticas seguindo os passos abaixo:
- Na aba Permissões, clique no botão Adicionar permissões e clique em Criar política em linha.
Figura 5 – Tela Funçao IAM
- Na tela Criar política, clique na aba JSON e cole a definição das políticas abaixo na janela.
- Clique em Revisar política.
- Insira um nome para a política e clique no botão Criar política.
Figura 6 – Tela Criar política
Execute os passos acima para inserir cada uma das políticas abaixo.
- Política para permitir a pesquisa de ARN no AWS Config:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "config:SelectResourceConfig",
"Resource": "*"
}
]
}
- Política para permitir a execução API do serviço Resource Groups:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"tag:getResources",
"tag:getTagKeys",
"tag:getTagValues",
"tag:TagResources",
"tag:UntagResources"
],
"Resource": "*"
}
]
}
- Para este blog post iremos incluir apenas as permissões para inserir tags no Amazon EC2, para outros recursos AWS, adicione as permissões necessárias de acordo com o tipo de recurso.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeTags",
"ec2:CreateTags"
],
"Resource": "*"
}
]
}
Passo 3: Crie uma regra no Amazon EventBridge
Crie uma regra no Amazon EventBridge para que ela seja acionada quando um recurso AWS for classificado como não compatível e faça a execução de uma função AWS Lambda para posteriormente inserir a tag nesse recurso. Para criar a regra, entre no serviço Amazon EventBridge, clique em Regras e depois clique no botão Criar regra.
Na tela Definir detalhes da regra, use as configurações abaixo:
- Para o campo Nome, insira o valor Inserir-tag.
- Para o campo Descrição, insira uma descrição.
- Em Barramento de eventos, deixe o valor default.
- Nos outros campos, deixe os valores já selecionados e clique em Próximo.
Figura 7 – Tela Definir detalhes da regra
Para a tela Criar padrão de eventos, use as configurações abaixo:
Na seção Fonte do evento, deixe a primeira opção selecionada.
Na seção Evento de exemplo – opcional, não altere nenhum campo.
Na seção Padrão de eventos, use as configurações abaixo:
- Para o campo Fonte do evento, selecione Serviços da AWS.
- Para o campo Serviço da AWS, selecione Config.
- Para o campo Tipo de evento, selecione Config Rules Compliance Change.
- Selecione Qualquer tipo de mensagem.
- Selecione Nomes de regra específicos.
- Insira o nome da regra criada no AWS Config.
- Deixe todos os outros campos sem alterá-los e clique em Próximo.
Figura 8 – Tela Criar padrão de eventos
Na tela Selecionar destinos, use as configurações abaixo:
Na seção Destino 1, use as configurações abaixo:
- No campo Tipos de destino, selecione Serviços da AWS.
- No campo Selecionar um destino, selecione Função do Lambda.
- Em Função, selecione o nome da AWS Lambda criada no Passo 2.
- Expanda o campo Configurações adicionais.
- Em Configurar entrada e destino, selecione Transformador de entrada.
- Clique no botão Configurar transformador de entrada.
Será aberta uma janela onde iremos fazer uma alteração no payload que será enviado para a função AWS Lambda. Para isso use as configurações abaixo:
Desça até a seção Transformados de entrada de destino.
- Na janela Caminho de entrada, insira o trecho:
{
"resourceID": "$.detail.newEvaluationResult.evaluationResultIdentifier.evaluationResultQualifier.resourceId",
"resourceType": "$.detail.newEvaluationResult.evaluationResultIdentifier.evaluationResultQualifier.resourceType",
"typeComplient": "$.detail.newEvaluationResult.complianceType"
}
- Na janela Modelo, insira o trecho abaixo:
{
"resourceType": "<resourceType>",
"resourceId": "<resourceID>",
"typeComplient": "<typeComplient>",
"requiredTags": {"CostCenter": "45678"}
}
- Clique em Confirmar.
- Deixe os demais campos sem alterá-los e clique em Próximo duas vezes e depois em Criar regra.
Figura 9 – Tela Selecionar destinos
Testando a solução
Após concluirmos as configurações acima, já podemos efetuar um teste. Como no Passo 3 incluímos a permissão apenas para incluir tags no Amazon EC2, nosso teste será fazendo a criação de uma instância sem nenhuma tag e aguardar que seja inserida a tag automaticamente.
Lembrando que para que a solução seja capaz de inserir tags em outros tipos de recurso é necessário a inclusão de políticas de IAM com permissões para os serviços desejados na função IAM do AWS Lambda.
Abaixo podemos ver a tag CostCenter, com valor 45678, inserida de forma automática pela nossa solução após a criação da instância.
Figura 10 – Tela detalhes da instância Amazon EC2
Conclusão
Nesse blog post vimos como implementar uma solução automatizada para detectar e inserir tags em recursos que são criados sem tags obrigatórias de forma simples. Essa solução permite que você insira tags em diferentes tipos de recursos, permitindo assim um maior controle sobre os custos e uso dos serviços na AWS.
Acerca do autor
Ricardo Marques é Senior Solutions Architect na AWS, com mais de 15 anos de experiência em desenvolvimento de software, arquiteturas de soluções escaláveis, cloud native, microsserviços, Serverless e segurança. Ele trabalha apoiando clientes nativos digitais, ajudando-os em sua jornada para a nuvem.