ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Collecting Event Data 1. Slack Push notification for Elastic beanstalk (Elasticbeanstalk 서버 Slack 알림 설정하기)
    Project/Collecting Event Data 2023. 1. 10. 19:24
    728x90
    반응형

     AWS SNS is a push notification service. We can send a slack notification through a below pipeline :

    • SNS subscribes an EB application
    • Once the application's status changes, EB send an event msg to SNS
    • SNS fowards the event msg to a Lambda function
    • The Lambda function send a notification to Slack via webhook

     

    Create an SNS topic

    First of all, we need to create an SNS subscription and topic for EB. We can create it using SNS console as well but it's way more easier to create it with EB console.

     

    1. Go to Elastic beanstalk > your application > your Environment > Configuration > Notifications (Edit)

    (Elastic beanstalk에 알림을 설정하는 Application/Environment의 구성(Configuration) > 알림(Notifications)로 들어간다)

    2. Write your email address (it's ok to write any dummy email address) > click Apply.

    (다음과 같은 화면이 나오는데, 이메일 란에 이메일을 적고 Apply를 누른다.)

    3. Then a new SNS subscription will be created. We'll use this ARN# later.

    (그러면 이렇게 구독이 생성된다. 어느 포스팅에서는 생성하고 람다 연결한 후 이메일 지워도 된다고하는데 이메일 지우면 주제가 삭제된다.)

     

    Create a Lambda Function

     

    Next, we need to write a Lambda function script to send a slack notification. Here is a basic script in Python.

    (다음은 슬랙 메세지를 보낼 수 있는 간단한 python script이다)

    import json
    import logging
    import os
    
    from urllib.request import Request, urlopen
    from urllib.error import URLError, HTTPError
    
    SLACK_CHANNEL = os.environ['SLACK_CHANNEL']
    HOOK_URL = os.environ['HOOK_URL']
    
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    def lambda_handler(event, context):
        logger.info("Event        : " + str(event))
        logger.info("SLACK Channel: #" + SLACK_CHANNEL)
        logger.info("HOOK URL     : " + HOOK_URL)
    
        msg = {
            "channel": SLACK_CHANNEL,
            "blocks": [{
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": event["Records"][0]["Sns"]["Message"]
                }
            }]
        }
    
        req = Request(HOOK_URL, data = json.dumps(msg).encode('utf-8'))
    
        try:
            response = urlopen(req)
            response.read()
            logger.info("Message posted to %s", SLACK_CHANNEL)
        except HTTPError as e:
            logger.error("Request failed: %d %s", e.code, e.reason)
        except URLError as e:
            logger.error("Server connection failed: %s", e.reason)

     

    To do not expose our slack hook url and the channel name, I set those as environment variables. We can set Lambda function's environment variables at Configuration > Environment variables.

    (람다에서 환경변수는 구성(Configuration) > 환경변수(Environment variables)에서 할 수 있다.)

     

    SNS events follow below format. As the above code, I used Records[0][Sns][Message] part only but you can add any other part on your needs. We also can test our Lambda function with the below JSON.

    (SNS이벤트는 다음 양식으로 발송된다. 이 샘플로 람다 함수 코드를 테스트할 수 있다.)

    {
      "Records": [
      	{
          "EventSource": "aws:sns",
          "EventVersion": "1.0",
          "EventSubscriptionArn": "arn:aws:sns:ap-northeast-2:00000:ElasticBeanstalkNotifications-Environment-APP-ENV:1111-1111-1111-1111",
          "Sns": {
            "Type": "Notification",
            "MessageId": "1234-5678-9101-1121",
            "TopicArn": "arn:aws:sns:ap-northeast-2:0000000:ElasticBeanstalkNotifications-Environment-your-env",
            "Subject": "AWS Elastic Beanstalk Notification - Environment health has transitioned from Ok to Info. Applica......",
            "Message": "Timestamp: Tue Jan 10 16:55:00 UTC 2023\nMessage: Environment health has transitioned from Ok to Info. Application update in progress on 1 instance. 0 out of 1 instance completed (running for 19 seconds).\n\nEnvironment: TEST-ENV\nApplication: APP\n\nEnvironment URL: http://TEST-ENV.ap-northeast-2.elasticbeanstalk.com\nNotificationProcessId: ed05c426-fe75-46c9-9ca2-c03d53d85e25",
            "Timestamp": "2018-09-18T01:54:04.516Z",
            "SignatureVersion": "1",
            "Signature": "VaxT10......",
            "SigningCertUrl": "https://sns.ap-northeast-2.amazonaws.com/....pem",
            "UnsubscribeUrl": "https://sns.ap-northeast-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-2:151095201970:ElasticBeanstalkNotifications-Environment-APP-ENV:......",
            "MessageAttributes": {}
          }
        }
      ]
    }

     

    Test the Lambda Function

     

    1. After deploying your lambda function, click the arrow at the right of Test button.

    2. Click "Configure test event"

    3. Create new event with the above JSON. You just can copy and paste it at the "Event JSON" part.

    4. Save the test event and click "Test" button.

    5. If you received Slack msg, you can go to the next step.

     

    Create an SNS subscription

     

    1. Go to AWS SNS > Subscriptions > click Create subscription

    (AWS SNS로 들어가서 구독(subscriptions) > 구독 생성을 클릭한다)

    2. Fill in the blanks:

    (다음 정보를 입력한다.)

    • Topic ARN(주제 ARN) - Where event happens (알람을 발생시키는 곳): SNS topic arn which we created at EB console (아까 Elastic Beanstalk 콘솔을 통해 생성한 SNS 주제 ARN)
    • Protocol(프로토콜): AWS Lambda
    • 엔드포인트(Endpoint) - 슬랙 알람을 전달할 곳: Lambda의 Function ARN

    FInally, you will get slack notification every time EB status changes after you click create button.

    (그리고 생성 버튼을 누르면 끝난다. 이제 EB 환경의 상태가 변경될 때마다 슬랙 알람이 전송된다.)

    728x90
    반응형

    댓글