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
- Nome da Função: CE-Exporter-MySQL
- 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
- Diretório Local: Crie um diretório local para armazenar o código da Lambda.
- 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 MySQLMYSQL_PASSWORD
: Senha do usuário do banco de dados MySQLMYSQL_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