Slack-Codecommit 연동 :: 마이구미
이 글은 슬랙(Slack) 과 코드커밋(Codecommit) 을 연동하는 과정을 다룬다.
코드커밋은 AWS 에서 제공하는 Github 이라고 보면 된다.
AWS 람다(Lambda) 학습의 기본 예제로 볼 수 도 있기에, 람다 학습이 필요하다면 도움을 줄 것이다.
슬랙과 코드커밋을 연동하는 목적과 방식은 여러가지가 존재한다.
이 글에서 다루는 연동은 코드커밋에서 어떤 이벤트라도 발생한다면, 슬랙에 알려주는 것을 목표로한다.
이를 위해 본인이 다루는 방식은 다음과 같다.
- Codecommit - Git 저장소
- SNS - 메시지 트리거
- Lambda - 작성된 함수 호출
- CloudWatch Logs - 함수 실행에 관련된 로그 확인
위 그림의 흐름대로 코드커밋에서 발생한 이벤트를 슬랙에 알려준다.
그 결과는 다음과 같은 모습으로 슬랙에 출력하게 할 수 있다.
이러한 결과를 얻기 위해서 단계별로 알아본다.
- 슬랙 설정
- AWS 람다 함수 생성
- SNS Topic 생성
- SNS - Lambda 연동
- Codecommit 설정
1. 슬랙 설정
슬랙에서는 외부 요청을 전송받기 위한 방법으로, Custom Integrations 중 Incoming WebHooks 을 제공한다.
관련 페이지에서 필요한 설정들을 입력한다.
그 중 Webhook URL 의 값을 추후에 사용할 것이다.
이 URL에 AWS 람다 함수의 결과값을 반환한다고 보면 된다.
2. 람다 함수 생성
실질적인 부분으로써, 코드커밋에서 발생한 이벤트를 넘겨 받아 원하는 출력 형태를 위해 코드를 작성한다.
관련 이름을 "CODECOMMIT-WEBHOOK" 연동 으로 지정하겠다.
람다 함수 생성 과정에서 추후 작업을 위한 역할에 lambda, codecommit, cloudwatch 관련 정책을 지정해준다.
이번 단계에서는 아무 설정없이 단순히 람다 함수를 생성한 것이다. (즉, 이 상태로는 동작할 수 없다.)
추후 작업은 4번 단계에서 진행한다.
(관련 람다 함수 예제 코드는 가장 하단에 배치하겠다.)
3. SNS Topic 생성
SNS는 Topic 을 사용하여 게시와 구독을 분리할 수 있다.
코드커밋과 슬랙을 위한 새로운 Topic 을 생성한다.
이 토픽은 "codecommit-slack" 이라고 이름을 지어주겠다.
생성된 토픽을 들어간 후, "create Subscription" 버튼을 통해 구독을 생성해준다.
람다 함수 실행을 위해 프로토콜은 람다로 설정해준다.
엔드포인트는 이전에 생성한 "CODECOMMIT-WEBHOOK" 를 설정해준다.
이로써, SNS 는 메시지를 통해 관련 람다 함수를 실행한다.
4. SNS - Lambda 연동
이 단계는 SNS 를 통해 람다 함수를 실행하기 위한 작업이다.
SNS 를 클릭하면 관련 트리거 설정에서 이전에 생성한 토픽 "codecommit-slack" 을 선택하여 지정한다.
아래와 같은 결과 이미지가 나올 것이다.
5. Codecommit 설정
지금까지의 작업으로, SNS 와 Lambda 는 서로 연결되어 있다는 것은 어느정도 파악할 수 있다.
하지만 실질적으로 이벤트를 SNS 에게 알려주게 되는 코드커밋과의 연결고리는 없다.
그것은 해당 저장소의 설정 메뉴에서 트리거를 지정할 수 있다.
보내는 방식에 있어, 이 글에서 사용하는 SNS 를 설정해준다.
이전 단계에서 생성한 SNS Topic 을 설정해준다.
아래에 존재하는 "Test trigger" 버튼을 통해 쉽게 테스트할 수 있다.
버튼을 클릭한다는 것은 지정된 람다 함수를 실행한다는 것이다.
상태는 cloudWatch log 를 통해 확인하면 된다.
작업이 완료되면, Test trigger 또는 코드커밋에 이벤트가 발생하면 슬랙에 출력되는 것을 볼 수 있다.
출력되는 형식은 아래 코드에서 slackMessgae 변수를 참고하면 된다.
자세한 가이드는 슬랙 공식 문서를 참고하자.
https://api.slack.com/docs/message-attachments
이 글은 AWS 에서 Slack 에 요청하는 방식이다.
다음 글에서는 반대로 Slack 에서 AWS 에 요청하는 방식을 알아볼 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | const https = require("https"); const AWS = require("aws-sdk"); const url = require("url"); // to get the slack hook url, go into slack admin and create a new "Incoming Webhook" integration const slack_url = "[Webhook URL]"; const slack_req_opts = url.parse(slack_url); slack_req_opts.method = "POST"; slack_req_opts.headers = { "Content-Type": "application/json" }; exports.handler = function(event, context) { (event.Records || []).forEach(function(rec) { if (rec.Sns) { var req = https.request(slack_req_opts, function(res) { if (res.statusCode === 200) { context.succeed("posted to slack"); } else { context.fail("status code: " + res.statusCode); } }); req.on("error", function(e) { console.log("problem with request: " + e.message); context.fail(e.message); }); const codecommit = new AWS.CodeCommit({ apiVersion: "2015-04-13" }); const records = JSON.parse(event.Records[0].Sns.Message).Records[0]; let repository = records.eventSourceARN.split(":")[5]; let commitId = records.codecommit.references[0].commit; let region = records.eventSourceARN.split(":")[3]; const timestamp = new Date(event.Records[0].Sns.Timestamp).getTime() / 1000; let subject = event.Records[0].Sns.Subject; // Get the repository from the event and use it to get details of the commit codecommit.getCommit( { commitId: commitId, repositoryName: repository }, function(err, data) { if (err) { context.fail(err); } else { console.log(data); const commit = data.commit; let color = "#36a64f"; let branchName = records.codecommit.references[0].ref; let msg = commit.message; let authorName = commit.author.name + " <" + commit.author.email + ">"; const slackMessage = { text: "*" + subject + "*", attachments: [ { color: color, author_name: authorName, title: "CodeCommit Notification", title_link: "https://ap-northeast-2.console.aws.amazon.com/codecommit/home?region=" + region + "#repository/" + repository + "/commit/" + commitId, fields: [ { title: "Branch", value: branchName, short: false }, { title: "Message", value: "`" + msg + "`", short: false } ], ts: timestamp } ] }; req.write(JSON.stringify(slackMessage)); // for testing: , channel: '@vadim' req.end(); } } ); } }); }; | cs |