본문 바로가기

Management

[실습] Amazon SNS(Simple Notification Service) 실습하기 (Lambda, Slack WebHook, CloudWatch)

반응형

안녕하세요 서후아빠입니다. ^_^

이번 세션은 Amazon SNS에 대해서 실습 해보겠습니다. 

Event는 테스트하기 편한 것으로 선택하시면 되고, 저는 S3에 File을 업로드 및 삭제하는 행위로 정의하였습니다. 


구성도

User가 S3에 File을 업로드 및 삭제 행위를 하는 Event(myevent)가 발생하면 SNS를 호출합니다. 
SNS는 3개의 구독과 연결되어 있습니다. 
  - Email 구독을 통하여 운영자(user01@gtek.com)으로 메일을 발송합니다.
  - Lambda(mytoficfunction) 구독을 통하여 CloudWatch 로그 그룹에 로깅합니다. 
  - Lambda(slackfunction) 구독을 통하여 CloudWatch 로그 그룹에 로깅하고, slcak channel로 WebHook 호출을 합니다.

1단계 : Slack 가입 및 WebHook URL 확인 (Slack 연동하지 않을 경우 SKIP)

https://slack.com 이동 > "TRY FOR FREE" > 메일 인증(ex : slack01@gtek.com) > 워크스페이스 생성(ex : awsSlack)

Slack 로그인 상태 > 좌측 메뉴에서 "Browse Slack" > Apps

검색란 “incoming webhooks” > Add > Add to Slack

Post to Channel에서 “awsSlack” 선택 > Add Incoming WebHooks integration

Webhook URL 확인(ex : https://hooks.slack.com/services/T03VbeH) > Save Settings

2단계 : Topic (주제) 생성

Amazon SNS > Topics > Creat topic 

Details Encryption(옵션) Access policy(옵션) Delivery status logging(옵션)
Type : Standard (or FIFO)
Name : mytopic
Display name(옵션) : -
Disable encryption Choose method : Basic (or Advanced)
Define who can publish messages to the topic : Only the topic owner
Define who can subscribe to this topic : Everyone
-
FIFO는 SQS만 지원합니다.
Display name는 SMS사용 시 옵션입니다.
Encryption을 활성화 시 CMK 선택(기본 : alias/aws/sns)해야 합니다.
Delivery status logging 
  - Log delivery status for these protocols : Lambda, SQS, HTTP/S, Platform application endpoint, Kinesis Data Firehose 지원

3단계 : Subscription (구독) 생성 - Email 경우

Amazon SNS > Subscriptions > Create subscription

Details Subscription filter policy(옵션) Redrive policy (dead-letter queue) (옵션)
Topic ARN : mytopic
Protocol : Email
Endpoint : user01@gtek.com
- Redrive policy : Disabled (or Enabled)
Protocol : Amazon Kinesis Data Firehose, SQS, Lambda, Email, HTTP/S, Paltform application endpoint 지원

수신 메일(aws에서 user01@gtek.com로 발송된 메일) > “Confirm subscription” 클릭

mytopic을 사용하는 이벤트가 발생하면 user01@gtek.com으로 메일이 발송됩니다.

4단계 : Subscription (구독) 생성 - Lambda 경우

AWS Lambda > Functions > Create function

Create function Basic information SNS trigger Lambda function code
Choose one ... : Use a blueprint
Blueprints(검색하여 선택하고, Configure) : sns-message-python
Function name : mytopicfunction
Execution role : Create a new role with basic Lambda permissions
SNS topic : mytopic 기본값 사용
Choose one ... : Use a blueprint
Blueprints(검색하여 선택하고, Configure) : cloudwatch-alarm-to-slack-python
Function name : slackfunction
Execution role : Use an existing role (mytopicfunction에서 생성된 Role 선택)
Environment variables
  - Key(slackchannel) : awsSlack
  - Key(kmsEncryptedHookUrl) : https://hooks.slack.com/services/T03VbeH
SNS topic : mytopic 아래 참조
# slackfunction Code 
  
import urllib3
import json
http = urllib3.PoolManager()
def lambda_handler(event, context):
    url = "https://hooks.slack.com/services/T03VbeH"   //1단계에서 확인한 URL
    msg = {
        "channel": "#awsSlack",                        //1단계에서 생성한 Channel
        "username": "slack01",                         //1단계에서 가입한 계정
        "text": event['Records'][0]['Sns']['Message'],
        "icon_emoji": ""
    }
    
    encoded_msg = json.dumps(msg).encode('utf-8')
    resp = http.request('POST',url, body=encoded_msg)
    print({
        "message": event['Records'][0]['Sns']['Message'], 
        "status_code": resp.status, 
        "response": resp.data
    })
Execution role
  - 선택 옵션 : Use an existing role, Create a new role from AWS policy templates
  - 신규 생성으로 진행하면 "AWSLambdaBasicExecutionRole"이 자동 생성됩니다.

slackfuction은 개발자가 필요한 내용을 설계를 해야 하는 부분이며, 예시 코드는 AWS(https://aws.amazon.com/ko/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams/ > Slack용 Python 코드 조각 예제 참조)에서 제공하는 기본 코드입니다.

AWS Lambda > Functions > mytopicfunction or slackfuction > Configuration (tab) 

Menu 설명 Remark
General configuration 중요하거나 메모리가 필요한 작업은 메모리 용량 수정  
Concurrency 필요 시 동시성 예약  
Environment variables Key(slackchannel), Key(kmsEncryptedHookUrl) 확인 및 수정  

Amazon SNS > Topics > mytopic > Publish message > SNS 동작 시 함께 동작 (옵션, SKIP 가능)

Message details Message body Message attributes
Subject(옵션) : mymessage
TTL(옵션) : -
Message structure : Identical payload for all delivery protocols. (or Custom payload for each delivery protocol.)
Message body to send to the endpoint(전송할 메시지 입력) : This is test messages.
Type : -
Name : -
Value : -
Type : String, String.Array, Number, Binary 지원

mytopic이 동작하면 Log groups에 로깅됩니다.
- 타임스탬프 예시 : 2022-03-05T10:46:32.708+09:00
- Messages 예시 : From SNS : This is test messages.

CloudWatch > Log groups > /aws/lambda/mytopicfunction or /aws/lambda/slackfuction 생성 확인

5단계 : 테스트 (S3 업로드 이벤트 발생)

Amazon SNS > Topics > mytopic > Edit > Access policy > 아래 참조하여 수정 > Save changes

# S3가 SNS 접근에 대한 권한 부여

...기본 정책 하단에 아래 내용 추가...
    {
      "Sid": "__console_sub_0",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "SNS:Subscribe",
      "Resource": "arn:aws:sns:ap-northeast-2:AWS계정:mytopic"   //region, AWS계정, topic 확인
    },
    {
      "Sid": "s3EventSNSNotification",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:ap-northeast-2:AWS계정:mytopic",  //region, AWS계정, topic 확인
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:s3:::mybucket"               //buctket 확인 
        }
      }
    }
  ]
}
권한 없이 Event notifications 생성하면 “Unable to validate the following destination configurations”오류 팝업됩니다.

Amazon S3 > buckets > Create bucket : 이름(mybucket)

Amazon S3 > buckets > mybucket > Properties (tab) > Event notifications의 Create event notification

General configuration Event types (필요한 이벤트 선택) Destination
Event name : myevent
Prefix(옵션) : -
Suffix(옵션) : .xls
All object create events
All object removal events
All restore object events
Destination : SNS topic (or Lambda or SQS)
Specify SNS topic : Choose from your SNS topics > mytopic
Lambda를 Destination에 직접 연결도 가능합니다. 다만, SNS를 이용하면 다중 호출(Email, Lambda, SQS 등)이 가능합니다.

Amazon S3 > buckets > mybucket > Upload > 2개 파일(test.txt, test xls) 업로드

Amazon S3 > buckets > mybucket > Upload > 2개 파일(test.txt, test xls) 삭제

수신 메일(aws에서 user01@gtek.com로 발송된 메일) 확인 : 2개 메일 수신 

slack의 awsSlack 채널에서 수신 메시지 확인 

CloudWatch > Log groups : 로깅 확인

총 4번(업로드 2개, 삭제 2개)의 행위에서 2개(확장자가 xls)만 동작하기 때문에 메일이 2개만 발송됩니다.
반응형