자습서: Amazon Simple Notification Service에서 AWS Lambda 사용
하나의 AWS 계정에서 Lambda 함수를 사용하여 별도의 AWS 계정에서 Amazon SNS 주제를 구독할 수 있습니다. 이 자습서에서는 AWS Command Line Interface를 사용하여 Lambda 함수 생성, Amazon SNS 주제 생성 및 이 두 리소스가 서로 액세스할 수 있는 권한 부여와 같은 AWS Lambda 작업을 수행합니다.
사전 조건
이 자습서에서는 사용자가 기본 Lambda 작업과 Lambda 콘솔에 대해 어느 정도 알고 있다고 가정합니다. 그렇지 않은 경우 콘솔로 Lambda 함수 생성의 지침에 따라 첫 Lambda 함수를 생성합니다.
다음 단계를 완료하려면 명령을 실행할 명령줄 터미널 또는 셸이 필요합니다. 명령과 예상 결과는 별도의 블록에 나열됩니다.
aws --version
다음 결과가 표시됩니다.
aws-cli/2.0.57 Python/3.7.4 Darwin/19.6.0 exe/x86_64
긴 명령의 경우 이스케이프 문자(\
)를 사용하여 명령을 여러 행으로 분할합니다.
Linux 및 macOS는 선호 셸과 패키지 관리자를 사용합니다.
Windows에서는 Lambda와 함께 일반적으로 사용하는 일부 Bash CLI 명령(예:zip
)은 운영 체제의 기본 제공 터미널에서 지원되지 않습니다. Ubuntu와 Bash의 Windows 통합 버전을 가져오려면 Linux용 Windows Subsystem을 설치
이 자습서에서는 계정 2개를 사용합니다. AWS CLI 명령은 각각 다른 계정에서 사용하도록 구성된 명명된 프로필 2개를 사용하여 이를 설명합니다. 이름이 다른 프로필 즉, 기본 프로필 하나 또는 명명된 프로필 하나를 사용하는 경우 필요에 따라 명령을 수정합니다.
Amazon SNS 주제 생성(계정 A)
계정 A에서 소스 Amazon SNS 주제를 생성합니다.
aws sns create-topic --name sns-topic-for-lambda --profile accountA
주제를 생성한 후 주제의 Amazon 리소스 이름(ARN)을 기록합니다. 이는 나중에 주제를 구독하기 위해 Lambda 함수에 권한을 추가할 때 필요합니다.
실행 역할 생성(계정 B)
계정 B에서 AWS 리소스에 액세스할 수 있는 권한을 함수에 부여하는 실행 역할을 생성합니다.
실행 역할을 만들려면
-
IAM 콘솔에서 역할 페이지
를 엽니다. -
역할 생성(Create role)을 선택합니다.
-
다음 속성을 사용하여 역할을 만듭니다.
-
신뢰할 수 있는 엔터티. – AWS Lambda.
-
권한 – AWSLambdaBasicExecutionRole.
-
역할 이름 –
lambda-sns-role
.
-
AWSLambdaBasicExecutionRole 정책은 함수가 CloudWatch Logs에 로그를 쓰는 데 필요한 권한을 가집니다.
Lambda 함수 생성(계정 B)
계정 B에서 Amazon SNS로부터의 이벤트를 처리하는 함수를 생성합니다. 다음은 Amazon SNS 이벤트 입력을 수신하고 이벤트에 포함된 메시지를 처리하는 예제 코드입니다. 이해를 돕기 위해, 코드는 수신 이벤트 데이터의 일부를 CloudWatch Logs에 기록합니다.
다른 언어로 작성된 샘플 코드는 샘플 함수 코드 단원을 참조하세요.
예 index.js
console.log('Loading function'); exports.handler = function(event, context, callback) { // console.log('Received event:', JSON.stringify(event, null, 4)); var message = event.Records[0].Sns.Message; console.log('Message received from SNS:', message); callback(null, "Success"); };
함수를 만들려면
-
샘플 코드를
index.js
파일에 복사합니다. -
배포 패키지를 만듭니다.
zip function.zip index.js
-
create-function
명령을 사용해 Lambda 함수를 만듭니다.aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \ --role
arn:aws:iam::
\ --timeout 60 --profile accountB<AccountB_ID>
:role/lambda-sns-role
함수를 생성한 후 함수의 ARN을 기록합니다. 이는 나중에 Amazon SNS에 함수를 호출할 권한을 추가할 때 필요합니다.
교차 계정 권한 설정(계정 A 및 B)
계정 A에서 계정 B에 주제를 구독할 수 있는 권한을 부여합니다.
aws sns add-permission --label lambda-access --aws-account-id
<AccountB_ID>
\ --topic-arn arn:aws:sns:us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA
계정 B에서 Amazon SNS로부터 호출을 허용하는 Lambda 권한을 추가합니다.
aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:
us-east-2
:<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-2:
<AccountA_ID>
:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-2:<AccountB_ID>
:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns1\"}" }
정책을 추가할 때 --source-account
파라미터를 사용하여 Lambda 정책에 소스 계정을 추가하면 안 됩니다. 소스 계정은 Amazon SNS 이벤트 소스에 대해 지원되지 않으므로 액세스가 거부됩니다.
SNS 주제가 있는 계정이 옵트인 리전에서 호스팅되는 경우 보안 주체의 리전을 지정해야 합니다. 예를 들어 아시아 태평양(홍콩) 리전에서 SNS 주제를 사용하는 경우 보안 주체에 대해 sns.amazonaws.com
대신 sns.ap-east-1.amazonaws.com
을 지정해야 합니다.
구독 생성(계정 B)
계정 B에서 해당 주제에 대한 Lambda 함수를 구독합니다. 계정 A의 sns-topic-for-lambda
주제로 메시지가 전송되면 Amazon SNS는 계정 B에서 Function-With-SNS
함수를 호출합니다.
aws sns subscribe --protocol lambda \ --topic-arn arn:aws:sns:
us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-2
:<AccountB_ID>
:function:Function-With-SNS \ --profile accountB
다음 결과가 표시됩니다.
{ "SubscriptionArn": "arn:aws:sns:us-east-2:
<AccountA_ID>
:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }
출력에는 주제 구독의 ARN이 포함되어 있습니다.
구독 테스트(계정 A)
계정 A에서 구독을 테스트합니다. 텍스트 파일에 Hello World
를 입력하고 message.txt
로 저장합니다. 그런 다음, 다음 명령을 실행합니다.
aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:
us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --profile accountA
그러면 Amazon SNS 서비스에서 메시지를 승인했음을 나타내는 고유한 식별자가 포함된 메시지 ID가 반환됩니다. Amazon SNS는 주제의 구독자에게 이를 전달하려고 시도합니다. 또는 JSON 문자열을 message
파라미터에 직접 제공할 수 있지만, 텍스트 파일을 사용하면 메시지에서 줄 바꿈을 사용할 수 있습니다.
Amazon SNS 대한 자세한 내용은 What is Amazon Simple Notification Service를 참조하세요.
리소스 정리
이 자습서 용도로 생성한 리소스를 보관하고 싶지 않다면 지금 삭제할 수 있습니다. 더 이상 사용하지 않는 AWS 리소스를 삭제하면 AWS 계정에 불필요한 요금이 발생하는 것을 방지할 수 있습니다.
계정 A에서 Amazon SNS 주제를 정리합니다.
Amazon SNS 주제를 삭제하려면
-
Amazon SNS 콘솔의 주제 페이지
를 엽니다. -
생성한 주제를 선택합니다.
-
삭제를 선택합니다.
-
텍스트 입력 필드에
delete me
을 입력합니다. -
삭제를 선택합니다.
계정 B에서 실행 역할, Lambda 함수 및 Amazon SNS 구독을 정리합니다.
실행 역할 삭제
-
IAM 콘솔에서 역할 페이지
를 엽니다. -
생성한 실행 역할을 선택합니다.
-
삭제를 선택합니다.
-
텍스트 입력 필드에 역할의 이름을 입력하고 Delete(삭제)를 선택합니다.
Lambda 함수를 삭제하려면
-
Lambda 콘솔의 함수 페이지
를 엽니다. -
생성한 함수를 선택합니다.
-
작업(Actions), 삭제(Delete)를 선택합니다.
-
텍스트 입력 필드에
delete
를 입력하고 Delete(삭제)를 선택합니다.
Amazon SNS 구독을 삭제하려면
-
Amazon SNS 콘솔의 구독 페이지
를 엽니다. -
생성한 구독을 선택합니다.
-
삭제(Delete)와 삭제(Delete)를 차례로 선택합니다.