Amazon RDS와 함께 AWS Lambda 사용 - AWS Lambda

Amazon RDS와 함께 AWS Lambda 사용

Lambda 함수를 Amazon RDS 프록시를 통해 Amazon Relational Database Service(Amazon RDS) 데이터베이스에 직접 연결할 수 있습니다. 간단한 시나리오에서는 직접 연결이 유용하며 프로덕션에서는 프록시를 사용하는 것이 좋습니다. 데이터베이스 프록시는 함수가 데이터베이스 연결을 소진하지 않고 높은 동시성 레벨에 도달할 수 있도록 하는 공유 데이터베이스 연결 풀을 관리합니다.

짧게 데이터베이스를 연결하거나 다수의 데이터베이스 연결을 열고 닫는 Lambda 함수에는 Amazon RDS 프록시를 사용하는 것이 좋습니다.

함수 구성

Lambda 콘솔에서는 Amazon RDS 데이터베이스 인스턴스와 프록시 리소스를 프로비저닝하고 구성할 수 있습니다. 자세한 내용은 구성 탭에서 RDS 데이터베이스를 참조하세요. 또는 Amazon RDS 콘솔에서 Lambda 함수에 대한 연결을 생성하고 구성할 수도 있습니다.

  • 데이터베이스에 연결하려면 데이터베이스를 실행하는 동일한 Amazon VPC에 함수가 있어야 합니다.

  • MySQL, MariaDB, PostgreSQL 또는 Microsoft SQL Server 엔진과 함께 Amazon RDS 데이터베이스를 사용할 수 있습니다.

  • MySQL 또는 PostgreSQL 엔진과 함께 Aurora DB 클러스터를 사용할 수도 있습니다.

  • 데이터베이스 인증을 위해 Secrets Manager 보안 암호를 제공해야 합니다.

  • IAM 역할은 보안 암호를 사용할 권한을 제공해야 하며, 신뢰 정책에서는 Amazon RDS가 역할을 수임하도록 허용해야 합니다.

  • 콘솔을 사용하여 Amazon RDS 리소스를 구성하고 이를 함수에 연결하는 IAM 보안 주체에는 다음 권한이 있어야 합니다.

    참고

    데이터베이스 연결 풀을 관리하기 위해 Amazon RDS 프록시를 구성하는 경우에만 Amazon RDS 프록시 권한이 필요합니다.

    예 권한 정책
    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:CreateSecurityGroup", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "ec2:AuthorizeSecurityGroupIngress", "ec2:AuthorizeSecurityGroupEgress", "ec2:RevokeSecurityGroupEgress", "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", "ec2:DescribeNetworkInterfaces" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "rds-db:connect", "rds:CreateDBProxy", "rds:CreateDBInstance", "rds:CreateDBSubnetGroup", "rds:DescribeDBClusters", "rds:DescribeDBInstances", "rds:DescribeDBSubnetGroups", "rds:DescribeDBProxies", "rds:DescribeDBProxyTargets", "rds:DescribeDBProxyTargetGroups", "rds:RegisterDBProxyTargets", "rds:ModifyDBInstance", "rds:ModifyDBProxy" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "lambda:CreateFunction", "lambda:ListFunctions", "lambda:UpdateFunctionConfiguration" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "iam:AttachRolePolicy", "iam:AttachPolicy", "iam:CreateRole", "iam:CreatePolicy" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "secretsmanager:GetResourcePolicy", "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds", "secretsmanager:CreateSecret" ], "Resource": "*" } ] }

Amazon RDS는 데이터베이스 인스턴스 크기를 기준으로 프록시에 시간당 요금을 부과합니다. 자세한 내용은 RDS 프록시 요금을 참조하세요. 일반적인 프록시 연결에 대한 자세한 내용은 Amazon RDS 사용 설명서에서 Amazon RDS 프록시 사용을 참조하세요.

Lambda 및 Amazon RDS 설정

Lambda와 Amazon RDS 콘솔 모두 Lambda와 Amazon RDS를 연결하는 데 필요한 일부 리소스를 자동으로 구성하는 데 도움이 됩니다.

Lambda 함수를 사용하여 Amazon RDS 데이터베이스에 연결합니다.

다음 코드 예제는 Amazon RDS 데이터베이스에 연결하는 Lambda 함수를 구현하는 방법을 보여줍니다. 이 함수는 간단한 데이터베이스 요청을 하고 결과를 반환합니다.

Go
SDK for Go V2
참고

GitHub에 더 많은 내용이 있습니다. 서버리스 예제 리포지토리에서 전체 예제를 찾아보고 설정 및 실행 방법을 알아봅니다.

Go를 사용하여 Lambda 함수에서 Amazon RDS 데이터베이스에 연결

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 /* Golang v2 code here. */ package main import ( "context" "database/sql" "encoding/json" "fmt" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/rds/auth" _ "github.com/go-sql-driver/mysql" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(event *MyEvent) (map[string]interface{}, error) { var dbName string = "DatabaseName" var dbUser string = "DatabaseUser" var dbHost string = "mysqldb.123456789012.us-east-1.rds.amazonaws.com" var dbPort int = 3306 var dbEndpoint string = fmt.Sprintf("%s:%d", dbHost, dbPort) var region string = "us-east-1" cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { panic("configuration error: " + err.Error()) } authenticationToken, err := auth.BuildAuthToken( context.TODO(), dbEndpoint, region, dbUser, cfg.Credentials) if err != nil { panic("failed to create authentication token: " + err.Error()) } dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true&allowCleartextPasswords=true", dbUser, authenticationToken, dbEndpoint, dbName, ) db, err := sql.Open("mysql", dsn) if err != nil { panic(err) } defer db.Close() var sum int err = db.QueryRow("SELECT ?+? AS sum", 3, 2).Scan(&sum) if err != nil { panic(err) } s := fmt.Sprint(sum) message := fmt.Sprintf("The selected sum is: %s", s) messageBytes, err := json.Marshal(message) if err != nil { return nil, err } messageString := string(messageBytes) return map[string]interface{}{ "statusCode": 200, "headers": map[string]string{"Content-Type": "application/json"}, "body": messageString, }, nil } func main() { lambda.Start(HandleRequest) }
JavaScript
SDK for JavaScript (v2)
참고

GitHub에 더 많은 내용이 있습니다. 서버리스 예제 리포지토리에서 전체 예제를 찾아보고 설정 및 실행 방법을 알아봅니다.

Javascript를 사용하여 Lambda 함수에서 Amazon RDS 데이터베이스에 연결

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 /* Node.js code here. */ // ES6+ example import { Signer } from "@aws-sdk/rds-signer"; import mysql from 'mysql2/promise'; async function createAuthToken() { // Define connection authentication parameters const dbinfo = { hostname: process.env.ProxyHostName, port: process.env.Port, username: process.env.DBUserName, region: process.env.AWS_REGION, } // Create RDS Signer object const signer = new Signer(dbinfo); // Request authorization token from RDS, specifying the username const token = await signer.getAuthToken(); return token; } async function dbOps() { // Obtain auth token const token = await createAuthToken(); // Define connection configuration let connectionConfig = { host: process.env.ProxyHostName, user: process.env.DBUserName, password: token, database: process.env.DBName, ssl: 'Amazon RDS' } // Create the connection to the DB const conn = await mysql.createConnection(connectionConfig); // Obtain the result of the query const [res,] = await conn.execute('select ?+? as sum', [3, 2]); return res; } export const handler = async (event) => { // Execute database flow const result = await dbOps(); // Return result return { statusCode: 200, body: JSON.stringify("The selected sum is: " + result[0].sum) } };

Amazon RDS의 이벤트 알림 처리

Lambda를 사용하여 Amazon RDS 데이터베이스의 이벤트 알림을 처리할 수 있습니다. Amazon RDS는 Amazon Simple Notification Service(Amazon SNS) 주제에 알림을 전송합니다. 이 알림이 Lambda 함수를 호출하도록 구성할 수 있습니다. Amazon SNS는 Amazon RDS의 메시지를 자체 이벤트 문서로 래핑하여 함수에 이를 전송합니다.

알림 전송을 위한 Amazon RDS 데이터베이스 구성에 대한 자세한 내용은 Amazon RDS 이벤트 알림 사용을 참조하세요.

예 Amazon SNS 이벤트의 Amazon RDS 메시지
{ "Records": [ { "EventVersion": "1.0", "EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:rds-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "EventSource": "aws:sns", "Sns": { "SignatureVersion": "1", "Timestamp": "2023-01-02T12:45:07.000Z", "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==", "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem", "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "Message": "{\"Event Source\":\"db-instance\",\"Event Time\":\"2023-01-02 12:45:06.000\",\"Identifier Link\":\"https://console.aws.amazon.com/rds/home?region=eu-west-1#dbinstance:id=dbinstanceid\",\"Source ID\":\"dbinstanceid\",\"Event ID\":\"http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/USER_Events.html#RDS-EVENT-0002\",\"Event Message\":\"Finished DB Instance backup\"}", "MessageAttributes": {}, "Type": "Notification", "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486", "TopicArn":"arn:aws:sns:us-east-2:123456789012:sns-lambda", "Subject": "RDS Notification Message" } } ] }

Lambda 및 Amazon RDS 자습서

  • Amazon RDS 데이터베이스에 액세스하기 위해 Lambda 함수 사용 – Amazon RDS 사용 설명서에서 Lambda 함수를 사용하여 Amazon RDS 프록시를 통해 Amazon RDS 데이터베이스에 데이터를 쓰는 방법을 알아보세요. Lambda 함수는 메시지가 추가될 때마다 Amazon SQS 대기열에서 레코드를 읽고 데이터베이스의 테이블에 새 항목을 기록합니다.