AQ Tech Blog

GitHub Actionsを使ったCI/CD | AQ Tech Blog

作成者: tsuyoshi.watanabe|2022年10月26日

サムネ出典URL:https://github.com/logos

はじめに

クラウドインテグレーション部の渡邊です。

本記事は、私が携わった案件で利用したGitHub Actionsの概要、良い点、注意点について主に記述しています。

CI/CDの初心者でも理解できる内容にしていますのでぜひ最後までご覧ください。

なお、本記事はGitHubのプライベートリポジトリを想定して記述した内容となっております。

用語の説明

CI/CDとは

CI/CDとは、開発 / 運用までのビルドやデプロイを自動化するための手法のことです。

CI:Continuous Integration(継続的インテグレーション)の略

継続的インテグレーションはビルドやテストを頻繁に行うことによる開発の効率化や省力化を図る手法を指す。

CD:Continuous Delivery(継続的デリバリー)の略

継続的デリバリーは開発で修正したプログラムを自動的に環境に展開する仕組みを指す。

CI/CDを導入したインフラ環境のデプロイとして下記の例をあげます。

  1. バージョン管理ツールで管理されたローカルリポジトリのコードを更新
  2. ローカルリポジトリの変更内容をリモートリポジトリへ反映
  3. リモートリポジトリへの反映をトリガーにCI/CDツールで処理を実行
    e.g. マシンイメージのビルド、インスタンスやコンテナへのデプロイ

 

 

GitHub Actionsとは

GitHub ActionsはGitHubが提供するCI/CDのためのワークフローエンジンを指します。

ワークフローエンジンはビルド、テスト、デプロイといったワークフローの定義を実行する機能です。

GitHub Actionsのコンポーネントを以下の表にまとめます。

コンポーネント

説明

ワークフロー

1つ以上のジョブを実行する自動化されたプロセス

イベント

ワークフローを実行するトリガーとなるリポジトリ内の特定のアクティビティ(例:ブランチへのpush)

ジョブ

同じランナーで実行されるワークフロー内のステップのセット

アクション

ワークフローのタスク単位

ランナー

トリガーされたときにワークフローを実行するサーバー

参考:Understanding GitHub Actions

 

ワークフローの内容に関して、以下の画像が定義ファイルの抜粋となっており、yaml形式でワークフローを定義しています。

定義ファイルの各セクションの詳細は次回執筆予定です。

 

【GitHub Actionsのワークフロー定義ファイル例】

参考:GitHub Actions入門 ── ワークフローの基本的な構造からOIDCによる外部サービス認証まで

 

Terraformとは

TerraformはHashiCorp社が提供しているOSSで、インフラの構成をソースコードとして管理できるツールです。

例えば、AWSリソースの反映をGitHub Actionsが自動化する際にTerraformを活用できます。

TerraformとGitHub Actions、GitHubを組み合わせた構成の場合は、以下のような流れでAWSヘリソースを反映させていきます。

 

・流れ 

  1.  GitHubリポジトリにTerraformのコードを反映
  2. 1.をトリガーにしてGitHub Actionsがジョブ(AWSへのリソースの反映)実行
  3. Terraformによって実環境にAWSリソース作成

GitHub Actionsの良い点

①低コスト

GitHubリポジトリにはパブリックリポジトリとプライベートリポジトリがあります。

 パブリックリポジトリの場合はGitHub Actionsの利用が無料であり、 プライベートリポジトリの場合だと、無料枠+ 従量課金という課金形態になっております。

プライベートリポジトリの無料枠に関して、Proアカウントでは毎月50時間までは無料です。

ただ、タイムアウトの設定には注意が必要です。(詳しくは、「利用する上での注意点」の章で後述します。)

参考:シンプルな従量課金

 

②設定が容易

CI/CDサービスを利用するために実行環境等のリソースを用意する場合もありますが、Github Actionsの場合は定義ファイルを用意するだけで実行環境含めCI/CDを導入できます。

さらに、プロジェクトではステージング環境、本番環境など環境に応じてブランチを分けることが主流ですが、1つの定義ファイルでブランチ毎に応じた処理を指定可能です。

on:
  # productionブランチへのプッシュをトリガーにする
  push:
    branches:
      - production
  # stageブランチへのプルリクエストをトリガーにする
  pull_request:
    branches:
      - stage

GitHub Actionsを利用する上での注意点

①同時実行トラブル

Terraformなどのリソース構成管理ツールではステートファイルでリソースの現在の状態を管理します。

Terraformの実行時にはステートファイルを参照して環境へ変更を加えますが、Terraformの同時実行等でステートファイルに不整合が発生する場合があります。

GitHub Actionsと組み合わせた場合にアクションが同時実行されると上述の不整合が発生し、アクション自体がエラーとなる場合があります。

 

同時実行が起こる場合の一例

  1.  GitHub Actionsが設定されている対象リポジトリにコード反映
  2.  GitHub Actionsが呼び出され、アクション実行
  3. 2.のアクション完了前に同じブランチに対して別の修正を反映
  4.  GitHub Actionsが同時に実行される
  5. 環境差異が発生し、Terraformのステートファイルで不整合となり後続のアクションが失敗
    1. ②のアクションでS3バケット作成
    2. ④のアクションでは、S3バケット作成前のステートファイルを利用
    3. 既にS3バケットが存在しているのにS3を作成しようとしエラーとなる

 

 

上記のようなGitHub Actionsが同時実行されないための対処法として`concurrency`の導入が有効です。concurrencyは、GitHub Actionsの前の処理が完了するまで次の処理を待機するといった挙動になります。

`concurrency`はワークフローおよびジョブ単位で制御することができます。

また、以下のコード例では`$`にブランチが参照され、stageブランチで実行した場合は 「deploy-stage」というグループ名になります。グループ名を分けることにより、ブランチ単位で同時実行の制御もできます。

 name: 'Terraform'

on:
  push:
    branches:
      - "production"
      - "stage"

# 同時実行を抑制
concurrency: deploy-$  

jobs:
  apply_tf:
    name: Terraform apply
    runs-on: ubuntu-latest
~~~以下、略~~~

参考:Using concurrency

 

【GitHub Actionsのワークフロー画面】



②タイムアウトエラー

GitHub Actionsは実行時間に応じて課金される従量課金制です。デフォルトのタイムアウトは6時間で、処理が途中で止まりタイムアウトエラーが発生してしまうと、まるまる6時間分の実行料金がかかってしまうため注意する必要があります。

そのため、定義ファイル内にて`timeout-minutes`の設定を記述し、タイムアウト時間を短くすることをお勧めします。

~~~定義ファイル抜粋~~~
jobs:
  apply_tf:
    name: Terraform apply
    runs-on: ubuntu-latest
    # job全体に対してタイムアウトを30分で設定
    timeout-minutes: 30 

    steps:
    - name: Terraform Apply
      if : $false
      run: Terraform apply -auto-approve
      # step個別に設定することも可能
      timeout-minutes: 20
      working-directory: Terraform/environments/$

参考:[GitHub]Actions Workflowへのtimeout指定のススメ

まとめ

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

注意点を意識しながらぜひGitHub Actionsのメリットを享受していただきたいと思います。

次回の記事ではGitHub Actionsを利用した構築をハンズオン形式で紹介予定です。そちらもぜひご覧ください!

参考リンク

GitHub Actionsの構造

GitHub Actions料金