Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

Kenichi Sasaki

March 06, 2018
Tweet

More Decks by Kenichi Sasaki

Other Decks in Technology

Transcript

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

    access tokens • (bot専用のGitHubアカウントがよさそう)
  2. 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
  3. How to get personal token Settings > Developer settings >

    Personal access tokens > Generate new token Scopeの選択は repo
  4. 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
  5. 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'); }); };
  6. 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 }); // 以降実行したいコード }
  7. AWS SNS - Lambda連携 exports.handle = (event, context, callback) =>

    { let msg = JSON.parse(event.Records[0].Sns.Message); { Event: { Records[{ Sns: { Message: “エスケープされたJSON形式でのGitHubイベント” } }] } }
  8. 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."); }
  9. 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"]}'