Architecture/AWS

AWS Lambda๋กœ Slack๊ณผ ์—ฐ๋™ํ•ด์„œ ์•Œ๋žŒ ์„ค์ • (RDS PostgreSQL, ๋žŒ๋‹ค ์Šฌ๋ž™ ์—ฐ๋™, SNS ๊ตฌ๋… ์„ค์ •)

ํƒฑ์ ค 2023. 9. 24. 16:30

RDS PostgreSQL Slack ์•Œ๋žŒ ํ…Œ์ŠคํŠธ (slack incoming-webhook ์•ฑ ์ด์šฉ)

Slack์— ์•Œ๋ฆผ ์ˆ˜์‹ ์„ ์œ„ํ•œ ์•ฑ ์ถ”๊ฐ€ (incoming-webhook)

๊ตฌ์„ฑ ์„ ํƒํ•ด์„œ ๊ตฌ๋…์„ ์›ํ•˜๋Š” ์Šฌ๋ž™ ์ฑ„๋„์„ ์„ ํƒ

 

์„ ํƒ ํ›„ ์›นํ›„ํฌ URL ๋ณต์‚ฌํ•ด๋‘” ๋’ค (๋žŒ๋‹ค ์ƒ์„ฑ ์‹œ ํ•„์š”) ์„ค์ • ์ €์žฅ


Slack ์ˆ˜์‹ ์„ ์œ„ํ•œ AWS Lambda ํ•จ์ˆ˜ ์ƒ์„ฑ

์—ญํ•  ์„ ํƒ ํ›„ SNS ํŠธ๋ฆฌ๊ฑฐ๋Š” ์•„์ง ์ฃผ์ œ ์ƒ์„ฑ ์ „์ด๊ธฐ์— ์ œ๊ฑฐํ•œ๋‹ค.


๋žŒ๋‹ค ์ƒ์„ฑ ์‹œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •

kmsEncryptedHookUrl๊ณผ slackChannel ๊ฐ’์„ ์ž…๋ ฅํ•ด์ค€๋‹ค

Url ์ •๋ณด์™€ slackChannel์€ ์œ„์— ์Šฌ๋ž™์—์„œ ์•ฑ ์„ค์ •ํ•  ์‹œ ์ •๋ณด๋“ค์„ ์ž…๋ ฅํ•ด์ค€๋‹ค

์ƒ์„ฑ ์™„๋ฃŒ


Amazon SNS ์ฃผ์ œ ์ƒ์„ฑ

ํ‘œ์ค€ ์„ ํƒ, ์ด๋ฆ„ ์ž…๋ ฅ ํ›„ ์ƒ์„ฑ

์ƒ์„ฑ๋œ ์ฃผ์ œ๋กœ ๋“ค์–ด๊ฐ€์„œ ๊ตฌ๋… ์ƒ์„ฑ

์ฃผ์ œ ARN์œผ๋กœ ์œ„์—์„œ ์ƒ์„ฑํ•œ ๋žŒ๋‹ค ์„ ํƒ ํ›„ ํ”„๋กœํ† ์ฝœ AWS Lambda ์„ ํƒ → ๊ตฌ๋… ์ƒ์„ฑ

๊ตฌ๋… ์ƒ์„ฑ๋œ ๊ฒƒ ํ™•์ธ


ํ…Œ์ŠคํŠธ ์•Œ๋žŒ ์ˆ˜์‹ 

์ƒ์„ฑ๋œ ๋žŒ๋‹ค ํ•จ์ˆ˜๋กœ ๋“ค์–ด๊ฐ€์„œ ํ…Œ์ŠคํŠธ ์ด๋ฒคํŠธ ์ƒ์„ฑ ํ›„ ํ…Œ์ŠคํŠธ ์ง„ํ–‰

  • ์Šฌ๋ž™ ํ…Œ์ŠคํŠธ ์˜ค๋ฅ˜ ์ˆ˜์ • -> hook_url ์ˆ˜์ • ๋ฐ ๋™์‹œ์„ฑ ํŽธ์ง‘

AWS Lambda๋ฅผ ์ด์šฉํ•œ Sequence Check ์Šฌ๋ž™ ์•Œ๋žŒ๊นŒ์ง€

  • rds slack ์‹œํ€€์Šค test -> psycopg2 ๋ชจ๋“ˆ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๊ณ  ๋œจ๋Š” ์—๋Ÿฌ ์ˆ˜์ • -> layer ์ถ”๊ฐ€ํ•˜๋ฉด๋จ
    • AWS Lambda ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ DB ์ปค๋„ฅ์…˜์— ํ•„์š”ํ•œ ๋ชจ๋“ˆ ๊ธฐ๋Šฅ ์ œ๊ณต์„ ์•ˆํ•œ๋‹ค.(ํฌ์ŠคํŠธ๊ทธ๋ ˆ - psycopg2, mysql - psmyqsl ๋“ฑ) → psycopg2๋ฅผ ๊ฐœ๋ณ„์ ์œผ๋กœ ๋ฐ›์•„์„œ Lambda๋‚ด Layer(๊ณ„์ธต)๋ผ๋Š” ๊ณณ์— ์˜ฌ๋ ค์•ผํ•œ๋‹ค.
    • Add a layer(๊ณ„์ธต์ƒ์„ฑ) ์— ์•„๋ž˜์— ์ถ”๊ฐ€๋œ psycopg2-layger.zip ํŒŒ์ผ ์—…๋กœ๋“œ

Layers ์ƒ์„ฑ ํ™•์ธ!

  • postgre_alarm_test_ty ๋žŒ๋‹ค ์ƒ์„ฑ ์‹œ ์ฝ”๋“œ
import json
import os
import psycopg2
import urllib.request

ENCRYPTED_HOOK_URL = os.environ['kmsEncryptedHookUrl']#ํ•ด๋‹น ํ™˜๊ฒฝ๋ณ€์ˆ˜๋“ค์€ ๊ตฌ์„ฑ์—์„œ ์ถ”๊ฐ€
SLACK_CHANNEL =os.environ['slack_channel']

def post_slack(argStr):
    message = argStr
    send_data = {
        "text": message,
    }
    send_text = json.dumps(send_data)
    request = urllib.request.Request(
        ENCRYPTED_HOOK_URL,
        data=send_text.encode('utf-8'),
    )

    with urllib.request.urlopen(request) as response:
        slack_message = response.read()

def lambda_handler(event, context):
# TODO implement
    sql = 'select * from (    select sequencename , round(("last_value")::numeric/max_value::numeric, 10) as pct from pg_catalog.pg_sequences) a where a.pct > 0.07;'

    conn = psycopg2.connect(
        host = os.environ['DB_HOST'],
        dbname = os.environ['DB_NAME'],
        user = os.environ['DB_USER'],
        password = os.environ['DB_PASSWORD'],
        port = os.environ['DB_PORT']
        )

    cur = conn.cursor()

#print(cur.mogrify(sql))
    cur.execute(sql)

    result = cur.fetchall()

    for cur in result:
        if cur is not None:
            msg = cur[0] + ' is urgent'
            post_slack(os.environ['DB_NAME'] + ' ' + msg + '(taeyeong)')
        else:
            post_slack("sequence is normal.")

    conn.close()
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
  • ๋žŒ๋‹ค ๊ตฌ์„ฑ ์‹œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŽธ์ง‘
  • https://user-images.githubusercontent.com/61795757/182526372-52196f84-72c3-441a-9ae9-86ba287788cb.png
  • ํŠธ๋ฆฌ๊ฑฐ ์ถ”๊ฐ€ (ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ํ™œ์šฉํ•œ ์ด๋ฒคํŠธ ๊ฑธ๊ธฐ)

https://user-images.githubusercontent.com/61795757/182526744-1b0b8b58-0817-4ced-a2b6-d2c84c582c47.png

  • 1๋ถ„์— 1๋ฒˆ์”ฉ ์•Œ๋žŒ ์˜ค๋Š” ๊ฒƒ ํ™•์ธ
  • https://user-images.githubusercontent.com/61795757/182527340-8c4da201-ab85-497b-9341-2288d547282f.png
728x90