The Ops Community ⚙️

Cover image for Eventos orientados com Amazon EventBridge
Rafael Conceição
Rafael Conceição

Posted on

Eventos orientados com Amazon EventBridge

As arquiteturas orientadas a eventos (Event-Driven) são caracterizadas por serviços que se comunicam de forma assíncrona e desacoplado através de eventos.

Os serviços transmitirão eventos (Produtores) que serão consumidos e reagidos por outros serviços (Consumidores).

Uma característica que marca uma Arquitetura Event-Drive é que: Produtores e consumidores estão completamente dissociados, um produtor não deve saber ou se importar com quem está consumindo seus eventos.

Event-Driven Architectures Draw

O que seria o Amazon EventBridge?

O Amazon EventBridge é um serviço que oferece acesso em tempo real a alterações de dados em serviços da AWS, em suas aplicações e em aplicações de software como serviço (SaaS) sem precisar escrever código. Para começar, você pode escolher uma origem de eventos no console do EventBridge. Em seguida, pode selecionar um destino entre os serviços da AWS, incluindo o AWS Lambda, o Amazon Simple Notification Service (SNS) e o Amazon Kinesis Data Firehose. O EventBridge entregará automaticamente os eventos quase em tempo real.

Em resumo você pode receber, filtrar, transformar, rotear (dos Produtores) e entregar esses eventos a Consumidores.

Trabalhando com o Amazon EventBridge

Para exemplificar o uso do Amazon EventBridge vamos criar o seguinte cenário:

  • Toda vez que uma instancia RDS for criada queremos que uma Lambda seja executada. Para nosso exemplo a Lambda irá adicionar uma tag.

Utilizaremos então a seguinte arquitetura:

Event-Driven Architectures exemple

  1. Como Produtor de eventos utilizaremos o CloudTrail.
  2. Como Broker, que irá tratar os eventos, utilizaremos o EventBridge
  3. Como Consumer desses eventos utilizaremos a AWS Lambda

O repositório do Github rafaelonline/eventbridge-lambda possui um exemplo de configuração infraestrutura usando Terraform e o script Python utilizado.

Passo 1

Pre-Requisito: É preciso que a conta possua um Trail configurado no CloudTrail, saiba como configurar em Creating a trail

O CloudTrail gera eventos no formato JSON e possui integração nativa com o EventBridge. Ele será nosso Produtor de eventos.

O CloudTrail proporciona visibilidade sobre as atividades de usuários por meio do registro das ações executadas na sua conta. O CloudTrail registra informações importantes sobre cada ação, como quem fez a solicitação, quais serviços foram usados, quais ações foram executadas, quais os parâmetros da ação e quais elementos da resposta foram retornados pelo serviço da AWS

Passo 2

Agora devemos configurar uma regra no EventBridge Rules para monitorar os eventos desejados.

No nosso caso o event pattern será a própria AWS tendo como origem o Cloudtrail e eventos do rds.amazonaws.com de nome CreateDBInstance.

Exemplo no console da AWS:

Exemplo no console da AWS

Exemplo de código Terraform para criação da Rule:

###### EVENTBRIDGE RULE - CREATED RDS INSTANCE ######
resource "aws_cloudwatch_event_rule" "rds_event_rule" {
  name          = "rule-rds-created"
  description   = "Triggers Lambda when new RDS instance are created"
  is_enabled    = true
  event_pattern = <<EOF
    {
    "source": ["aws.rds"],
    "detail-type": ["AWS API Call via CloudTrail"],
    "detail": {
        "eventSource" : ["rds.amazonaws.com"],
        "eventName": ["CreateDBInstance"]
    }
    }
  EOF
}
Enter fullscreen mode Exit fullscreen mode

Passo 3

Agora precisamos encaminhar nosso evento para o Consumidor (Target), que será uma Lambda.

Um Target é um recurso ou endpoint que EventBridge envia um evento para quando o evento corresponde ao padrão de evento definido para uma regra. A regra processa os dados do evento e envia as informações pertinentes ao Target

Podemos encaminhar esse mesmo evento para até cinco (5) Targets, por exemplo enviar um SNS informando que um RDS foi criado, além de executar a Lambda.

Inclusive podemos enviar o evento originalmente como foi gerado, enviar somente uma parte do evento, fazer alguma edição no evento antes de enviar, enviar um json de evento fixo.

Exemplo no console da AWS:

Exemplo no console da AWS

Exemplo de código Terraform para criação do Target:

###### EVENTBRIDGE TARGET - CREATED RDS INSTANCE ######
resource "aws_cloudwatch_event_target" "lambda_rule_rds" {
  depends_on = [aws_lambda_function.autotag]
  rule       = aws_cloudwatch_event_rule.rds_event_rule.name
  target_id  = "SendToLambda"
  arn        = aws_lambda_function.autotag.arn
}
Enter fullscreen mode Exit fullscreen mode

Passo 4

Chegamos ao passo final que é termos o nosso Consumidor, para nosso cenário usaremos uma Lambda que irá adicionar uma Tag a instancia RDS criada.

Script Python que cria a Tag

"""Add tags on RDS and Aurora."""
import logging
import os
import boto3
from botocore.exceptions import ClientError

# Config Logging.
log = logging.getLogger()
log.setLevel(logging.INFO)

def lambda_handler(event, context):
    """Add tags on RDS and Aurora"""

    # Define the tags to add to the RDS instance
    tag_key = os.environ.get('TAG_KEY')
    tag_value = os.environ.get('TAG_VALUE')
    tags = [
        {
            'Key': tag_key,
            'Value': tag_value
        }
    ]

    # Connect to RDS service
    rds = boto3.client('rds')
    event_name = event.get("detail").get("eventName")

    if event_name == "CreateDBCluster":
        aurora_arn = event.get("detail").get("responseElements").get("dBClusterArn")
    # Add tags to the Regional Cluster
        try:
            rds.add_tags_to_resource(
                ResourceName=aurora_arn,
                Tags=tags
            )
            log.info('Tag adicionda com sucesso ao Cluster Aurora: %s', aurora_arn)
        except ClientError as error:
            log.exception(error)

    else:
    # Add tags to the RDS instance
        rds_arn = event.get("detail").get("responseElements").get("dBInstanceArn")
        try:
            rds.add_tags_to_resource(
                ResourceName=rds_arn,
                Tags=tags
            )
            log.info('Tag adicionda com sucesso ao RDS: %s', rds_arn)
        except ClientError as error:
            log.exception(error)        
Enter fullscreen mode Exit fullscreen mode

Exemplo de código Terraform para criação Lambda:

###### GENERATE PACKAGE LAMBDA ###### 
data "archive_file" "lambda_autotag" {
  type        = "zip"
  source_dir  = "${path.module}/code/src"
  output_path = "${path.module}/code/lambda_package.zip"
}

###### LAMBDA FUNCTION ######
resource "aws_lambda_function" "autotag" {
  function_name    = var.autotag_function_name
  role             = aws_iam_role.lambda_exec_role.arn
  filename         = data.archive_file.lambda_autotag.output_path
  source_code_hash = data.archive_file.lambda_autotag.output_base64sha256
  description      = var.autotag_description
  publish          = true

  runtime       = "python3.8"
  handler       = "main.lambda_handler"
  timeout       = 300
  memory_size   = 128
  architectures = ["arm64"]

  environment {
    variables = {
      TAG_KEY   = var.lambda_tag_key
      TAG_VALUE = var.lambda_tag_value
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Saiba Mais

Event-Driven Architectures vs. Event-Based Compute in Serverless Applications

Oldest comments (0)