Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Como Configurar uma Função Lambda com Python para Exportar Custos da AWS para um Banco de Dados MySQL

Neste tutorial, vamos detalhar o processo de criação e configuração de uma função Lambda que exporta os custos do AWS Cost Explorer para um banco de dados MySQL. Esse processo envolve a criação da função Lambda, configuração do banco de dados MySQL. Vamos ao passo a passo:

Passo 1: Criar a Função Lambda

  1. Nome da Função: CE-Exporter-MySQL
  2. Linguagem: Python 3.12

Passo 2: Configurar o Banco de Dados MySQL

Execute os seguintes comandos no seu servidor MySQL para criar o banco de dados e a tabela necessária:

CREATE DATABASE IF NOT EXISTS ResourceCosts;
USE ResourceCosts;

CREATE TABLE costs (
  id int AUTO_INCREMENT PRIMARY KEY,
  account_id varchar(20),
  region varchar(50),
  service varchar(50),
  amount decimal(10,2),
  currency_unit varchar(10),
  start_time datetime,
  end_time datetime
);

ALTER TABLE costs
  ADD KEY idx_costs_account_region_service (account_id, region, service);

Passo 3: Criar a Pasta do Código do Lambda

  1. Diretório Local: Crie um diretório local para armazenar o código da Lambda.
  2. Dependências: Crie um arquivo requirements.txt com o seguinte conteúdo:
pymysql
boto3

Passo 4: Instalar Dependências

No terminal, execute o comando abaixo para instalar as dependências no diretório local:

pip3 install -r requirements.txt -t .

Passo 5: Adicionar o Código Fonte

Crie um arquivo chamado lambda_function.py no mesmo diretório e adicione o seguinte código:

import boto3
import pymysql
import os
import datetime

# Configurações MySQL
MYSQL_DB = os.getenv('MYSQL_DB')
MYSQL_HOST = os.getenv('MYSQL_HOST')
MYSQL_PASSWORD = os.getenv('MYSQL_PASSWORD')
MYSQL_PORT = int(os.getenv('MYSQL_PORT'))
MYSQL_USER = os.getenv('MYSQL_USER')

# Classe para manipulação de dados do Cost Explorer e MySQL
class CostExplorerToMySQL:
    def __init__(self):
        self.ce_client = boto3.client('ce')
        self.sts_client = boto3.client('sts')
        self.conn = pymysql.connect(host=MYSQL_HOST,
                                    user=MYSQL_USER,
                                    password=MYSQL_PASSWORD,
                                    db=MYSQL_DB,
                                    port=MYSQL_PORT)
        self.account_id = self.get_account_id()

    def get_account_id(self):
        response = self.sts_client.get_caller_identity()
        return response['Account']

    def fetch_cost_data(self, start_date, end_date):
        results = []
        response = self.ce_client.get_cost_and_usage(
            TimePeriod={'Start': start_date, 'End': end_date},
            Granularity='DAILY',
            Metrics=['UnblendedCost'],
            GroupBy=[
                {'Type': 'DIMENSION', 'Key': 'REGION'},
                {'Type': 'DIMENSION', 'Key': 'SERVICE'}
            ]
        )
        results.extend(response['ResultsByTime'])
        while 'nextToken' in response:
            nextToken = response['nextToken']
            response = self.ce_client.get_cost_and_usage(
                TimePeriod={'Start': start_date, 'End': end_date},
                Granularity='DAILY',
                Metrics=['UnblendedCost'],
                GroupBy=[
                    {'Type': 'DIMENSION', 'Key': 'REGION'},
                    {'Type': 'DIMENSION', 'Key': 'SERVICE'}
                ],
                NextPageToken=nextToken
            )
            results.extend(response['ResultsByTime'])
        return results

    def insert_cost_data(self, data):
        cursor = self.conn.cursor()
        insert_query = """
            INSERT INTO costs (account_id, region, service, amount, currency_unit, start_time, end_time)
            VALUES (%s, %s, %s, %s, %s, %s, %s)
        """
        cursor.executemany(insert_query, data)
        self.conn.commit()

    def process_and_store_data(self, start_date, end_date):
        raw_data = self.fetch_cost_data(start_date, end_date)
        processed_data = []
        for result in raw_data:
            start_time = result['TimePeriod']['Start'] + " 00:00:00"
            end_time = result['TimePeriod']['End'] + " 23:59:59"
            for group in result['Groups']:
                region = group['Keys'][0]
                service = group['Keys'][1]
                amount = float(group['Metrics']['UnblendedCost']['Amount'])
                currency_unit = group['Metrics']['UnblendedCost']['Unit']
                processed_data.append((self.account_id, region, service, amount, currency_unit, start_time, end_time))
        self.insert_cost_data(processed_data)

    def close(self):
        self.conn.close()

def lambda_handler(event, context):
    explorer_to_mysql = CostExplorerToMySQL()
    ontem = datetime.datetime.utcnow() - datetime.timedelta(days=1)
    hoje = datetime.datetime.utcnow()
    start_date = ontem.strftime('%Y-%m-%d')
    end_date = hoje.strftime('%Y-%m-%d')
    explorer_to_mysql.process_and_store_data(start_date, end_date)
    explorer_to_mysql.close()
    return "Report Generated"

Passo 6: Empacotar e Enviar para a AWS

Compacte o conteúdo do diretório em um arquivo ZIP e envie para a função Lambda na AWS:

zip -r aws-ce-exporter-mysql.zip .
aws lambda update-function-code --function-name CE-Exporter-MySQL --zip-file fileb://aws-ce-exporter-mysql.zip
rm -rf aws-ce-exporter-mysql.zip

Passo 7: Criar a Política de IAM

Crie uma política de IAM no console da AWS com o seguinte JSON para permitir as ações ce:GetCostAndUsage e tag:GetResources:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ce:GetCostAndUsage",
                "tag:GetResources"
            ],
            "Resource": "*"
        }
    ]
}

Passo 8: Anexar a Política à Role do Lambda

No console da AWS, vá até a função Lambda CE-Exporter-MySQL, clique em “Configurações de permissão” e anexe a política criada anteriormente à função.

Passo 9: Configurar Variáveis de Ambiente

No console do AWS Lambda, vá para as configurações da sua função Lambda e adicione as seguintes variáveis de ambiente:

  • MYSQL_DB: Nome do banco de dados MySQL (ex.: ResourceCosts)
  • MYSQL_HOST: Endereço do host do banco de dados MySQL
  • MYSQL_PASSWORD: Senha do usuário do banco de dados MySQL
  • MYSQL_PORT: Porta do banco de dados MySQL (geralmente 3306)
  • MYSQL_USER: Usuário do banco de dados MySQL

Passo 10: Ajustar o Tempo de Execução Máximo da Lambda

No Console da AWS, navegue até a função Lambda CE-Exporter-MySQL. Clique na guia Configuration e, em seguida, em General configuration. Clique em Edit para ajustar o tempo de execução máximo. Defina o Timeout para 15 segundos e clique em Save.

Passo 11: Criar o EventBridge para Disparar a Lambda

No Console da AWS, navegue até Amazon EventBridge. Clique em Create rule para criar uma nova regra. Dê um nome à sua regra, como Ce-Exporter-MySQL-EB-Rule, e selecione Rule type como Event pattern. Na seção Event pattern, selecione Scheduled event e insira a expressão de cronograma: cron(0 0 * * ? *) para agendar a execução da Lambda diariamente à 00:00 UTC. Clique em Next.

Conclusão

Com esses passos, a função Lambda CE-Exporter-MySQL estará configurada para executar diariamente, obter os custos do AWS Cost Explorer e inserir esses dados no banco de dados MySQL. Certifique-se de configurar corretamente as variáveis de ambiente para que a função Lambda possa conectar ao banco de dados

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Rolar para cima