현재 담당하고 있는 서비스는 amplify 를 통해 master 와 staging 브랜치를 기준으로 배포 환경 구성이 되어있다.
그동안은 프론트를 혼자 담당하고 있었고 마스터 배포가 잦은 편은 아니었기에 직접 aws amplify 에 접속해 배포 현황을 보고 배포가 완료되면 팀 채널에 공유하는 식으로 업무를 진행했었는데, 조금씩 마스터 배포가 훨씬 자주 일어나게 되자 amplify 접속하는 것도 귀찮아져서 슬랙 알람 봇을 구현해야겠다는 생각을 했다.
amplify 는 이메일 알람 이외 다른 notification은 제공하지 않았기에 이메일 트리거를 사용하는 방법을 택했다.
그렇게 찾은 두 가지 방법
- 개인용 슬랙 메일 주소로 알람 받는 법
- amplify의 이메일 노티를 감지해 lambda 함수로 슬랙 웹훅에 전달하기
1. 개인용 슬랙 메일 주소로 알람 받는 법
우선 1의 경우를 설명하자면 슬랙 계정의 preferences -> Messages & Media 탭 하단을 보면 개인용 이메일 계정을 확인할 수 있다.
개인용 이메일 주소를 aws Amplify -> notifications 의 이메일로 등록한다.
그럼 이제 아래와 같이 slack-bot 앱을 통해 메일을 받을 수 있게 된다.
이렇게 간단하게 본인만 확인 가능한 alert 구현이 가능하다.
그런데... 이 방법은 내게 2가지 정도의 문제가 있었다
우선 프론트엔드로써.. 저렇게 빌드 상태 구분조차 힘든 UI 를 용납할 수 없었다.
그리고 그 전까지는 FE 1인 체계였기에 알림을 개인 이메일 슬랙봇으로 받아도 무방했으나, 새 팀원 분의 합류로 이제는 배포 현황에 대한 알람 채널이 필요하다는 생각이 들었다.
그래서 2의 방법을 시도했다.
2. amplify의 이메일 노티를 감지해 lambda 함수로 슬랙 웹훅에 전달
조금 더 자세 하게 말하자면 amplify에 이메일 주소를 등록해 놓게 되면 amplify 는 빌드 상태가 변경될 때마다 해당 이메일 주소로 이벤트를 실행 시켜 이메일을 발송하게 되어있는데,
이 이벤트를 AWS SNS 를 통해 감지하고 이를 트리거로 갖는 AWS lambda 함수를 만들어 슬랙 API 를 사용, 알람을 받을 수 있도록 구현하는 것이다.
세부 설정 방법은 아래 링크를 참고했다.
How to Send Slack Notifications for AWS Amplify Deployments
Save time and set up Slack notifications for your front-end projects
betterprogramming.pub
나의 경우 위 링크에서의 함수 코드를 그대로 넣으니 작동이 안되어 보니 lambda 함수 실행 파일이 .mjs 의 형식으로 기본 셋팅 되어있어 발생한 문제라 index.js로 파일명 수정 후 정상 작동 되는 것을 확인했다.
위 함수 그대로 웹훅에 연결하게 되면 아래와 같이 1번의 방법을 사용했던 이메일로 오던 message 를 그대로 보내주고 있는 것을 확인할 수 있다.
하지만 영 맘에 드는 구조가 아니었기에 받을 수 있는 데이터를 탐색하기 시작했다.
Amplify event 객체 (일부 마스킹처리)
const event = {
Records: [
{
Sns: {
Type: 'Notification',
MessageId: '보안',
TopicArn: 'arn:aws:sns:보안',
Subject: null,
Message:
'"Build notification from the AWS Amplify Console for app: https://master.보안.com/. Your build status is STARTED. Go to https://console.aws.amazon.com/amplify/보안/master/47 to view details on your build. "',
Timestamp: '2023-09-13T07:16:42.890Z',
SignatureVersion: '1',
Signature: '보안',
SigningCertUrl: 'https://##보안.pem',
UnsubscribeUrl: 'https://##보안',
MessageAttributes: {},
},
},
],
};
Message만 추출해서 보여주던 이유가 있었다.
그것 말고는 정보가 딱히 없었기 때문에.....
더 많은 정보를 보여주고 싶어 이런 저런 방법을 찾아봤는데 직접 shell script를 짜거나 무엇인가를 하라고 했는데 잘 모르는 분야이기도 하고 당장 필요한 기능은 아닌 듯 하여 좀 더 세밀한 개발 환경 구축이 필요할 때 학습하여 도입하고, 그 전까지는 우선 위 이벤트 객체를 활용하는 쪽을 택했다.
일단 쓸 수 있는 데이터를 파악한 뒤 아래와 같이 js 의 exports.handler 이벤트 함수 코드를 수정했다.
exports.handler = async event => {
const message = event.Records[0].Sns.Message.slice(1, -1);
const buildStatus = message.includes('STARTED')
? 'STARTED'
: message.includes('FAILED')
? 'FAILED'
: 'SUCCEED';
const urlRegex = /https:\/\/[^\s]+/g;
const urlMatches = message.match(urlRegex);
const branchNameMatches = urlMatches[0].includes('master')
? '마스터'
: urlMatches[0].includes('staging')
? '스테이징'
: '알 수 없는 브랜치';
const deployHistory = urlMatches[1].split('/').pop();
const title =
buildStatus === 'STARTED'
? `🚀 ${branchNameMatches} ${deployHistory}번째 빌드 시작!\n`
: buildStatus === 'FAILED'
? `👿 ${branchNameMatches} 배포 실패!\n`
: `🌼 ${branchNameMatches} ${deployHistory}번째 배포 성공!\n`;
const timestamp = new Date(event.Records[0].Sns.Timestamp).getTime() / 1000;
const slackMessage = {
attachments: [
{
title,
title_link:
buildStatus === 'SUCCEED' ? 'https://www.hoolzzuk.com/' : undefined,
color:
buildStatus === 'STARTED'
? 'info'
: buildStatus === 'FAILED'
? 'danger'
: 'good',
fields: [
{
title: '브랜치',
value: branchNameMatches,
short: true,
},
{
title: '배포 현황',
value: urlMatches[1],
},
],
ts: timestamp,
},
],
};
await postRequest(slackMessage);
};
정규 표현식을 사용해(gpt 최고) message에서 Url만 추출한 뒤 url에 존재하는 빌드 히스토리 스택과 브랜치 이름을 식별할 수 있도록 했고, 빌드 상태를 좀 더 시각적으로 분명하게 보여주기 위해 상태 별 타이틀과 컬러의 핸들링을 진행했다.
오늘의 결과물
나름 로켓도 달고 악마도 넣고 꽃도 넣었다
팀장님이 보시더니 "와~ 힙해요~"라고 호응해주셨다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
담당하는 서비스가 계속 커지면서 안정적이고 편한 개발 환경은 무엇일지에 대해 많은 고민을 하고 있는데 이번 기회를 통해 lambda 라는 존재에 대해서 조금 더 알게 된 것 같아 좋은 경험이었다고 생각한다.
'Code > Dev environment' 카테고리의 다른 글
[package] patch-package로 오픈 소스 수정하여 사용하기 (0) | 2023.10.01 |
---|---|
CLI (Command Line Interface) 개념 및 주요 명령어 (0) | 2020.09.20 |