LoginSignup
24
13

More than 1 year has passed since last update.

定期スクリプト実行環境としてのGitLab CIのススメ

Last updated at Posted at 2021-12-02

ラクスAdvent Calendar 2021 の2日目は、スプリットキーボードならぬデュアルキーボード歴2ヶ月の @oohira が、左手に Magic Keyboard、右手に REALFORCE というごった煮環境からお送りします。

昨日は「初日取ったった!」してくれた @Y-Kanoh さんの「GASでカユいところに手が届いたTips3選」でした。勢い、大事ですね。

はじめに

これまで定期実行したいちょっとしたスクリプトは、個人PCやプロジェクト共用サーバー、Jenkins などを使って実行していましたが、ここ数年で GitLab CI を使って実行する方法に完全に落ち着きました。この記事では、社内のメンバーも読者に想定しつつ、GitLab CI のよさと簡単な始め方を紹介したいと思います。

背景と前提

GitLab CI(や GitHub Actions)が登場する前の世界では、Linux の cron や、Windows のタスクスケジューラー、Jenkins などを使ってスクリプトを定期実行することが多かったのではないかと思います。いずれの方法でも目的は果たせますが、次のような課題もありました。

  • 実行マシンを用意するのが面倒
    • 個人PCなのか共用サーバーなのかは別として、スクリプトを実行するためのマシンを用意し、デプロイする仕組みを考えなければならない
  • 実行マシンのミドルウェアを管理するのが面倒
    • スクリプトで使用するプログラミング言語を実行できる環境を整備したり、実行マシン自体のOSやミドルウェアを定期的にアップデートしなければならない
  • 引き継ぎするのが面倒
    • 別の人にスクリプトを引き継いでメンテしてもらう必要が出たときに、実行マシンの構成や手順などを文書化して伝えなければならない

GitLab CI を使うと、これらの問題を解決したスクリプト実行環境を簡単に構築することができます。GitHub Actions でも同じことが実現できると思いますが、弊社ではソースコード管理システムとして GitLab を採用しているため、ここでは GitLab CI を前提として話を進めます。執筆時点で確認したバージョンは次の通りです。

  • GitLab v14.0.5
  • GitLab v14.6.0-pre

はじめの一歩

まずは、GitLab CI でスクリプトが実行できるミニマムの環境を作ります。

  1. GitLab プロジェクトを新規作成する
  2. GitLab Runner を登録する(GitLab.comの場合は不要)
    • 自社でサーバーを立てている&Shared runner が有効になっていない場合は、 Settings > CI/CD > Runners から、GitLab CI を実行するためのサーバーを登録する必要があります。
      • 弊社メンバーの皆さまは、↓にある個別 Runner を使ってもらってOKですよ。 これ、一部の人にしか見えていないっぽいことが発覚してしまいました 1 image.png
  3. .gitlab-ci.yml を作成する

    • プロジェクトルートにビルド設定を記載したファイルを作成します。リポジトリをチェックアウトしなくても、GitLab の Web 画面から作成・編集するとお手軽です
    .gitlab-ci.yml
    image: alpine
    
    awesome-job:
      stage: build
      script:
        - echo "Hello, World!"
    
  4. .gitlab-ci.yml をコミット&push する

    • 修正をコミットすると、自動的に GitLab CI によるビルドが始まります。ビルドログなどを確認すると、awesome-job という名前のジョブが実行されて成功したことや、Alpine Linux をベースイメージとするコンテナ内で script に指定したコマンドが実行されたことなどが分かります image.png image.png

簡単ですね

POINT: 実行環境の準備が楽
GitLab CI は、GitLab に統合されているため、実行マシンを別に用意2したり、スクリプトを実行サーバーにデプロイしたりする手間がありません。.gitlab-ci.yml に実行したいスクリプトを書くだけで、あとは GitLab CI がいい感じに実行してくれます。

ミドルウェアを変更する

ここで、もう少し本格的なスクリプトを作りたくなったとしましょう。シェルスクリプトでは心もとないので、Node.js に切り替えるとします(Go でも Ruby でも好きな言語をどうぞ)。

  1. .gitlab-ci.yml を変更する

    • Node.js がセットアップ済みの軽量イメージとして node:14-alpine を使ってみます 3
    .gitlab-ci.yml
    image: node:14-alpine
    
    awesome-job:
      stage: build
      script:
        - npm xmas
    
  2. 実行ログを確認する :christmas_tree:
    image.png

POINT: ミドルウェアの管理や更新が楽
GitLab CI は、コンテナベースの実行環境なので、スクリプトを実行するOSやプログラミング言語を変更しても、新たにミドルウェアをセットアップする手間がありません。.gitlab-ci.yml に必要なバージョンのミドルウェアを指定するだけで準備が完了します。

定期実行する

このままでは(CIの本来の期待通りではありますが)コミットするたびに実行されてしまうので、スケジュール登録して定期実行できるようにします。

  1. スケジュール実行のときだけビルドするよう .gitlab-ci.yml を変更する

    .gitlab-ci.yml
    image: alpine
    
    awesome-job:
      stage: build
      rules:
        - if: $CI_PIPELINE_SOURCE == "schedule"
      script:
        - echo "Hello, World!"
    
  2. スケジュール設定を登録する

  3. スケジュール設定した日時に自動実行されるのを待つ

  4. 手動で即時実行する

    • 動作確認などで次回スケジュール実行まで待てない場合は、Play ボタンから手動でキックできます image.png

外部システムと連携する

スクリプトを実行する仕組みは整いましたが、このままでは GitLab CI のログでしか出力を確認することができません。多くの場合は、Slack や Mattermost のようなチャットツールに結果を投稿したり、Git にコードをコミットしたり、別のシステムとの連携が期待されます。

ここでは、Mattermost に投稿する bot を作ってみます。

  1. Webhook URL を取得する
    • Mattermost 側で Incoming Webhook を実行するためのURLを発行します
  2. .gitlab-ci.yml を修正する

    • Mattermost にメッセージを投稿するようスクリプトを変更します。curl コマンドを追加でインストールしている点や、URLをハードコーディングせずに環境変数としている点に注意してください(説明の都合上、インラインでコマンドを書いていますが、エスケープがつらいので実際は別ファイルに切り出すとよいでしょう)
    .gitlab-ci.yml
    image: alpine
    
    awesome-job:
      stage: build
      rules:
        - if: $CI_PIPELINE_SOURCE == "schedule"
      script:
        - apk add curl
        - 'curl -k -X POST -H "Content-Type: application/json"
          -d "{\"icon_emoji\": \"santa\", \"username\": \"santa_bot\", \"text\": \"Hello, Mattermost. :tada:\"}"
          "${MATTERMOST_URL}"'
    
  3. スケジュール設定に環境変数を登録する

    • CI/CD > Schedules からスケジュール設定を開き、スクリプトに渡したい環境変数の値を設定します。スクリプト中にハードコーディングしないことで、デバッグ中に接続先を変更するなど融通がききやすくなります image.png
    • なお、ここで指定する環境変数の値は、ビルドログ中にも展開されません image.png
  4. 定期実行されるのを待つ or 手動実行する

    • GitLab CI で実行されたスクリプトから Mattermost への投稿 4 が成功します :tada: image.png

好きな言語で書いたスクリプトからチャットへ投稿ができるようになったので、あとはスクリプトで何を投稿するか、アイデア次第です。

POINT: 引き継ぎが楽
スクリプトだけでなく、ミドルウェアまで含めた前提条件が .gitlab-ci.yml にコード化されるため、スクリプトの実行に何が必要かを把握しやすくなります。また、スケジュール設定や環境変数の値も含めてすべて GitLab 上に一元化されるため、引き継ぎはリポジトリを伝えれば何とかなります(多分)。

成果物を保存する

スクリプトの出力を二次利用する別の方法として、生成したファイルを GitLab に保存しておき、後から参照できるようにすることもできます。

  1. .gitlab-ci.yml を修正する

    • 外部サービスから取得したネコ画像を artifacts として保存するよう指定します
    .gitlab-ci.yml
    image: alpine
    
    awesome-job:
      stage: build
      rules:
        - if: $CI_PIPELINE_SOURCE == "schedule"
      script:
        - apk add curl
        # Powered by Cat as a service (CATAAS)
        - curl -s "https://cataas.com/cat/gif" -o cat.gif
      artifacts:
        paths:
          - cat.gif
    
  2. 実行ログの画面から確認する
    image.png
    image.png

:cat: :cat:

Tips

最後に雑多な Tips を紹介します。

  • 一時的に無効にする
    • スクリプトのデバッグ時など、一時的に定期実行を無効にしたい場合は、スケジュール設定の Active フラグで切り替えることができます
  • エラーメールはスケジュール設定のオーナーだけに届く
    • ビルドが失敗した場合の通知メールは、スケジュール設定を登録したユーザー(オーナー)だけにしか送信されません
    • 監視スクリプトなど、ビルド失敗をチームとしてウォッチする必要がある場合は、別途チャットに通知するようにしておくなり、メールを自動転送するようにしておくなり、何かしらの対処が必要です
  • 複数のスクリプトを管理する

    • 1つのリポジトリでスケジュールが異なる複数のスクリプトを管理したい場合は、スケジュール設定の環境変数をうまく組み合わせることで対応することができます
    .gitlab-ci.yml
    image: alpine
    
    awesome-job:
      stage: build
      rules:
        - if: '$CI_PIPELINE_SOURCE == "schedule" && $AWESOME_JOB_SCHEDULE == "1"'
      script:
        - echo "Awesome job"
    
    great-job:
      stage: build
      rules:
        - if: '$CI_PIPELINE_SOURCE == "schedule" && $GREAT_JOB_SCHEDULE == "1"'
      script:
        - echo "Great job"
    

さらに学ぶには

まとめ

この記事では、GitLab CI を使って定期実行スクリプトを管理・実行する方法を紹介しました。ソースコードの管理と実行環境の管理を一元化することができ、とてもオススメです。

GitLab CI、イイよ!


  1. プロジェクトロックしていない Specific runner を社内メンバーに自由に使ってもらって、 GitLab CI を手軽に試してもらおうというのがそもそも今回の記事の目的だったのに、ここにきてまさかとはこのこと。やはり管理者にお試し用の Shared runner を用意してもらうしかないか。とり急ぎ Specific runner の候補が1つも出ない場合は、Show Runner installation instructions の手順に従って… :pray:(ry 

  2. 厳密には、GitLab CI の実行に使う GitLab Runner を誰かが用意する必要があります。そのため、GitLab CI を使ったからといって完全に実行マシンの管理が不要になるわけではありませんが、GitLab Runner さえ用意すれば他の大多数の人はその恩恵を受けるだけで済みます。 

  3. npm xmas がとうとう削除されたっぽいので、意図的に少し古めの Node.js を使用しています。 

  4. 当たり前と言えば当たり前ですが、GiLab CI が実行するコンテナから Mattermost へアクセスできる必要があります。GitLab.com を使っているけど Mattermost は社内ネットワークで稼働している、と言った場合は面倒かもしれません 

24
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
13