1. RDS 클러스터에 람다 역할 추가
- IAM 에서 람다 최소권한을 줄수 있는 InvokeFunction 권한 정책 생성
- 위에서 만든 정책을 IAM 역할을 새로 만들어서 역할에 정책 부여
- 이후 RDS 클러스터에 IAM 역할 관리에서 위에서 만든 역할을 할당

2. 람다 함수 생성
- RDS 와 같은 VPC 안에 동일한 서브넷 할당
- 보안그룹 생성 혹은 기존에 있던 RDS 에 할당된 보안그룹 재귀로 받아서 연결
3. RDS 클러스터 파라미터 그룹 생성 및 aws_default_lambda_role 역할 부여
- 파라미터 그룹 Type 에서 DB Cluser Parameter Group 을 선택해 파라미터 그룹 새로 생성

- 파라미터 설정에 aws_default_lambda_role 값에
- 생성한 람다 함수의 ARN role 기입

4. RDS 환경 설정
- AWS 공식문서 참고
- SELECT user,host FROM mysql.user; 쿼리문에 아래처럼 설정되어 있는지 확인

5. 람다 호출 테스트
- SELECT lambda_async('람다ARN','');
정상적으로 호출되면 빈 JSON이 반환됨
6. 트러블 슈팅
- Lambda API returned error: Missing IAM Credentials for specified aws_default_lambda_role
- 1,3 번에 대해 제대로 설정이 안되었을 때 발생
- Lambda API returned error: Network Connection. curlCode: 28, Timeout was reached
- 보안그룹 아웃바운드룰 443 포트 열어줘야 함
- Lambda API returned error: Invalid Request Content. Could not parse request body into json:
Could not parse payload into json:
Illegal unquoted character ((CTRLCHAR, code 10)): has to be escaped using backslash to be included in string value- 인코딩 할때 줄바꿈 이스케이프 문제
- 아래에서 TO_BASE64()를 사용할때 REPLACE 로 개행제거
SET @data = TO_BASE64(CONCAT(
'{
"ID": "', NEW.ID,'",
"NAME": "', NEW.NAME,'",
"DESCRIPTION": "', NEW.DESCRIPTION,'",
}'
));
--
SET @data = REPLACE(TO_BASE64(CONCAT(
'{
"ID": "', NEW.ID,'",
"NAME": "', NEW.NAME,'",
"DESCRIPTION": "', NEW.DESCRIPTION,'",
}'
)),'\n,'');
- MYSQL 컬럼 데이터 타입이 CHAR 인 경우에 null 이 찍히면 키네시스에 아무런 정보도 담기지 않음
- lambda 에서 오류도 내 뱉지 않고 키네시스 for 문이 돌아가지도 않아 하나하나 컬럼 테스트 해본결과
- 고정형 문자열(CHAR) 인 경우 null 말고 해당 길이의 데이터를 기입해야 키네시스가 제대로 돌아감
- Unknown trigger has an error in its body: ‘Access denied; you need (at least one of) the Invoke Lambda privilege(s) for this operation’
시발 이거 삽질을 몇일동안 한건지 좆같은년들 chatGPT 도 개소리하고 구글링해도 안나옴 ㅡㅡ- rds 클러스터 파라미터 그룹에 activate_all_roles_on_login 1 저장
- 이후 아래 sql 문 실행후 trigger 테스트
# activate_all_roles_on_login 1 로 바꾸고 나서 아래 권한 부여
-----
SELECT CURRENT_ROLE()
# 오로라 버전 3이상
GRANT AWS_LAMBDA_ACCESS TO 사용할디비계정@'%';
# 오로라 버전 2이상
GRANT INVOKE LAMBDA ON *.* TO 사용할디비계정@'%';
SET ROLE ALL ;
FLUSH PRIVILEGES;
------
코드 스니펫 (mysql + golang)
MySQL
# 키네시스로 넘기려면 base64 encoding 필요함
SET @data = TO_BASE64(CONCAT('{"operation":"ping"}'));
# 아래 템플릿에 맞춰서 encoding 한 변수 CONCAT 으로 JSON payload 에 넘겨줌
SELECT lambda_async('람다함수ARN',CONCAT('{
"Records":[
{
"kinesis":{
"data":"',@data,'"
}
}
]
}'));
# Trigger
DELIMITER //
CREATE TRIGGER `test_lambda`
AFTER INSERT ON
`사용되어질 테이블 이름` FOR EACH ROW
BEGIN
SET @data = TO_BASE64(CONCAT(
'{
"ID": "', NEW.ID,'",
"NAME": "', NEW.NAME,'",
"DESCRIPTION": "', NEW.DESCRIPTION,'",
}'
));
SELECT lambda_async('ARN람다함수',CONCAT('{
"Records":[
{
"kinesis":{
"data":"',REPLACE(@data,'\n',''),'"
}
}
]
}')) INTO @result;
END;
DELIMITER ;
패키지 설치
- go get github.com/aws/aws-lambda-go
- 아래 코드 zip 파일로 람다에 배포
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"log"
"os"
)
func init() {
log.Println("테스트 시작")
}
type Payload struct {
Operation string `json:"operation"`
}
func pingTest(ctx context.Context, event events.KinesisEvent) {
for _, record := range event.Records {
fmt.Printf("lambda_async 로부터 들어온 데이터", record)
if record.Kinesis.Data == nil {
fmt.Println("데이터가 Null")
continue
}
var payload Payload
if err := json.Unmarshal(record.Kinesis.Data, &payload); err != nil {
fmt.Println("페이로드 디코딩 실패:", err.Error())
continue
}
fmt.Println(payload)
}
}
func main() {
lambda.Start(pingTest)
}
'AWS' 카테고리의 다른 글
쉘 프로그래밍 자동화 (0) | 2022.12.12 |
---|---|
VPC 피어링 (0) | 2022.11.03 |
aws ec2 ssh 접속 오류 (0) | 2022.10.23 |
AWS Cognito 소셜로그인 인증 구현 (golang) (2) | 2022.06.17 |
S3 영상이 재생이 안되고 다운로드가 된다? (0) | 2022.04.27 |