GitHub Actions

GitHub ActionsでGCEへのデプロイを楽にしてみた

はじめに


今回はgithub actionsを導入することによって、開発プロセスの短縮に成功したので、その経験を共有しさせていただきます。

このワークフローができたことによって、何がどう変わったかまとめました↓

AS IS


  1. ローカル環境でブランチ切って各自で開発
  2. gitにpush
  3. プルリク・レビュー
  4. masterブランチにマージ
  5. GCEにSSHで接続
  6. ユーザーの変更
  7. gitが入っているディレクトリに移動&git pull

TO BE


  1. ローカル環境でブランチ切って各自で開発
  2. gitにpush
  3. プルリク・レビュー
  4. masterブランチにマージ
  5. あとはgithub actionsがやってくれる!

一言でいうと、私たち開発者が行う作業がgithub内で完結できるようになったということです。

開発の動機はシンプル↓

  1. 毎回毎回デプロイのためにVMにSSHで接続するのがめんどくさかった
  2. マージして満足し、VM側のコードを更新し忘れたりすることが過去にあった

実際にワークフローを作っていこう


1. 下準備

  1. サービスアカウントとキーの準備
    1. SSH接続に必要な権限を持ったサービスアカウントとキーを作成し、鍵情報を取得しておきます
      1. 今回必要だった権限を以下にまとめてます
権限役割
compute.instances.getインスタンスの詳細情報を取得
compute.instances.useインスタンスに対して操作を実行
compute.instances.osLoginOS ログインを使用してインスタンスに SSH アクセス
iam.serviceAccounts.actAs設定されたサービスアカウントとして行動
iam.serviceAccounts.getサービスアカウントの詳細情報を取得
  1. githubのsecrets変数に秘密情報を登録
    1. 今回登録したのは以下2つです
      1. サービスアカウントの鍵情報
      2. slackのwebhook URL
        1. webhookの取得について

2. github actions作成

実装内容は実にシンプルです。

  1. 開発ブランチをmasterブランチにマージすることをトリガーにワークフローを起動する
  2. サービスアカウントでGCE(VMインスタンス)にSSH接続
  3. 接続できたらユーザーを変更し、git pullを実行
  4. git pullコマンドの実行結果を確認するため、コマンド実行時のログをslackに通知

まずはスクリプトの全体はこんな感じです↓

name: Deploy to GCP VM

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Google Cloud SDK
        uses: google-github-actions/setup-gcloud@v0.3.0
        with:
          project_id: test-project
          service_account_key: ${{ secrets.GCP_SA_KEY }}
          export_default_credentials: true

      - name: SSH and Pull Repository in GCP VM
        id: git_pull
        run: |
        echo "::set-output name=git_pull_output::$(
          gcloud compute ssh user@example-instance \
            --zone asia-northeast1-b \
            --quiet \
            --command='
              cd path/to/repository && 
              git pull
            '
        )"

      - name: Notify Slack
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: git_pull_output
          text: ${{ steps.git_pull.outputs.git_pull_output }}
          webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
        if: always()  # ジョブの成功失敗に関わらず Slack通知

次に、各ステップが何をしているのかを解説いたします。

1. ワークフロー命名とトリガー定義

name: Deploy to GCP VM

on:
  push:
    branches:
      - master
  • name: ワークフロー名を設定
  • on: このワークフローが実行される条件の定義を行う
    • master ブランチにプッシュ(つまり開発ブランチのマージ)があった際にワークフローが実行されるように設定

2. jobs: ジョブを定義

jobs:
  deploy:
    runs-on: ubuntu-latest
  • deploy: ジョブ名定義
  • runs-on: 実行環境の定義
    • ubuntu-latest:最新のUbuntuを使用することを定義

3. ステップの定義

3.1 コードのチェックアウト

steps:
  - name: Checkout code
    uses: actions/checkout@v2
  • steps: ジョブ内で実行される一連のステップを定義
  • name: ステップの名前定義
  • uses: 使用するアクションを指定
    • GitHubが提供するactions/checkout@v2アクションを使用してリポジトリのコードをチェックアウト

3.2 Google Cloud SDK のセットアップ

  - name: Setup Google Cloud SDK
    uses: google-github-actions/setup-gcloud@v0.3.0
    with:
      project_id: test-project
      service_account_key: ${{ secrets.GCP_SA_KEY }}
      export_default_credentials: true
  • uses: google-github-actions/setup-gcloud@v0.3.0の使用を定義
  • with: setup-gcloud アクションの設定を行う
    • project_id: GCPのプロジェクトID→プロジェクトIDとは
    • service_account_key: サービスアカウントキーをgithubのシークレットから取得
    • export_default_credentials: デフォルトの認証情報としてサービスアカウントキーをエクスポート

3.3 GCP VMへSSH接続し、リポジトリのプルを行う

- name: SSH and Pull Repository in GCP VM
  id: git_pull
  run: |
  echo "::set-output name=git_pull_output::$(
    gcloud compute ssh user@example-instance \
      --zone asia-northeast1-b \
      --quiet \
      --command='
        cd path/to/repository && 
        git pull
      '
  )"
  • run: 実行するコマンドを記載gcloud compute SSHを使用して特定のVMに接続し、git pull コマンドを実行させる
  • –quiet:コマンド実行時に対話型プロンプト(yes/noとか聞かれるやつ)を抑制するために使用

4.スラックへの通知

- name: Notify Slack
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    fields: git_pull_output
    text: ${{ steps.git-pull.outputs.git_pull_output }}
    webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
  if: always()  # ジョブの成功失敗に関わらず Slack通知
  • uses: 8398a7/action-slack@v3 は、GitHub Actions で Slack への通知を送るためのアクション
    • パラメータの設定
      • status: ${{ job.status }} はジョブの最終ステータス(成功、失敗、キャンセルなど)を表す。この値を使って、通知メッセージにジョブの成否を含めている
      • fields: 前のステップで git pull の実行結果を出力した変数
      • text: ${{ steps.git-pull.outputs.git_pull_output }}
        • slackに通知するテキストの設定
          • git pull の出力されたログを、通知の際のテキストとして設定
      • webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
        • GitHub Secrets に保存された Slack の Webhook URL を参照
  • if: always(): ジョブの成功や失敗に関わらず、メッセージを Slack に通知する

まとめ・所感


無事、VMインスタンスへ最新のコードのバージョンを反映するワークフローが完成しました。

いかがだったでしょうか。

slackへ通知されることで、「本当にプルされているのかな。。」といった不安を感じることがないのは、個人的に工夫できた点だと思います。

今回は1〜2時間程度で作成できる簡単なものでしたが、実際に運用をしている中で、以前と比較して開発ストレスが大きく減りました。

今後も業務効率化を目指し、いろんなgithub actionsを作成していきたいと思います。

ピックアップ記事

  1. 最速で理解したい人のためのIT用語集

関連記事

  1. Adobe Analytics

    【実験してみた】CNAMEを使わずにAdobeAnalyticsを1stパーティクッキーで計測する

    こんにちは、エクスチュアの権泳東(權泳東/コン・ヨンドン)です。…

  2. Google Cloud Platform

    【GCP】Cloud Workflowsでデータパイプラインの構築を試してみた①概要編

    こんにちは、エクスチュアの黒岩と申します。エクスチュアブログ…

  3. Google Analytics

    Cloud FunctionsとOpenWeather APIを使ってGoogle Analytic…

    こんにちは、エクスチュアの権泳東(權泳東/コン・ヨンドン)です。…

  4. Adobe Analytics

    Adobe AnalyticsからDWHレポートをGoogle Cloud Storageにアップロ…

    こんにちは、エクスチュアの權泳東(権泳東/コン・ヨンドン)です。…

  5. Google Cloud Platform

    Google Compute EngineのUbuntu VMにスワップ領域を作成する

    こんにちは、エクスチュアの權泳東(権泳東/コン・ヨンドン)です。…

  6. Google BigQuery

    BigQueryのユーザー定義関数(UDF)をTableauで使う

    こんにちは、エクスチュアの渡部です。今回はTableauでstan…

最近の記事

  1. Snowflakeや最新データ基盤が広義のマーケティングにも…
  2. 回帰分析はかく語りき Part3 ロジスティック回帰
  3. GCSへのSnowflake Open Catalogによる…
  4. VPC Service Controlsで「NO_MATCH…
  5. モダンデータスタックなワークフローオーケストレーションツール…
  1. セッションリプレイ

    【Tips】セッションリプレイについて
  2. IT用語集

    アドイン(Add In)・アドオン(Add On)って何?
  3. Databricks

    Databricksを始める前に覚えておきたいScalaプログラミングの基本
  4. Snowflake

    第14回関西DB勉強会-Snowflake Summit参加報告-
  5. IT用語集

    Macのプロキシ設定を"簡単に"解説してみた
PAGE TOP