Entenda o risco das políticas. Faça perguntas sobre políticas em linguagem natural. Solicite uma demonstração →
Published:
A forma excessivamente complexa como o CloudTrail e o CloudWatch Events funcionam em conjunto
by FireMon
Uma das questões mais complicadas do meu percurso na cloud tem sido entender como o CloudTrail e o CloudWatch Events funcionam em conjunto. Por alguma razão, levei anos (e muitos testes) para compreender como a ligação realmente funciona; e, sobretudo, como funciona com o conceito de trails multirregião e de AWS Organization. Depois, quando finalmente percebi tudo, presumi que todos já soubessem, mas conversas recentes deixaram claro que esta confusão é bastante comum. Eis, então, a minha melhor tentativa de simplificar as coisas.
Primeiro, o problema que procuramos resolver: criar CloudWatch Rules baseadas em eventos do CloudTrail e utilizá-las para enviar notificações ou acionar funções Lambda.
É isso — quero enviar uma notificação para algo simples como a chamada de API que abre uma nova regra de security group (AuthorizeSecurityGroupIngress, caso tenha curiosidade).
Para que isto funcione, é necessário ter o seguinte implementado:
- CloudTrail ativado na região onde a chamada de API é feita.
- CloudTrail a transmitir para o CloudWatch.
- Uma CloudWatch Rule na região da chamada de API que procure essa chamada de API específica, ou todas as chamadas de API do CloudTrail.
Agora, a confusão:
- Quando cria um CloudTrail multirregião ou um Organization trail, nos bastidores a AWS está efetivamente a configurar trails em cada uma das regiões (e em cada conta, no caso de um Org trail). São todos trails separados, mas cada um está configurado para enviar os seus resultados para um bucket S3 partilhado, e só é possível gerir cada um na respetiva conta e região de origem.
- No entanto, os eventos do CloudWatch para chamadas de API só são criados na região da chamada de API.
- Assim, se criar um trail multirregião, os dados são todos recolhidos centralmente, mas os eventos aparecem apenas localmente. Uma CloudWatch Rule na região do trail de origem só será acionada por chamadas de API feitas nessa região (de origem). Portanto, se criar um alarme para alterações de security groups, este só funcionará na região de origem — não nas outras regiões — mesmo estando o CloudTrail ativado.
- O CloudWatch Log Group/Stream aparecerá na região primária, não nas outras regiões, mas cada evento é criado na região que o originou.
- Se quiser recolher todos os eventos de chamadas de API, tem de utilizar uma definição de evento não documentada (que colei abaixo).
- Se ler a documentação da Amazon… nada disto é explicado com clareza. Pelo menos não consegui encontrar. Na verdade, estive uma vez numa chamada de suporte em que cheguei à conclusão, e o representante da AWS continuava a murmurar: “Não creio que funcione assim”, enquanto os meus eventos começavam a chegar. Estava a ter uma noite difícil.
Por alguma razão, isto foi pouco intuitivo para mim. Tinha presumido que, ao centralizar o trail, seria possível centralizar a CloudWatch Rule para ser acionada por eventos de chamadas de API. Infelizmente, isso estava totalmente errado e, mesmo centralizando o trail, continua a ser necessário criar a Rule em cada região que lhe interesse. Mesmo que utilize o Event Bus para recolher eventos de várias contas, continua a ser necessário criar uma CloudWatch Rule em cada região de cada conta para enviar o evento para o Bus e, depois, criar Rules em cada região do Event Bus para acionar a notificação/ação pretendida.
Eis como recomendo abordar esta questão se pretender as capacidades de alerta quase em tempo real ou a remediação/ações automáticas suportadas pelas CloudWatch Rules:
- Ative um trail multirregião. Só precisa de o fazer uma vez, e um Organization trail é suficiente.
- Isto cria todos os trails regionais de que necessita. Parece um único trail central, mas é na realidade um conjunto de trails regionais que enviam os seus dados para um recetor central.
- Opção 1: crie uma CloudWatch Rule em cada região para a qual pretenda alertas quase em tempo real. O CloudFormation e o Terraform são aliados valiosos nesta fase.
- Opção 2: centralize todos os seus eventos. Em cada região, crie uma Rule para enviar todos os eventos do CloudTrail para uma função Lambda ou um tópico SNS, que depois os encaminha para o seu destino. Nós próprios utilizamos esta técnica; enviamos através de um endpoint de API personalizado, mas pode transmitir para o Kinesis ou praticamente qualquer destino.
Para dar início ao seu percurso, ficam dois exemplos de código.
O padrão de filtro secreto para a sua CloudWatch Rule recolher todos os eventos do CloudTrail:
{
"detail-type": [
"AWS API Call via CloudTrail"
] }
E eis um exemplo de código Lambda para encaminhar eventos, neste caso, para o Kinesis:
import json
import boto3
def lambda_handler(event, context):
kinesis = boto3.client('kinesis', region_name='us-west-2')
data = json.dumps(event)
print(data)
response = kinesis.put_record(
StreamName='cloudsec_prod_stream_alert_kinesis',
Data=data,
PartitionKey='test-client-id'
)
print(response)
return {
'statusCode': 200,
'body': json.dumps('Record added')
}