가상의 고객사 시스템 구축과 운영
SI
SM
CloudWatch에서 알람 발생 → SNS 푸시 서비스 호출 → Lambda 함수 트리거 → 연동된 Slack 채널로 알람 전송
Webhook
Webhook은 서버에서 이벤트가 발생했을 때 클라이언트를 호출하는 메커니즘 제공한다. 외부 시스템에서 이벤트가 발생하면, 클라이언트에서 제공하는 Webhook Trigger가 Action을 수행(슬랙 채널에 메세지 발송)한다. Webhook 내부에서 슬랙의 Webhook endpoint로 post 요청하는 것이다.
우리는 webhook을 통해서 서버에 문제가 발생하면 슬랙의 채널로 실시간 알림을 받을 것이다.
1. 작업용 워크스페이스 생성한 뒤 알림 받을 채널 생성 > 설정 및 관리 > 앱 관리
2. app directory에서 webhook을 검색한 뒤 '수신 웹후크'에 들어가 슬랙에 추가한다.
3. 채널을 선택하고 수신 웹후크 통합 앱 추가 버튼을 누른다.
4. 이름을 지정하고 저장한 뒤 웹 후크 URL을 복사한다. 이 URL은 계속 쓰일 예정이므로 잘 보관해둔다.
5. 설정 지침을 확장하면 cURL을 확인할 수 있다. 이것을 복사해서 EC2 인스턴스에 붙여넣기 한다.
6. 슬랙에 알림이 발생한 것을 확인한다.
SNS
SNS(Simple Notification Service)는 게시자(publisher)로부터 구독자(subscriber)에게 메시지를 전달해주는 서비스이다. 게시자는 이벤트를 생산하고 구독자는 이벤트 발생에 대한 메시지를 받는다.
1. SNS 서비스 대시보드에 들어간다.
2. 주제 생성 버튼을 누른다.
3. 표준을 선택하고 이름을 설정한 뒤 생성해준다.
Lambda
Lambda는 서버리스 컴퓨팅 서비스이다. 애플리케이션을 실행하기 위한 별도의 서버 셋업 없이 곧바로 코드를 실행해주며, 고정 비용 없이 사용 시간에 대해서만 비용을 발생시킨다. 코드를 Lambda 콘솔에서 인-라인으로 작성하거나 패키지로 업로드하기만 하면 자동으로 배포가 이루어진다. 모니터링도 간소화할 수 있어서 필요한 각종 지표들을 CloudWatch를 통해 확인할 수 있다.
1. Lambda 서비스 대시보드에 들어간다.
2. 함수 생성을 클릭한다.
3. 블루프린트는 특정한 함수를 수행하기 위한 샘플코드와 기본 설정을 제공한다. 블루프린트 사용을 누르고 cloudwatch-alarm-to-slack-python을 선택한다.
4. 함수 이름을 생성하고 다음과 같이 설정한다.
앞에서 생성한 SNS 선택
환경 변수
slackChannel: 작업용 채널 이름
kmsEncryptedHookUrl: 임시 값으로 test 저장
KMS
KMS(Key Management Service)는 데이터를 암호화하는 데 사용되는 암호화 키인 고객 마스터 키(CMKs)를 관리한다. 우리는 Lambda함수에서 Slack으로 메시지 전송할 때 KMS로 webhook url을 암호화할 것이다.
1. KMS 서비스 대시보드에 들어간다.
2. EC2 인스턴스에 다음과 같이 작성하여 KMS 키를 생성한다.
# aws kms create-key --region ap-northeast-2
3. 고객 관리형 키에서 키가 생성된 것을 확인한다.
4. 다음과 같이 작성해서 키 별칭을 설정해준다.
# aws kms create-alias --alias-name alias/{Key Name} --target-key-id {Your Key ID} --region ap-northeast-2
5. aws cli 버전을 확인하고 버전에 따라 키를 암호화하는 명령을 작성한다.
# aws --version
KMS 키 이름, Webhook url, Lambda 함수 이름에 오타가 없는지 반드시 확인한다(!!).
// AWS CLI version 1 일 때
# aws kms encrypt --key-id alias/{Key Name} --plaintext "{Webhook URL}" --region ap-northeast-2 --encryption-context LambdaFunctionName={Lambda Function Name}
// AWS CLI version 2 일 때
# aws kms encrypt --key-id alias/{Key Name} --plaintext fileb://<(echo "{Webhook URL}") --region ap-northeast-2 --encryption-context LambdaFunctionName={Lambda Function Name}
CiphertextBlob의 값이 암호화된 webhook url이다.
Lambda 함수의 환경변수와 정책을 설정해줄 것이다.
1. 구성 > 환경변수 편집
2. 생성한 KMS 키를 고객 마스터 키로 설정하고 kmsEncryptedHookUrl에는 앞에서 암호화해준 webhook url인 CiphertextBlob를 복사해서 붙여넣고 저장한다.
3. 구성> 권한에서 역할 이름을 클릭하면 AWSLambdaBasicExecutionRole 정책을 볼 수 있다. 이것은 기본으로 생성되는 실행 권한으로, 로그 파일과 관련된 정책이다. KMS 키로 암호화 된 webhook url을 lambda 함수에서 decrypt(해독)하기 위해 KMS decrypt 정책이 필요하다.
4. IAM 서비스로 가서 정책 > 정책 생성 해준다. JSON에 다음 Policy를 입력한다. KMS key ARN은 해당 서비스로 가서 복사해온다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1443036478000",
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": [
"<your KMS key ARN>"
]
}
]
}
5. 정책 이름을 설정해준다. 오타가 있으므로 수정하여 진행한다!! (Excution > Execution)
6. 다시 Lambda 함수의 정책으로 돌아가 정책 연결을 클릭해서 생성한 정책을 연결해준다.
1. Lambda의 테스트 탭에 들어가 새 이벤트를 작성해준다. 템플릿은 hello-world, 이름은 자유롭게 설정한 뒤 내용에 다음과 같이 입력한다.
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:eu-west-1:000000000000:cloudwatch-alarms:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"Sns": {
"Type": "Notification",
"MessageId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"TopicArn": "arn:aws:sns:eu-west-1:000000000000:cloudwatch-alarms",
"Subject": "ALARM: \"Example alarm name\" in EU - Ireland",
"Message": "{\"AlarmName\":\"Example alarm name\",\"AlarmDescription\":\"Example alarm description.\",\"AWSAccountId\":\"000000000000\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (10.0) was greater than or equal to the threshold (1.0).\",\"StateChangeTime\":\"2017-01-12T16:30:42.236+0000\",\"Region\":\"EU - Ireland\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"DeliveryErrors\",\"Namespace\":\"ExampleNamespace\",\"Statistic\":\"SUM\",\"Unit\":null,\"Dimensions\":[],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":1.0}}",
"Timestamp": "2017-01-12T16:30:42.318Z",
"SignatureVersion": "1",
"Signature": "Cg==",
"SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.pem",
"UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:000000000000:cloudwatch-alarms:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"MessageAttributes": {}
}
}
]
}
변경 사항 저장 > 테스트
2. 슬랙에 다음과 같은 메시지가 오면 성공이다.
1분 동안 bastion instance의 CPU 사용률 50%가 1회 이상 발생하면 알람을 발생하고 이를 슬랙으로 받아볼 것이다.
1. CloudWatch 서비스에서 경보를 생성한다.
2. EC2 인스턴스의 CPU를 모니터링할 것이므로 지표를 다음과 같이 선택해준다.
[ 지표 선택 > EC2 > 인스턴스별 지표 > CPU Utilization, bastion 인스턴스 선택 ]
3. 지표와 조건을 지정해준다.
1분 동안 CPUUtilization이 50보다 크면 경보를 발생할 것이다.
4. 알림을 설정해준다. 지표가 임계값을 벗어났을 때 경보 상태를 트리거하고, 앞에서 생성한 SNS로 알림을 전송한다. Lambda 함수가 이 SNS를 구독하고 있으므로, 트리거가 발생하면 Lambda 함수에서 webhook을 통해 슬랙으로 알림을 보낼 것이다.
이름을 설정해주고 저장한다.
알림이 제대로 작동하는지 확인하기 위해 임의로 1분 동안 bastion instance의 CPU 사용률 50%를 달성하도록 부하를 발생시킬 것이다.
1. bastion instance에 stress를 설치한다.
# sudo amazon-linux-extras install epel -y
# sudo yum install stress -y
2. 5분(300초)동안 cpu 99.9%를 사용한다.
# stress --cpu 1 --timeout 300
3. 작업이 완료되면 CloudWatch에 경보가 발생하고 슬랙에 경보 알림 메시지가 전송된다. 이렇게 되면 성공!