24*365 ์ฅ์ ๋ชจ๋ํฐ๋ง์ ๋ํด์(with AWS CloudWatch)
365์ผ 24์๊ฐ ์ฅ์ ๋ชจ๋ํฐ๋ง์ ํ์ง ์์ผ๋ฉด ์ฆ๊ฐ์ ์ธ ๋์์ด ๋ถ๊ฐํ ๊ฒ์ด๋ผ ์๊ฐํ๋ค.
์ด๋ค ์์ผ๋ก ๊ธฐ์
์์๋ ์ด๋ฅผ ํด๊ฒฐํ๋์ง ์ฐพ์๋ณด๋ค๊ฐ AWS CloudWatch์ ๋ํด์ ๊ณต๋ถํด ๋ณด๊ฒ ๋์๋ค.
์ ์ฒด์ ์ธ ํ๋ฆ์ ์๋์ ๊ฐ๋ค.
CloudWatch์์ ์๋ ๋ฐ์ -> SNS ํธ์ ์๋น์ค ํธ์ถ -> Lambda ํจ์ ํธ๋ฆฌ๊ฑฐ -> Slack ์ฑ๋๋ก ์๋์ ์ก
1. Slack
์ฐ์ Slack์์ ์ ์ํฌ์คํ์ด์ค๋ฅผ ์์ฑํ๊ณ ์ค์ ์์ web hook์ ์ถ๊ฐํด์ค๋ค.
web hook์ด ์ ์์ ์ผ๋ก ๋์ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์๋ ์์ ๋ช
๋ น์ด๋ฅผ ๋ณต์ฌํ์ฌ ํฐ๋ฏธ๋์์ ์คํ์ํจ๋ค.
OK๊ฐ ๋จ๋ฉด ์ ์์ ์ผ๋ก ์ค์ ๋ ๊ฒ์ด๋ค.
OK๊ฐ ๋จ๋ฉด ๊ทธ ๋ค์ slack channel์ ๋ค์ด๊ฐ๋ฉด ์๋์ ๊ฐ์ ๋ฉ์์ง๊ฐ ๋์ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด์ web hook์ ์ ์์ ์ผ๋ก ์ค์ ๋์๋ค. ์ด์ ๋ AWS๋ฅผ ๊ฑด๋๋ฆด ์ฐจ๋ก์ด๋ค!
2. SNS ํ ํฝ ์์ฑ
CloudWatch์ ๊ฐ์ Publisher์๊ฒ์ ์จ ๋ฉ์์ง๋ฅผ lambda์ ๊ฐ์ ์๋ฒ๋ฆฌ์ค ์๋น์ค์๊ฒ ์ ๋ฌํด ์ฃผ๋ ์ญํ ์ ํ๋ค.
Lambda์ ๋ํด์ ์ถ๊ฐ์ ์ผ๋ก ๋งํ์๋ฉด, ์๋ฒ๋ฆฌ์ค ์ปดํจํ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ฉฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๊ธฐ ์ํ ๋ณ๋์ ์๋ฒ ์ ์ ์์ด ๊ณง๋ฐ๋ก ์ฝ๋๋ฅผ ์คํํด ์ฃผ๋ ์๋น์ค์ด๋ค.
์๋์ ๊ฐ์ด AWS์์ ๊ฐ๋จํ๊ฒ ์ฃผ์ ์ด๋ฆ๋ง ์ค์ ํ๋ฉด ์ถ๊ฐ๊ฐ ๋๋ค.
3. Lambda ์์ฑ
๋ธ๋ฃจํ๋ฆฐํธ ์ฌ์ฉ์ ์ฒดํฌํ๋ฉด ๋ค๋ฅธ ์ฌ๋๋ค์ด ๋ง๋ค์ด๋์ slack ์ฌ๋ก๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
๋ฐฉ๊ธ ๋ง๋ค์ด๋์ SNS๋ฅผ ์ฐ๊ฒฐํ๋ค.
๊ทธ๋ค์์๋ ํ๊ฒฝ ๋ณ์๋ฅผ ์ธํ
ํด์ค์ผ ํ๋ค. slackChannel๊ณผ kmsEncryptedHookUrl์ ์ถ๊ฐํด์ค์ผ ํ๋ค.
์ฑ๋ ๊ฐ์ ๊ฒฝ์ฐ๋ ๋ด๊ฐ ๋ง๋ค์ด๋์ ์ฌ๋ ์ฑ๋ ์ด๋ฆ์ ์
๋ ฅํ๋ฉด ๋์ง๋ง, kmsEncryptedHookUrl ๊ฐ์ ๊ฒฝ์ฐ์๋ ์๋ฌด๋ ๋ด๊ฐ ์ด๋ค ์ฑ๋๋ก ๋ณด๋ด๋์ง ์ ์ ์๊ฒ ์ํธํ๋ฅผ ํด์ผ ํ๋๋ฐ ์์ง ์ํธํ๋ฅผ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ์์์ ๊ฐ์ ์ง์ด๋ฃ๊ณ ๋์ค์ ์์ ํ๋ค.
์ด์ ๋๋ค๋ฅผ ์์ฑํ๋ฉด ์๋์ ๊ฐ์ ํ๋ฉด์ ๋ณผ ์ ์๋ค.
4. KMS (Key Management Service)
๋ฐ์ดํฐ๋ฅผ ์ํธํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ํธํ ํค์ธ Customer Master Key(CMKs)๋ฅผ ๊ด๋ฆฌํ๋ค.
์ฌ๊ธฐ์๋ Lambda ํจ์์์ Slack์ผ๋ก ๋ฉ์์ง๋ฅผ ์ ์กํ ๋ web hook์ ์ํธํํ๋๋ฐ ์ฌ์ฉํ๋ค.
aws kms create-key --region ap-northeast-2
์ ๋ช ๋ น์ ํตํด key๋ฅผ ์์ฑํ๋ค.
์ฌ์ฉํ ๋ ํธํ๋๋ก ๋ณ์นญ์ ๋ถ์ฌ์ค๋ค.
aws kms create-alias --alias-name alias/test-kms-key --target-key-id {keyId} --region ap-northeast-2
์ด์ ํค๋ฅผ ์ด์ฉํ์ฌ Slack URL์ ์ํธํํด์ผ ํ๋ค.
Lambda Function ๋ด์์ Hook Url์ Decryption ํ๋ ์ฝ๋๊ฐ ์๋์ ๊ฐ์ด ์ด๋ฏธ ์กด์ฌํ๊ณ ์์ ๊ฒ์ด๋ค.
HOOK_URL = "https://" + boto3.client('kms').decrypt( CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL), EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']})['Plaintext'].decode('utf-8')
๊ทธ๋ฆฌ๊ณ ์๋ฌด Lambda Function์์๋ ์ํธํ๋ Web Hook Url์ ๋ณตํธํํด์๋ ์๋๋ฏ๋ก key์ Lamda Function๋ ์ง์ ํด ์ค๋ค.
โป ์ฃผ์: Web Hook Url์์ https:// ๋ ๋นผ๊ณ ๋ฃ์ด์ผ ํจ. (๋ณตํธํ ์ฝ๋์ ์ด๋ฏธ https:// ๊ฐ ํฌํจ๋์ด ์๊ธฐ ๋๋ฌธ)
์๋ ๋ช ๋ น์ด๋ aws version 2.X ๊ธฐ์ค์ ๋๋ค.
aws kms encrypt --key-id alias/{kms key alias} --plaintext fileb://<(echo "hooks.slack.com/~~~") --region ap-northeast-2 --encryption-context LamdaFunctionName={lambda function name}
ํด๋น ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ๋ฉด "CiphertextBlob", "KeyId"์ key๋ฅผ ๊ฐ์ง value๋ค์ด ์ถ๋ ฅ๋๋ค.
"CiphertextBlob"์ value๋ฅผ Lambda ํจ์๋ฅผ ์์ฑํ ๋ ์ ๋ ฅํ๋ kmsEncryptedHookUrl ํ๊ฒฝ๋ณ์์ ๊ฐ์ ์ ๋ ฅํ์ฌ ์์ ํ๋ค.
"KeyId"์ value๋ฅผ ์ํธํ ๊ตฌ์ฑ์์ ๊ณ ๊ฐ ๋ง์คํฐ ํค ์ฌ์ฉ์ผ๋ก ๋ณ๊ฒฝํ์ฌ ๊ณ ๊ฐ ๋ง์คํฐ ํค์ ์ ๋ ฅ์ผ๋ก ๋ฃ๋๋ค.
์ด์ Lambda ํจ์์ KMS ํค Decrypt ๊ถํ์ ์ถ๊ฐํด์ผํ๋ค.
๋จผ์ KMS Decrypt ์ ์ฑ ์ ์๋์ ๊ฐ์ด JSON ํํ๋ก ์ถ๊ฐํ๋ค.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1443036478000",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": [
"<kms key Id ์
๋ ฅ>"
]
}
]
}
๊ทธ๋ฆฌ๊ณ ๋์ Lambda ํจ์์ ์๋ ์์ฑ๋ Role์ ์๋ก ์์ฑํ ์ ์ฑ ์ ์ฐ๊ฒฐํด์ฃผ๋ฉด ๋๋ค.
5. Cloudwatch
๊ฒฝ๋ณด ์์ฑ์์ ๋จผ์ ์งํ๋ฅผ ์ ํํด์ผํ๋ค.
๋๋ EC2์ CPU ์ฌ์ฉ๋์ ์ ํํ์๋ค.
๊ทธ ๋ค์ ๋ช๋ถ๋ง๋ค ๊ฒฝ๋ณด๋ฅผ ๋ณด๋ผ์ง์ ๊ฒฝ๊ณ๊ฐ๋ค์ ์ค์ ํ ์ ์๋ค.
๊ทธ ๋ค์ ์ด์ ์ ์์ฑํด๋ SNS๋ฅผ ์ฐ๊ฒฐํด์ค๋ค. ์ด์ ๊ฒฝ๋ณด๋ฅผ ์์ฑํ๋ฉด CPU ์ฌ์ฉ๋์ด ์ค์ ํ ๊ฐ์ด ๋์ผ๋ฉด ์ฌ๋์ผ๋ก ์๋ฆผ์ด ์ค๊ฒ ๋๋ค.