Amazon Aurora MySQL DB 클러스터에서 Lambda 함수 호출 - Amazon Aurora

Amazon Aurora MySQL DB 클러스터에서 Lambda 함수 호출

네이티브 함수 lambda_sync 또는 lambda_async를 사용하여 Amazon Aurora MySQL 호환 버전 DB 클러스터에서 AWS Lambda 함수를 호출할 수 있습니다. Aurora MySQL에서 Lambda 함수를 호출하기 전에 Aurora DB 클러스터가 Lambda에 액세스해야 합니다. Aurora MySQL에 액세스 권한을 부여하는 방법에 대한 자세한 내용은 Aurora에 Lambda에 대한 액세스 권한 부여 섹션을 참조하세요. lambda_synclambda_async 저장 함수에 대한 자세한 내용은 Aurora MySQL 네이티브 함수로 Lambda 함수 호출 섹션을 참조하세요.

또한 저장 프로시저를 사용하여 AWS Lambda 함수를 호출할 수 있습니다. 그러나 저장 프로시저는 더 이상 사용되지 않습니다. 다음 Aurora MySQL 버전 중 하나를 사용 중인 경우 Aurora MySQL 네이티브 함수를 사용할 것을 적극 권장합니다.

  • MySQL 5.7 호환 클러스터의 경우 Aurora MySQL 버전 2.

  • MySQL 8.0 호환 클러스터의 경우 Aurora MySQL 버전 3.01 이상. Aurora MySQL 버전 3에서는 저장 프로시저를 사용할 수 없습니다.

Aurora에 Lambda에 대한 액세스 권한 부여

Aurora MySQL DB 클러스터에서 Lambda 함수를 호출하기 전에 먼저 클러스터에 Lambda 액세스 권한을 부여해야 합니다.

Aurora MySQL에 Lambda에 대한 액세스 권한을 부여하려면
  1. Aurora MySQL DB 클러스터에서 Lambda 함수를 호출하도록 허용하는 권한을 제공하는 AWS Identity and Access Management(IAM) 정책을 생성하세요. 지침은 AWS Lambda 리소스에 액세스할 수 있는 IAM 정책 생성 섹션을 참조하세요.

  2. IAM 역할을 생성하고 AWS Lambda 리소스에 액세스할 수 있는 IAM 정책 생성에서 생성한 IAM 정책을 새 IAM 역할에 연결하십시오. 지침은 Amazon Aurora에서 AWS 서비스에 액세스하도록 허용하는 IAM 역할 생성 섹션을 참조하세요.

  3. aws_default_lambda_role DB 클러스터 파라미터를 새 IAM 역할의 Amazon 리소스 이름(ARN)으로 설정하십시오.

    클러스터가 Aurora 글로벌 데이터베이스의 일부로 포함되는 경우 글로벌 데이터베이스의 각 Aurora 클러스터에 대해 동일한 설정을 적용합니다.

    DB 클러스터 파라미터에 대한 자세한 내용은 Amazon Aurora DB 클러스터와 DB 인스턴스 파라미터 단원을 참조하십시오.

  4. Aurora MySQL DB 클러스터의 데이터베이스 사용자가 Lambda 함수를 호출하도록 허용하려면 Amazon Aurora에서 AWS 서비스에 액세스하도록 허용하는 IAM 역할 생성에서 생성한 역할을 해당 DB 클러스터와 연결하십시오. IAM 역할과 DB 클러스터 연결에 대한 자세한 내용은 IAM 역할을 Amazon Aurora MySQL DB 클러스터와 연결 단원을 참조하십시오.

    클러스터가 Aurora 글로벌 데이터베이스의 일부로 포함되는 경우 해당 역할을 글로벌 데이터베이스의 각 Aurora 클러스터와 연결합니다.

  5. Lambda으로의 아웃바운드 연결을 허용하도록 Aurora MySQL DB 클러스터를 구성하십시오. 지침은 Amazon Aurora MySQL에서 다른 AWS 서비스로의 네트워크 통신 활성화 섹션을 참조하세요.

    클러스터가 Aurora 글로벌 데이터베이스의 일부로 포함되는 경우 글로벌 데이터베이스의 각 Aurora 클러스터에 대해 발신 연결을 활성화합니다.

Aurora MySQL 네이티브 함수로 Lambda 함수 호출

참고

Aurora MySQL 버전 2 또는 Aurora MySQL 3.01 이상을 사용하는 경우 lambda_synclambda_async 네이티브 함수를 호출할 수 있습니다. Aurora MySQL 버전에 대한 자세한 내용은 Amazon Aurora MySQL에 대한 데이터베이스 엔진 업데이트 단원을 참조하십시오.

네이티브 함수 lambda_synclambda_async를 호출하여 Aurora MySQL DB 클러스터에서 AWS Lambda 함수를 호출할 수 있습니다. 이 방식은 Aurora MySQL에서 실행 중인 데이터베이스를 다른 AWS 서비스와 통합하려는 경우에 유용합니다. 예를 들어 데이터베이스의 특정 테이블에 행이 삽입될 때마다 Amazon Simple Notification Service(Amazon SNS)를 사용하여 알림을 보낼 수 있습니다.

Lambda 함수를 호출하기 위해 네이티브 함수로 작업

lambda_synclambda_async 함수는 내장된 네이티브 함수이며 동기적 또는 비동기적으로 Lambda 함수를 호출합니다. 다른 작업으로 넘어가기 전에 Lambda 함수의 결과를 알아야 하는 경우, 동기식 함수 lambda_sync를 사용합니다. 다른 작업으로 넘어가기 전에 Lambda함수의 결과를 알 필요가 없는 경우, 비동기식 함수 lambda_async를 사용합니다.

Aurora MySQL 버전 3에서의 역할 부여

Aurora MySQL 버전 3에서는 네이티브 함수를 호출하는 사용자에게는 AWS_LAMBDA_ACCESS 역할이 부여되어야 합니다. 사용자에게 이 역할을 부여하려면 관리자 사용자로 DB 인스턴스에 연결하고 다음 명령문을 실행합니다.

GRANT AWS_LAMBDA_ACCESS TO user@domain-or-ip-address

다음 명령문을 실행하여 이 역할을 호출할 수 있습니다.

REVOKE AWS_LAMBDA_ACCESS FROM user@domain-or-ip-address
작은 정보

Aurora MySQL 버전 3에서 역할을 사용하는 경우 SET ROLE role_name 또는 SET ROLE ALL 문을 사용하여 해당 역할을 활성화할 수도 있습니다. MySQL 8.0 역할 시스템에 익숙하지 않을 경우 역할 기반 권한 모델에서 자세한 내용을 확인할 수 있습니다. 자세한 내용은 MySQL 참조 설명서의 역할 사용을 참조하세요.

이는 현재 활성 세션에만 적용됩니다. 다시 연결할 때 권한을 부여하려면 SET ROLE 문을 다시 실행해야 합니다. 자세한 내용은 MySQL 참조 매뉴얼의 SET ROLE 문을 참조하세요.

activate_all_roles_on_login DB 클러스터 파라미터로 사용자가 DB 인스턴스에 연결할 때 모든 역할을 자동으로 활성화할 수 있습니다. 이 파라미터를 설정하면 역할을 활성화하는 데 SET ROLE 문을 명시적으로 직접 호출할 필요가 없습니다. 자세한 내용은 MySQL Reference Manual(MySQL 참조 매뉴얼)의 activate_all_roles_on_login을 참조하세요.

하지만 다른 사용자가 저장 프로시저를 직접 호출한 경우에는 저장 프로시저를 시작할 때 명시적으로 SET ROLE ALL을 직접 호출하여 역할을 활성화해야 합니다.

Lambda 함수를 간접적으로 호출하려고 할 때 다음과 같은 오류가 발생하면 SET ROLE 문을 실행합니다.

SQL Error [1227] [42000]: Access denied; you need (at least one of) the Invoke Lambda privilege(s) for this operation

Aurora MySQL 버전 2에서의 권한 부여

Aurora MySQL 버전 2에서 네이티브 함수를 호출하는 사용자에게는 INVOKE LAMBDA 권한이 부여되어야 합니다. 사용자에게 이 권한을 부여하려면 관리자 사용자로 DB 인스턴스에 연결하고 다음 명령문을 실행합니다.

GRANT INVOKE LAMBDA ON *.* TO user@domain-or-ip-address

다음 명령문을 실행하여 이 권한을 호출할 수 있습니다.

REVOKE INVOKE LAMBDA ON *.* FROM user@domain-or-ip-address

lambda_sync 함수의 구문

lambda_sync 호출 유형으로 RequestResponse 함수를 동기식으로 호출합니다. 함수가 JSON 페이로드에서 Lambda 호출 결과를 반환합니다. 함수에는 다음과 같은 구문이 있습니다.

lambda_sync ( lambda_function_ARN, JSON_payload )

lambda_sync 함수의 파라미터

lambda_sync 함수에는 다음과 같은 파라미터가 있습니다.

lambda_function_ARN

호출할 Lambda 함수의 Amazon 리소스 이름(ARN)입니다.

JSON_payload

JSON 형식으로 호출된 Lambda 함수의 페이로드입니다.

참고

Aurora MySQL 버전 3은 MySQL 8.0의 JSON 구문 분석 함수를 지원합니다. 그러나 Aurora MySQL 버전 2에는 이러한 함수가 포함되어 있지 않습니다. Lambda 함수가 숫자 또는 문자열과 같은 원자 값을 반환할 때 JSON 구문 분석이 필요하지 않습니다.

lambda_sync 함수의 예

lambda_sync를 기반으로 하는 다음 쿼리는 함수 ARN을 사용하여 Lambda 함수 BasicTestLambda를 동기식으로 호출합니다. 함수에 대한 페이로드는 {"operation": "ping"}입니다.

SELECT lambda_sync( 'arn:aws:lambda:us-east-1:123456789012:function:BasicTestLambda', '{"operation": "ping"}');

lambda_async 함수의 구문

lambda_async 호출 유형으로 Event 함수를 비동기식으로 호출합니다. 함수가 JSON 페이로드에서 Lambda 호출 결과를 반환합니다. 함수에는 다음과 같은 구문이 있습니다.

lambda_async ( lambda_function_ARN, JSON_payload )

lambda_async 함수의 파라미터

lambda_async 함수에는 다음과 같은 파라미터가 있습니다.

lambda_function_ARN

호출할 Lambda 함수의 Amazon 리소스 이름(ARN)입니다.

JSON_payload

JSON 형식으로 호출된 Lambda 함수의 페이로드입니다.

참고

Aurora MySQL 버전 3은 MySQL 8.0의 JSON 구문 분석 함수를 지원합니다. 그러나 Aurora MySQL 버전 2에는 이러한 함수가 포함되어 있지 않습니다. Lambda 함수가 숫자 또는 문자열과 같은 원자 값을 반환할 때 JSON 구문 분석이 필요하지 않습니다.

lambda_async 함수의 예

lambda_async를 기반으로 하는 다음 쿼리는 함수 ARN을 사용하여 Lambda 함수 BasicTestLambda를 비동기식으로 호출합니다. 함수에 대한 페이로드는 {"operation": "ping"}입니다.

SELECT lambda_async( 'arn:aws:lambda:us-east-1:123456789012:function:BasicTestLambda', '{"operation": "ping"}');

트리거 내에서 Lambda 함수 호출

트리거를 사용하여 데이터 수정 문에서 Lambda을 호출할 수 있습니다. 다음 예제에서는 lambda_async 기본 함수를 사용하고 결과를 변수에 저장합니다.

mysql>SET @result=0; mysql>DELIMITER // mysql>CREATE TRIGGER myFirstTrigger AFTER INSERT ON Test_trigger FOR EACH ROW BEGIN SELECT lambda_async( 'arn:aws:lambda:us-east-1:123456789012:function:BasicTestLambda', '{"operation": "ping"}') INTO @result; END; // mysql>DELIMITER ;
참고

트리거는 SQL 문당 한 번이 아니라 수정된 행당 한 번 실행되며 한 번에 한 행씩 실행됩니다. 트리거가 실행되면 프로세스는 동기식입니다. 트리거가 완료될 때만 데이터 수정 문이 반환합니다.

쓰기 트래픽이 높은 테이블의 트리거에서 AWS Lambda 함수를 호출할 때는 주의해야 합니다. INSERT, UPDATEDELETE 트리거는 행별로 활성화됩니다. INSERT, UPDATE 또는 DELETE 트리거가 있는 테이블에서 쓰기가 많은 워크로드는 AWS Lambda 함수에 다량의 호출을 야기합니다.

Aurora MySQL 저장 프로시저(사용되지 않음)로 Lambda 함수 호출

mysql.lambda_async 프로시저를 호출하여 Aurora MySQL DB 클러스터에서 AWS Lambda 함수를 호출할 수 있습니다. 이 방식은 Aurora MySQL에서 실행 중인 데이터베이스를 다른 AWS 서비스와 통합하려는 경우에 유용합니다. 예를 들어 데이터베이스의 특정 테이블에 행이 삽입될 때마다 Amazon Simple Notification Service(Amazon SNS)를 사용하여 알림을 보낼 수 있습니다.

Aurora MySQL 버전 고려 사항

Aurora MySQL 버전 2부터 이러한 저장 프로시저 대신 네이티브 함수 메서드를 사용하여 Lambda 함수를 호출할 수 있습니다. 네이티브 함수에 대한 자세한 내용은 Lambda 함수를 호출하기 위해 네이티브 함수로 작업 단원을 참조하십시오.

Aurora MySQL 버전 2에서 mysql.lambda_async 저장 프로시저는 더 이상 지원되지 않습니다. 대신 네이티브 Lambda 함수를 사용하는 것을 권장합니다.

Aurora MySQL 버전 3에서 저장 프로시저는 사용할 수 없습니다.

Lambda 함수(사용되지 않음) 호출을 위한 mysql.lambda_async 프로시저로 작업

mysql.lambda_async 프로시저는 Lambda 함수를 비동기 방식으로 호출하는 기본 제공 저장 프로시저입니다. 이 프로시저를 사용하려면 데이터베이스 사용자가 EXECUTE 저장 프로시저에 대한 mysql.lambda_async 권한이 있어야 합니다.

구문

mysql.lambda_async 프로시저에는 다음과 같은 구문이 있습니다.

CALL mysql.lambda_async ( lambda_function_ARN, lambda_function_input )

파라미터

mysql.lambda_async 프로시저에는 다음과 같은 파라미터가 있습니다.

lambda_function_ARN

호출할 Lambda 함수의 Amazon 리소스 이름(ARN)입니다.

lambda_function_input

호출되는 Lambda 함수에 대한 입력 문자열(JSON 형식)입니다.

예제

트리거나 클라이언트 코드와 같은 여러 소스에서 호출할 수 있는 저장 프로시저의 mysql.lambda_async 프로시저에 대한 호출을 래핑하는 것이 좋습니다. 이 방식을 사용하면 임피던스 불일치 문제를 방지하고 Lambda 함수를 보다 쉽게 호출할 수 있습니다.

참고

쓰기 트래픽이 높은 테이블의 트리거에서 AWS Lambda 함수를 호출할 때는 주의해야 합니다. INSERT, UPDATEDELETE 트리거는 행별로 활성화됩니다. INSERT, UPDATE 또는 DELETE 트리거가 있는 테이블에서 쓰기가 많은 워크로드는 AWS Lambda 함수에 다량의 호출을 야기합니다.

mysql.lambda_async 절차에 대한 호출은 비동기식이지만 트리거는 동기식입니다. 다량의 트리거 활성화를 야기하는 명령문은 AWS Lambda 기능 종료에 대한 호출을 기다리지 않고, 다만 트리거 종료를 기다린 다음에 클라이언트로 제어를 돌려줍니다.

예: AWS Lambda 함수를 호출하여 이메일 보내기

다음 예제에서는 Lambda 함수를 사용하여 이메일을 보내기 위해 데이터베이스 코드에서 호출할 수 있는 저장 프로시저를 생성합니다.

AWS Lambda 함수

import boto3 ses = boto3.client('ses') def SES_send_email(event, context): return ses.send_email( Source=event['email_from'], Destination={ 'ToAddresses': [ event['email_to'], ] }, Message={ 'Subject': { 'Data': event['email_subject'] }, 'Body': { 'Text': { 'Data': event['email_body'] } } } )

저장 프로시저

DROP PROCEDURE IF EXISTS SES_send_email; DELIMITER ;; CREATE PROCEDURE SES_send_email(IN email_from VARCHAR(255), IN email_to VARCHAR(255), IN subject VARCHAR(255), IN body TEXT) LANGUAGE SQL BEGIN CALL mysql.lambda_async( 'arn:aws:lambda:us-west-2:123456789012:function:SES_send_email', CONCAT('{"email_to" : "', email_to, '", "email_from" : "', email_from, '", "email_subject" : "', subject, '", "email_body" : "', body, '"}') ); END ;; DELIMITER ;

저장 프로시저를 호출하여 AWS Lambda 함수 호출

mysql> call SES_send_email('example_from@amazon.com', 'example_to@amazon.com', 'Email subject', 'Email content');
예: AWS Lambda 함수를 호출하여 트리거에서 이벤트 게시

다음 예제에서는 Amazon SNS를 사용하여 이벤트를 게시하는 저장 프로시저를 생성합니다. 이 코드는 테이블에 행이 추가되면 트리거에서 프로시저를 호출합니다.

AWS Lambda 함수

import boto3 sns = boto3.client('sns') def SNS_publish_message(event, context): return sns.publish( TopicArn='arn:aws:sns:us-west-2:123456789012:Sample_Topic', Message=event['message'], Subject=event['subject'], MessageStructure='string' )

저장 프로시저

DROP PROCEDURE IF EXISTS SNS_Publish_Message; DELIMITER ;; CREATE PROCEDURE SNS_Publish_Message (IN subject VARCHAR(255), IN message TEXT) LANGUAGE SQL BEGIN CALL mysql.lambda_async('arn:aws:lambda:us-west-2:123456789012:function:SNS_publish_message', CONCAT('{ "subject" : "', subject, '", "message" : "', message, '" }') ); END ;; DELIMITER ;

CREATE TABLE 'Customer_Feedback' ( 'id' int(11) NOT NULL AUTO_INCREMENT, 'customer_name' varchar(255) NOT NULL, 'customer_feedback' varchar(1024) NOT NULL, PRIMARY KEY ('id') ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

트리거

DELIMITER ;; CREATE TRIGGER TR_Customer_Feedback_AI AFTER INSERT ON Customer_Feedback FOR EACH ROW BEGIN SELECT CONCAT('New customer feedback from ', NEW.customer_name), NEW.customer_feedback INTO @subject, @feedback; CALL SNS_Publish_Message(@subject, @feedback); END ;; DELIMITER ;

알림 트리거를 위하여 테이블에 행 삽입

mysql> insert into Customer_Feedback (customer_name, customer_feedback) VALUES ('Sample Customer', 'Good job guys!');