Slide 1

Slide 1 text

GAEアプリをCI/CDして 結果をSlackに通知した話 2019/1/31 Go(Un)Conference LT大会 5kg

Slide 2

Slide 2 text

Google Cloud Platform プレミアパートナー 自己紹介 名前: 本 雄太朗 (@qushot) 所属: クラウドエース株式会社 業務: サーバサイド(GAE, GKE)をGoで開発 Go歴: 2年弱

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

前置き

Slide 5

Slide 5 text

Google App Engine GoogleのインフラでWebアプリを実行できるPaaS。 開発者はアプリのコードだけ書いてればいいので楽。 Go 1.11対応(beta)。

Slide 6

Slide 6 text

Cloud Build 基本的にはコンテナイメージをビルドするためのサービス。 GitHubなどのリポジトリにPushすると 設定ファイルに従ってビルド・テスト・デプロイなどの処理ができる。

Slide 7

Slide 7 text

Cloud Pub/Sub ストリーム分析とイベント駆動型コンピューティング向けの基盤 メッセージキューみたいなサービス

Slide 8

Slide 8 text

Google Cloud Functions イベント駆動型のサーバーレスコンピューティングプラットフォーム。 HTTPリクエストやGCP/Firebaseでのイベントをトリガーに関数を実行する。 Go 1.11対応(beta)

Slide 9

Slide 9 text

話すこと 1. GAE/GoアプリをCloud BuildでCI/CDする! 2. CI/CDの結果をGCF/GoでSlack通知!

Slide 10

Slide 10 text

GAE/GoアプリをCloud BuildでCI/CD

Slide 11

Slide 11 text

やること Cloud Buildのトリガーを設定 ビルド設定ファイルを作成 Developer Cloud Build GitHub App Engine Build Trigger Build & Deploy Push

Slide 12

Slide 12 text

やること Cloud Buildのトリガーを設定 ビルド設定ファイルを作成 Developer Cloud Build GitHub App Engine Build Trigger Build & Deploy Push

Slide 13

Slide 13 text

Cloud Buildのトリガーを設定 ソースを選択(GitHubやBitbucket) リポジトリを選択 トリガーとするブランチや ビルド設定ファイルの選択 Cloud Buildでの環境変数を設定する

Slide 14

Slide 14 text

やること Cloud Buildのトリガーを設定 ビルド設定ファイルを作成 Developer Cloud Build GitHub App Engine Build Trigger Build & Deploy Push

Slide 15

Slide 15 text

ビルド設定ファイルを作成 cloudbuild.yaml - フロントのコードをビルドするステップ - go get するステップ - テストを走らせるステップ - デプロイするステップ steps: # デプロイするステップの例 - name: "gcr.io/cloud-builders/gcloud" args: [ "app", "deploy", "--project=$PROJECT_ID", "--no-promote", "./app/app.yaml", ]

Slide 16

Slide 16 text

CI/CDの結果をGCF/GoでSlack通知

Slide 17

Slide 17 text

やること Slackbot準備 (詳細は省略) 結果を受け取って投げる関数を実装 Cloud Build Cloud Functions Cloud Pub/Sub Slack Push Subscription Notification Event

Slide 18

Slide 18 text

やること Slackbot準備 (詳細は省略) 結果を受け取って投げる関数を実装 この辺は特になにもしなくてよい→ Cloud Build Cloud Functions Cloud Pub/Sub Slack Push Subscription Notification Event

Slide 19

Slide 19 text

やること Slackbot準備 (詳細は省略) 結果を受け取って投げる関数を実装 Cloud Build Cloud Functions Cloud Pub/Sub Slack Push Subscription Notification Event

Slide 20

Slide 20 text

ファイル構成 .bot ├── cmd │ └── main.go ←ローカル開発時に使う ├── shared │ └── shared.go ←共通ロジックなどを置いておく ├── build_report.go ←デプロイする関数を置いておく ├── .env.yaml ←環境変数を書いておく ├── build_report_deploy.sh ←デプロイ用スクリプト ├── go.mod └── go.sum

Slide 21

Slide 21 text

ファイル構成 .bot ├── cmd │ └── main.go ←ローカル開発時に使う ├── shared │ └── shared.go ←共通ロジックなどを置いておく ├── build_report.go ←デプロイする関数を置いておく ├── .env.yaml ←環境変数を書いておく ├── build_report_deploy.sh ←デプロイ用スクリプト ├── go.mod └── go.sum

Slide 22

Slide 22 text

関数を実装する build_report.go // PubSubからのメッセージ受ける構造体 type PubSubMessage struct { Data []byte `json:"data"` } // ↑のbyte配列をUnmarshalするための構造体 // 関数はPublicに func BuildReport(ctx context.Context, m PubSubMessage) error { // 処理 return nil } type build struct { Status string `json:"status"` LogURL string `json:"logUrl"` }

Slide 23

Slide 23 text

関数を実装する build_report.go // PubSubからのメッセージ受ける構造体 type PubSubMessage struct { Data []byte `json:"data"` } // ↑のbyte配列をUnmarshalするための構造体 // 関数はPublicに func BuildReport(ctx context.Context, m PubSubMessage) error { // 処理 return nil } type build struct { Status string `json:"status"` LogURL string `json:"logUrl"` } json.Unmarshalして、 buildのStatusが “SUCCESS” の場合は成功 Statusが “FAILURE”, “INTERNAL_ERROR”, “TIMEOUT” の場合は失敗 の通知を飛ばす処理を書く ※Statusには上記以外のものもあるので、気をつけないと通知まみれになる

Slide 24

Slide 24 text

別のトリガーを利用したい場合 公式ドキュメントに各トリガー向けのサンプルがあります https://cloud.google.com/functions/docs/calling/

Slide 25

Slide 25 text

環境変数を定義する .env.yaml OAUTH_ACCESS_TOKEN: xoxp-0123456789-foo-bar VERIFICATION_TOKEN: FooBarHogeFufu CHANNEL_ID: ABCDEFG Goからos.Getenvで読み込める

Slide 26

Slide 26 text

デプロイする build_report_deploy.sh #!/bin/bash gcloud functions deploy build_report \ --region asia-northeast1 \ --entry-point BuildReport \ --stage-bucket project-id_cloudbuild \ --runtime go111 \ --env-vars-file .env.yaml \ --trigger-topic cloud-builds Functionsでの関数名 デプロイ対象のGoの関数 環境変数のファイル

Slide 27

Slide 27 text

GitHubにPushすると... はい嬉しい

Slide 28

Slide 28 text

全体的なアーキテクチャ Developer Cloud Build GitHub App Engine Trigger Build & Deploy Push Pub/Sub Functions Slack Event Push Subscription Notification

Slide 29

Slide 29 text

微妙なところ GAEではデプロイ時に内部でCloud Buildを利用しているため、 Functionsのトリガーが反応してしまう つまり、自分で定義したCloud Build TriggerとGAEのCloud Buildを 区別する方法が無さそうなので、Slackに通知が2つ飛んできてしまう とはいえ成功通知が2つ来てればいいだけ (スッタタタッ! スッタタタッ!ってなってちょっとうざい)

Slide 30

Slide 30 text

せっかくなら 通知だけじゃ便利とは言えないよね! Slack Interactive Message [1] とか使って botからバージョンの切り替えとかやりたいよね! というわけでApp Engine Admin APIを叩こう! [1] Slack Interactive Message の例

Slide 31

Slide 31 text

と思いきや Go向けのクライアントライブラリが無い・・・[1] 自動生成されたライブラリ(やたら項目が多くてダルい)とか REST APIは提供されているので叩け無いことはないケド・・・ [1] https://cloud.google.com/appengine/docs/admin-api/client-libraries

Slide 32

Slide 32 text

Googleさん、お願いします^^

Slide 33

Slide 33 text

まとめ ほとんど手間をかけずにCI/CDを実現できた! デプロイの結果を通知してくれて便利になった! GAEのバージョン切り替えも(だるそうだけど)GCFでいけそう いずれ実装してどこかで話ができればと思います Slackbotの設定は情報が錯綜しており一番つらかったかも Goのお話ほとんどなくてごめんなさい Goのお話ほとんどなくて本当にごめんなさい...m(_ _)m

Slide 34

Slide 34 text

現在クラウドエースでは 絶賛社員募集中です! GCPやGoでの開発・運用に 興味があれば @qushot まで!

Slide 35

Slide 35 text

ご清聴ありがとうございました!