튜토리얼: AWS Lambda를 Amazon SNS와 함께 사용하기
튜토리얼: AWS Lambda를 Amazon SNS와 함께 사용하기 (Tutorial: Using AWS Lambda with Amazon Simple Notification Service)
이 튜토리얼에서는 한 AWS 계정의 Lambda 함수를 다른 AWS 계정의 Amazon Simple Notification Service(Amazon SNS) 토픽에 구독시켜요. Amazon SNS 토픽에 메시지를 게시하면 Lambda 함수가 메시지 내용을 읽어 Amazon CloudWatch Logs로 출력해요. 이 튜토리얼을 완료하려면 AWS Command Line Interface(AWS CLI)를 사용해요.
이 튜토리얼을 완료하려면 다음 단계를 수행해요.
- account A에서 Amazon SNS 토픽을 만들어요.
- account B에서 토픽의 메시지를 읽는 Lambda 함수를 만들어요.
- account B에서 토픽에 대한 구독을 만들어요.
- account A의 Amazon SNS 토픽에 메시지를 게시하고, account B의 Lambda 함수가 이를 CloudWatch Logs로 출력하는지 확인해요.
이 단계들을 완료하면서 Amazon SNS 토픽을 구성해 Lambda 함수를 호출하는 방법을 배워요. 또한 다른 AWS 계정의 리소스가 Lambda를 호출하도록 권한을 주는 AWS Identity and Access Management(IAM) 정책을 만드는 방법도 배워요.
튜토리얼에서는 두 개의 별도 AWS 계정을 사용해요. AWS CLI 명령은 서로 다른 AWS 계정용으로 구성된 accountA와 accountB라는 두 개의 명명된 프로필로 이를 보여줘요. AWS CLI를 다른 프로필로 구성하는 방법은 AWS Command Line Interface User Guide for Version 2의 Configuration and credential file settings을 참고하세요. 두 프로필에 같은 기본 AWS 리전을 구성해야 해요.
두 AWS 계정용으로 만든 AWS CLI 프로필 이름이 다르거나, 기본 프로필과 명명된 프로필 하나를 쓴다면 아래 단계의 AWS CLI 명령을 필요에 맞게 수정하세요.
본문
전제 조건
아직 AWS Command Line Interface를 설치하지 않았다면 AWS CLI 최신 버전 설치·업데이트하기의 단계를 따라 설치해요.
튜토리얼은 명령을 실행하기 위해 명령줄 터미널이나 셸이 필요해요. Linux와 macOS에서는 원하는 셸과 패키지 매니저를 사용해요.
참고 Windows에서는 Lambda에 자주 쓰는 일부 Bash CLI 명령(예:
zip)이 운영체제 내장 터미널에서 지원되지 않아요. Windows와 통합된 Ubuntu와 Bash를 얻으려면 Windows Subsystem for Linux를 설치하세요.
Amazon SNS 토픽 만들기 (account A)
토픽을 만들려면
- account A에서 다음 AWS CLI 명령으로 Amazon SNS 표준 토픽을 만들어요.
aws sns create-topic --name sns-topic-for-lambda --profile accountA
다음과 비슷한 출력이 보여요.
{
"TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda"
}
토픽의 Amazon Resource Name(ARN)을 메모해 두세요. 나중에 Lambda 함수에 토픽을 구독할 권한을 추가할 때 필요해요.
함수 실행 역할 만들기 (account B)
실행 역할(execution role)은 Lambda 함수에 AWS 서비스·리소스에 접근할 권한을 주는 IAM 역할이에요. account B에서 함수를 만들기 전에 함수가 CloudWatch Logs에 로그를 쓸 기본 권한을 주는 역할을 만들어요. Amazon SNS 토픽에서 읽을 권한은 이후 단계에서 추가할 거예요.
실행 역할을 만들려면
- account B에서 IAM 콘솔의 roles 페이지를 열어요.
- Create role을 선택해요.
- Trusted entity type에서 AWS service를 선택해요.
- Use case에서 Lambda를 선택해요.
- Next를 선택해요.
- 다음으로 역할에 기본 권한 정책을 추가해요. Permissions policies 검색 상자에
AWSLambdaBasicExecutionRole을 입력하고 Next를 선택해요. - 다음으로 역할 생성을 마무리해요. Role details 아래 Role name에
lambda-sns-role을 입력하고 Create role을 선택해요.
Lambda 함수 만들기 (account B)
Amazon SNS 메시지를 처리하는 Lambda 함수를 만들어요. 함수 코드는 각 레코드의 메시지 내용을 Amazon CloudWatch Logs에 기록해요.
이 튜토리얼은 Node.js 24 런타임을 사용하지만, 다른 런타임 언어의 예시 코드도 제공해요. 관심 있는 런타임의 코드를 보려면 아래 상자의 탭을 선택하세요. 이 단계에서 사용할 JavaScript 코드는 JavaScript 탭의 첫 번째 예시에 있어요.
다음은 JavaScript(SDK for JavaScript v3) 예시예요.
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
exports.handler = async (event, context) => {
for (const record of event.Records) {
await processMessageAsync(record);
}
console.info("done");
};
async function processMessageAsync(record) {
try {
const message = JSON.stringify(record.Sns.Message);
console.log(`Processed message ${message}`);
await Promise.resolve(1); //Placeholder for actual async work
} catch (err) {
console.error("An error occurred");
throw err;
}
}
참고 GitHub에 더 많은 내용이 있어요. Serverless examples 저장소에서 .NET, Go, Java, TypeScript, PHP, Python, Ruby, Rust용 전체 예시를 찾고 설정·실행 방법을 알아보세요. 이 튜토리얼은 Node.js 런타임을 사용하며, 각 언어의 핸들러는 메시지 본문(
record.Sns.Message)을 로그로 기록하는 동일한 패턴을 따르고 처리 실패 시 예외를 던져 호출을 실패로 표시해요.
함수를 만들려면
- 프로젝트용 디렉터리를 만들고 그 디렉터리로 이동해요.
mkdir sns-tutorial
cd sns-tutorial
- 샘플 JavaScript 코드를
index.js라는 새 파일에 복사해요. - 다음
zip명령으로 배포 패키지를 만들어요.
zip function.zip index.js
- 다음 AWS CLI 명령으로 account B에 Lambda 함수를 만들어요.
aws lambda create-function --function-name Function-With-SNS \
--zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
--role arn:aws:iam::<AccountB_ID>:role/lambda-sns-role \
--timeout 60 --profile accountB
다음과 비슷한 출력이 보여요.
{
"FunctionName": "Function-With-SNS",
"FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:Function-With-SNS",
"Runtime": "nodejs24.x",
"Role": "arn:aws:iam::123456789012:role/lambda_basic_role",
"Handler": "index.handler",
...
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:us-west-2::runtime:7d5f06b69c951da8a48b926ce280a9daf2e8bb1a74fc4a2672580c787d608206"
}
}
- 함수의 ARN을 기록해 두세요. 나중에 Amazon SNS가 함수를 호출하도록 권한을 추가할 때 필요해요.
함수에 권한 추가하기 (account B)
Amazon SNS가 함수를 호출하게 하려면 리소스 기반 정책(resource-based policy)의 문(statement)에서 권한을 부여해야 해요. 이 문은 AWS CLI add-permission 명령으로 추가해요.
Amazon SNS에 함수 호출 권한 부여하기
- account B에서 앞서 기록한 Amazon SNS 토픽의 ARN을 사용해 다음 AWS CLI 명령을 실행해요.
aws lambda add-permission --function-name Function-With-SNS \
--source-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
--statement-id function-with-sns --action "lambda:InvokeFunction" \
--principal sns.amazonaws.com --profile accountB
다음과 비슷한 출력이 보여요.
{
"Statement": "{\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\": \"arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns\"}"
}
참고 Amazon SNS 토픽이 있는 계정이 opt-in AWS 리전에 호스팅되어 있다면 principal에 리전을 지정해야 해요. 예를 들어 아시아 태평양(홍콩) 리전의 Amazon SNS 토픽으로 작업한다면 principal에
sns.amazonaws.com대신sns.ap-east-1.amazonaws.com을 지정해야 해요.
Amazon SNS 구독에 크로스 계정 권한 부여하기 (account A)
account B의 Lambda 함수가 account A에서 만든 Amazon SNS 토픽을 구독하게 하려면 account B가 토픽을 구독하도록 권한을 부여해야 해요. 이 권한은 AWS CLI add-permission 명령으로 부여해요.
account B에 토픽 구독 권한 부여하기
- account A에서 다음 AWS CLI 명령을 실행해요. 앞서 기록한 Amazon SNS 토픽의 ARN을 사용해요.
aws sns add-permission --label lambda-access --aws-account-id <AccountB_ID> \
--topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
--action-name Subscribe ListSubscriptionsByTopic --profile accountA
구독 만들기 (account B)
account B에서 이제 Lambda 함수를 튜토리얼 시작 시 account A에서 만든 Amazon SNS 토픽에 구독시켜요. 이 토픽(sns-topic-for-lambda)에 메시지가 전송되면 Amazon SNS가 account B의 Lambda 함수 Function-With-SNS를 호출해요.
구독을 만들려면
- account B에서 다음 AWS CLI 명령을 실행해요. 토픽을 만든 기본 리전과 토픽·Lambda 함수의 ARN을 사용해요.
aws sns subscribe --protocol lambda \
--region us-east-1 \
--topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
--notification-endpoint arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS \
--profile accountB
다음과 비슷한 출력이 보여요.
{
"SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx"
}
토픽에 메시지 게시하기 (account A 및 account B)
이제 account B의 Lambda 함수가 account A의 Amazon SNS 토픽에 구독됐으니, 토픽에 메시지를 게시해 설정을 테스트할 차례예요. Amazon SNS가 Lambda 함수를 호출했는지 확인하려면 CloudWatch Logs로 함수의 출력을 확인해요.
토픽에 메시지를 게시하고 함수의 출력을 보려면
- 텍스트 파일에
Hello World를 입력하고message.txt로 저장해요. - 텍스트 파일을 저장한 디렉터리에서 account A로 다음 AWS CLI 명령을 실행해요. 자기 토픽의 ARN을 사용해요.
aws sns publish --message file://message.txt --subject Test \
--topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
--profile accountA
이 명령은 고유 식별자가 있는 메시지 ID를 반환하며, Amazon SNS가 메시지를 수락했음을 나타내요. 그런 다음 Amazon SNS는 메시지를 토픽의 구독자에게 전달하려 해요. Amazon SNS가 Lambda 함수를 호출했는지 확인하려면 CloudWatch Logs로 함수 출력을 확인해요.
- account B에서 Amazon CloudWatch 콘솔의 Log groups 페이지를 열어요.
- 함수의 로그 그룹(
/aws/lambda/Function-With-SNS)을 선택해요. - 가장 최근 로그 스트림을 선택해요.
- 함수가 올바르게 호출됐다면 토픽에 게시한 메시지 내용을 보여주는 다음 비슷한 출력이 보여요.
2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO Processed message Hello World
2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO done
리소스 정리하기
이제 이 튜토리얼을 위해 만든 리소스를 계속 유지하고 싶지 않다면 삭제할 수 있어요. 더 이상 사용하지 않는 AWS 리소스를 삭제하면 AWS 계정에 불필요한 요금이 부과되는 것을 막을 수 있어요.
Account A에서 Amazon SNS 토픽을 정리해요.
Amazon SNS 토픽을 삭제하려면
- Amazon SNS 콘솔의 Topics 페이지를 열어요.
- 만든 토픽을 선택해요.
- Delete를 선택해요.
- 텍스트 입력 필드에
delete me를 입력해요. - Delete를 선택해요.
Account B에서 실행 역할, Lambda 함수, Amazon SNS 구독을 정리해요.
실행 역할을 삭제하려면
- IAM 콘솔의 Roles 페이지를 열어요.
- 만든 실행 역할을 선택해요.
- Delete를 선택해요.
- 텍스트 입력 필드에 역할 이름을 입력하고 Delete를 선택해요.
Lambda 함수를 삭제하려면
- Lambda 콘솔의 Functions 페이지를 열어요.
- 만든 함수를 선택해요.
- Actions, Delete를 선택해요.
- 텍스트 입력 필드에
confirm을 입력하고 Delete를 선택해요.
Amazon SNS 구독을 삭제하려면
- Amazon SNS 콘솔의 Subscriptions 페이지를 열어요.
- 만든 구독을 선택해요.
- Delete, Delete를 선택해요.