AWS Lambdaで作るGitHub bot/GitHub bot made with AWS Lambda

AWS Lambdaで作るGitHub bot/GitHub bot made with AWS Lambda

575b9ff9b04d8598ab4f5774bb431b02?s=128

Kenichi Sasaki

March 06, 2018
Tweet

Transcript

  1. AWS Lambdaで作る GitHub bot SRE-SET Automation-night #2 佐々木 健一 SRE@株式会社メルカリ

  2. 自己紹介 Kenichi SASAKI (@siroken3) Software Engineer (SRE) Mercari, Inc (2014/7〜)

  3. GitHub bot • 造語 • bot=人間ぽいもの • botと仲良く働いてやりましょう!

  4. GitHub botでできること • PullRequestへのコメントで何かさせる • Issueに自動的にラベリング • PullRequestの内容チェック • Request_changes

    • GitHub apiは多機能
  5. AWS Lambda • AWSのサーバレスアーキテクチャ • インフラの面倒をみなくてもよい

  6. 今回作ってみるGitHub bot • PullRequest へのコメントに反応 • 「Repeat 文言」 とコメントするとbotが 発言

  7. デモ

  8. 全体像 SNS Event Invoke GitHub api

  9. 開発環境 • 言語 • Node.js (v6.10.3) • ライブラリ • AWS-SDK

    • @octocat/rest
  10. 開発環境 • デプロイツール • Apex (http://apex.run) • GitHub統合方法 • Personal

    access tokens • (bot専用のGitHubアカウントがよさそう)
  11. 今回のコードは https://github.com/siroken3/SreSetAutomationNightVol2

  12. Lambda SNS Event Invoke GitHub api

  13. Apex project init $ apex init _ ____ _______ __

    / \ | _ \| ____\ \/ / / _ \ | |_) | _| \ / / ___ \| __/| |___ / \ /_/ \_\_| |_____/_/\_\ Enter the name of your project. It should be machine-friendly, as this is used to prefix your functions in Lambda. Project name: SRE-SET-Automation-Night-Vol2 Enter an optional description of your project. Project description: A sample apex project for SRE-SET automation night vol.2 [+] creating IAM SRE-SET-Automation-Night-Vol2_lambda_function role [+] creating IAM SRE-SET-Automation-Night-Vol2_lambda_logs policy [+] attaching policy to lambda_function role. [+] creating ./project.json [+] creating ./functions Setup complete, deploy those functions! $ apex deploy
  14. GitHub api SNS Event Invoke GitHub api

  15. How to get personal token Settings > Developer settings >

    Personal access tokens > Generate new token Scopeの選択は repo
  16. Create KMS Key for Encrypt Apexが生成した Role 自分の IAMユーザ AWS

    KMS で暗号化
  17. Encrypt personal token $ aws kms encrypt --key-id \ arn:aws:kms:us-east-1:xxxxxxxxxxxx:alias/AutomationNight

    \ --plaintext $TOKEN \ --query CiphertextBlob \ --output text (base64化されたTOKENが出力される) $ vim project.json "role": "arn:aws:iam::... "environment": { "GITHUB_TOKEN": (base64化されたTOKEN) }, "kms_arn": 作成したKMS Keyのarn
  18. Decrypt the token const AWS = require("aws-sdk"); const decrypt =

    (encrypted) => { const kms = new AWS.KMS(); return kms.decrypt({ CiphertextBlob: new Buffer(encrypted, 'base64') }).promise() .then((data) => { return data.Plaintext.toString('ascii'); }); };
  19. Decryptされたtokenで認証 exports.handle = (event, context, callback) => { let message

    = JSON.parse(event.Records[0].Sns.Message); let encryptedGithubToken = process.env['GITHUB_TOKEN']; decrypt(encryptedGithubToken) .then((token) => { // Decrypt enveironment variable GITHUB_TOKEN octokit.authenticate({ type: "oauth", token: token }); // 以降実行したいコード }
  20. Lambda invoke SNS Event Invoke GitHub api

  21. Setup AWS SNS Topics

  22. AWS SNS - Lambda連携

  23. AWS SNS - Lambda連携 exports.handle = (event, context, callback) =>

    { let msg = JSON.parse(event.Records[0].Sns.Message); { Event: { Records[{ Sns: { Message: “エスケープされたJSON形式でのGitHubイベント” } }] } }
  24. PullRequestにコメント const octokit = require("@octokit/rest")(); // This condition prevents infinity

    loop if (mag.comment.body.match(/^repeat/i)) { // Call GitHub api which creates issue comment. return octokit.issues.createComment({ owner: msg.repository.owner.login, repo: msg.repository.name, number: msg.issue.number, body: `@${msg.sender.login}, You said "${msg.comment.body}"` }); } else { return Promise.resolve("The comment was ignored."); }
  25. Setup GitHub SNS Event SNS Event Invoke GitHub api

  26. GitHub発行イベント (Repository) Settings > Integrations & services

  27. GitHub発行イベント • デフォルトでSNSで受け取れるGitHub のイベント= “push”のみ • 変更できる

  28. GitHub発行イベント変更 $ export TOKEN=xxxx $ export REPO_NAME=SreSetAutomationNightVol2 $ export GITHUB_ID=siroken3

    $ export HOOK_ID=$(curl -X GET -s -H "Authorization: token $TOKEN" https://api.github.com/repos/$GITHUB_ID/$REPO_NAME/hooks | jq '.[] | select( .name == "amazonsns") | .id') $ curl -X PATCH -s -H "Authorization: token xxxxxx" https://api.github.com/repos/$GITHUB_ID/$REPO_NAME/hooks/$HO OK_ID -d '{"add_events": ["issue_comment"], "remove_events": ["push"]}'
  29. これで全てがつながった! SNS Event Invoke GitHub api

  30. 今回のコードは https://github.com/siroken3/SreSetAutomationNightVol2

  31. 所感・落ち穂拾い • システム間連携肝要 • プリミティブな処理も必要 • GitHub apiのドキュメント重要 • イベントの解析にconsole.log重宝

    • AWS Cloud9のlambdaデバッガよさそう?
  32. 参考 • GitHubのプルリクエストをAmazon SNSに通知する (クラスメソッド株式会 社) • https://dev.classmethod.jp/cloud/aws/github-p ullrequest-to-amazonsns/

  33. 参考 • AWS Lambdaで環境変数とKMSを 使ってkintoneのAPIアクセス情報を設 定する (株式会社ジョイゾー) • https://www.joyzo.co.jp/blog/3616

  34. 参考 • @octokit/rest • https://octokit.github.io/rest.js • GitHub REST API v3

    (GitHub Inc.) • https://developer.github.com/v3/
  35. ご静聴ありがとうございました