AWS Chatbot을 이용한 Slack alert, 근데 이제 PagerDuty와 Terraform을 곁들인

AWS에서 서비스를 운영하면서 CloudWatch Alarm을 이용하지 않는 팀은 거의 없을 것입니다. Airbridge에서도 ELB와 같은 Managed Service들의 metric뿐만 아니라 custom metric들에 대해서도 alarm을 구성하여 모니터링에 활용하고 있습니다.
Alarm을 잘 활용하기 위해서는 alert channel 설정이 필수적입니다. 보통 업무용으로 slack을 쓰는 경우가 많기 때문에 많은 팀이 alert channel으로 slack을 이용합니다. 하지만 그 연동 작업에 불편함이 컸었는데요. AWS Chatbot 서비스를 이용한 개선에 관해 이야기해보려고 합니다.
또한, 중요한 alert에 대해서는 PagerDuty와 같은 incident 관리 도구를 연동하곤 합니다. Pagerduty 연동은 어떻게 하면 좋을지에 대한 고민 결과까지도 함께 다뤄보겠습니다.

기존 Practices의 문제점

aws cloudwatch alarm alert to slack 정도의 키워드로 검색하면 대부분의 article들이 Lambda와 slack의 incoming webhook 혹은 app을 이용한 방법을 소개합니다. 사실 slack으로 alert을 보내고자 하는 니즈는 매우 오래전부터 있었기 때문에 이러한 구현 방법은 일찍부터 practices가 많이 공유됐었습니다.
하지만 이렇게 운영할 경우 alert을 위해 쓰이는 lambda에 대한 운영을 신경 써야 한다는 점, 그리고 편하게 slack 내 여러 channel에 대해 연동할 때 코드 작업 혹은 구조적인 고민이 필요하다는 단점이 있습니다. 예를 들면 incoming webhook을 이용하여 연동했을 경우, 새로운 channel을 추가하고 싶다면 코드 수정이 필요할 가능성이 높습니다. 처음에 좀 더 신경 써서 개발한다면 parameter store 등에 channel별incomming webhook mapping을 두는 등의 방식으로도 할 수 있지만 보통 빠르게 구현하기 위해 코드 레벨에 하드 코딩하는 경우가 많기 때문입니다.
이럴 경우 lambda의 코드를 수정할 때마다 불편함을 감수하거나, 배포를 편하게 할 수 있는 환경을 만드는 등의 노력이 필요합니다. 이 뿐만 아니라 metric에 대한 alert을 설정할 경우 거의 보통은 metric의 visualization graph 등이 함께 보이게 하고 싶어 하는데 이를 위해 추가적인 코드 작업이 필요합니다.

AWS Chatbot

AWS에는 Chatbot이라는 managed service가 존재합니다. 주로 많이 쓰이는 몇 가지 chatbot 시나리오들에 대해 미리 구현이 되어 있어 바로 사용 가능한 완전 관리형 서비스입니다. 예를 들면 Lambda invoke를 chatbot을 통해 slack에서 가능하게 하거나, 이 글에서 다루는 주제인 CloudWatch alarm에 대한 연동 자동화 등이 포함되어 있습니다. 지원되는 client는 Chime와 Slack뿐이지만 많은 팀이 이미 Slack을 활용하고 있기 때문에 활용에 큰 문제가 없을 거라 예상합니다.
Configure new client를 통해 새로운 slack workspace를 쉽게 추가할 수 있습니다.
앞서 기존 Practices에서의 문제점으로 지적했던 channel 추가도 쉽게 됩니다.
위 연동에서 설정한 SNS topic에 대해 CloudWatch alarm을 설정하면 slack을 통해 alert을 확인할 수 있습니다.
Chatbot에 다른 어떤 기능들이 지원되는지에 대해서는 이 글의 주제를 벗어나므로 자세한 내용은 AWS 공식 문서를 참고해주세요.

AWS Chatbot w/Terraform

channel들을 하나하나 손으로 연동하는 것은 고통입니다. 고통스럽다면 손이 덜 가게 되고, 결국 적극적으로 연동을 하지 않게 될 수 있습니다. 그 때문에 자동화를 잘해두는 것이 중요한데요. 문제는 AWS Chatbot에 대해 공식 API 제공을 하지 않고 있다는 것입니다. 예를 들어, aws cli에서도 chatbot service에 대한 기능은 제공하지 않고 있습니다.
Terraform은 가장 널리 쓰이는 IaC 도구 중 하나로, 이런 AWS resource를 code로 관리하기 위해 널리 쓰입니다. Airbridge에서도 terraform을 이용한 infra 관리를 많이 하고 있습니다. 다행히, 저와 같은 고민을 먼저 한 분이 module을 공개해뒀습니다. 내부를 보면 CloudFormation을 활용하는 트릭으로 위 chatbot 연동을 구현했습니다. 실제로 사용 시 아래와 같은 코드로 configuration, channel id, workspace id, sns topic 등만 지정하면 쉽게 적용 가능합니다.
slack 또한 terraform slack provider가 존재합니다. 위 코드 예시에서 workspace id는 연동마다 바꿀 일이 없는 값이지만 channel id는 그렇지 않습니다. channel id를 따로 알아내려면 channel link를 복사하는 등의 작업을 해야 하는데 channel 생성도 terraform으로 자동화하면 그 불편함을 줄일 수 있습니다.

AWS PagerDuty Integration

Slack alert만으로는 충분하지 않은 경우가 있습니다. 즉각 대처가 필요한 경우 전화나 SMS 등으로 alert을 받을 수 있어야 합니다. Airbridge 팀에서는 PagerDuty라는 incident 도구를 사용하고 있습니다. 여러 Service에 대해서 escalation policy도 제공하고, incident에 대해서 acknowledge, snooze, resolve 등 핵심 기능을 잘 제공하기 때문에 오래전부터 사용하고 있습니다.
PagerDuty에서 제공하는 AWS integration은 여러 가지가 있지만 Airbridge에서는 크게 CloudWatch, Email integration 두 가지를 사용합니다. AWS와 PagerDuty를 연동할 때 실제로는 SNS를 통해 연동하는데, CloudWatch alarm 대상을 SNS topic으로 지정하고 해당 SNS topic에 대해 PagerDuty CloudWatch integration endpoint를 subscription으로 추가하면 CloudWatch alarm이 trigger 됐을 때 PagerDuty incident가 생성됩니다. 자세한 설명은 문서를 참고해주세요.
CloudWatch alarm을 매번 만들어주기 불편한 상황이 존재합니다. 예를 들면, Airflow DAG에서 failure callback으로 PagerDuty incident를 생성하고 싶은 경우입니다. DAG마다 CloudWatch alarm을 생성하기는 애매한 상황입니다. 이 경우, email integration을 사용할 수 있습니다. SNS topic의 Subscriptions로 email integration의 mail 주소를 넣으면 SNS topic에 message publish를 했을 때 PagerDuty에서 incident를 생성합니다.
단, SNS에서 email subscription의 경우 confirm mail에서 직접 confirm을 해줘야 하므로 자동화에 어려움이 있습니다. 이 불편함 때문에 Global event rule 등을 알아봤지만 너무 복잡해지는 것보다는 단순한 것이 관리하기 더 용이하다고 판단하여 email integration 방식을 유지하기로 했습니다.

PagerDuty w/Terraform

기존에는 PagerDuty까지는 IaC 하지 못했지만, terraform pagerduty provider를 본 뒤 terraforming 하기로 결정했습니다. terrafoming 할 대상은 escalation policy, service, integration입니다.
아쉽게도 extension은 terraforming 하지 않기로 했습니다. PagerDuty를 사용할 때 slack extension을 사용하면 slack에서 acknowledge, resolve 등을 할 수 있어서 매우 편리합니다. 하지만 extension을 terraforming 하려면 webhook url을 넣어야 하는데 webhook url을 만들고 가져오는 절차가 불편합니다. 차라리 PagerDuty dashboard에서 oauth로 연동하기가 훨씬 쉽고 인지하기도 편하다고 판단하여 slack extension은 dashboard에서 직접 연동하기로 했습니다.
이런 의사 결정의 배경에는 email integration 또한 수동으로 해줘야 하는 것이라는 점이 중요하게 작용했습니다. 앞서 언급한 것과 같이 email integration의 경우 직접 confirm을 해줘야 하기 때문입니다. 대신 terraform에서 aws_sns_topic_subscription resource를 생성해서 confirm mail을 자동으로 보내게 하는 것까지는 자동화 가능합니다.

마치며

AWS SNS, Chatbot, PagerDuty를 서로 연동하는 방법과 이를 IaC 하려면 어떻게 해야 하는지를 알아봤습니다. 완전히 자동화되지 않는 영역들이 존재해서 아쉽긴 하지만 dashboard에서 직접 연동하던 것보다는 훨씬 더 관리하기 쉽고 편리하기 때문에 만족스러운 개선 작업이었습니다.
Airbridge 백엔드 팀에서는 계속 채용을 진행하고 있습니다. 더 복잡한 시스템도 간단하게, 하지만 안정적으로 운영할 수 있도록 자동화하는 것을 좋아하시는 분들의 많은 관심 부탁드립니다!
ᴡʀɪᴛᴇʀ
Juhong Jung @toughrogrammer Backend Software Engineer
유니콘부터 대기업까지 쓰는 제품. 같이 만들어볼래요? 에이비일팔공에서 함께 성장할 다양한 직군의 동료들을 찾고 있어요! → 더 알아보기