Quero criar uma função do AWS Lambda que execute consultas no Amazon Redshift.
Resolução
Pré-requisito: siga estas etapas para configurar os endpoints do Amazon Virtual Private Cloud.
- Crie uma VPC com uma sub-rede privada.
- Crie um grupo de sub-redes. Adicione a VPC e a sub-rede que você acabou de criar.
- Crie um cluster privado do Amazon Redshift. Selecione a VPC e o grupo de sub-redes que você acabou de criar.
- Crie um novo segredo para o Amazon Redshift com o AWS Secrets Manager. Em seu nome secreto, digite redshift.
Crie sua função do Lambda
Para criar uma função do Lambda que consulta o cluster do Amazon Redshift, siga estas etapas:
- Abra o console do Lambda.
- Escolha Criar função.
- Escolha a opção Criar do zero.
- Atualize os seguintes campos:
Em Nome da função, insira um nome personalizado.
Em Runtime, insira seu ambiente de código.
Observação: os exemplos nesta resolução são compatíveis com o Python 3.9.
Em Arquitetura, insira a arquitetura do seu sistema.
Observação: os exemplos nesta resolução são compatíveis com x86_64.
Em Permissões, escolha Criar um novo perfil com permissões básicas do Lambda.
- Escolha Criar função.
Defina as permissões para a função do Lambda
Siga estas etapas:
- Abra o console do Lambda.
- Selecione Configuração.
- Escolha Permissões.
- Escolha o perfil criado para sua função do Lambda.
- Escolha Adicionar permissões.
- Selecione Anexar políticas.
- Adicione as políticas AmazonRedshiftDatafullAccess e SecretsManagerReadWrite ao seu perfil de execução do Lambda.
Observação: é uma prática recomendada conceder o privilégio mínimo apenas às permissões necessárias para realizar uma tarefa.
Adicione o código Python à sua função do Lambda
Neste exemplo, o Lambda se conecta ao banco de dados do Amazon Redshift e cria uma tabela lambda_func no esquema público.
Siga estas etapas:
-
Abra o console do Lambda.
-
Escolha Código.
-
Insira o código a seguir na caixa Código:
import os
import json
import boto3
import botocore
import botocore.session as bc
from botocore.client import Config
print('Loading function')
secret_name=os.environ['SecretId'] # getting SecretId from Environment varibales
session = boto3.session.Session()
region = session.region_name
# Initializing Secret Manager's client
client = session.client(
service_name='secretsmanager',
region_name=region
)
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
secret_arn=get_secret_value_response['ARN']
secret = get_secret_value_response['SecretString']
secret_json = json.loads(secret)
cluster_id=secret_json['dbClusterIdentifier']
# Initializing Botocore client
bc_session = bc.get_session()
session = boto3.Session(
botocore_session=bc_session,
region_name=region
)
# Initializing Redshift's client
config = Config(connect_timeout=5, read_timeout=5)
client_redshift = session.client("redshift-data", config = config)
def lambda_handler(event, context):
print("Entered lambda_handler")
query_str = "create table public.lambda_func (id int);"
try:
result = client_redshift.execute_statement(Database= 'dev', SecretArn= secret_arn, Sql= query_str, ClusterIdentifier= cluster_id)
print("API successfully executed")
except botocore.exceptions.ConnectionError as e:
client_redshift_1 = session.client("redshift-data", config = config)
result = client_redshift_1.execute_statement(Database= 'dev', SecretArn= secret_arn, Sql= query_str, ClusterIdentifier= cluster_id)
print("API executed after reestablishing the connection")
return str(result)
except Exception as e:
raise Exception(e)
return str(result)
Observação: substitua dev pelo nome do seu banco de dados.
-
Adicione uma variável de ambiente na seção de configuração da função do Lambda para a chave SecretID e secret_name.