研究開発部 Architectグループ ML PlatformチームのKAZYこと新井です。ちなみに名古屋にある中部支店に所属です。
開発リードタイムを改善するためにGitHub ActionsでKubernetesのマニフェスト生成できるようにした話をします。
前後編の2つに分けて公開しており、今回は後編として具体的な実装部分をお話します。
▼前編 buildersbox.corp-sansan.com
なお、本記事は【R&D DevOps通信】という連載記事のひとつです。
目次
- 目次
- 作成したワークフロー
- GitHub Appによるトークン取得
- Cookiecutter
- GitHub Actinsからプルリクエスト作成
- 実装
- Cookiecutterテンプレート管理に用いた理由
- おわりに
- アナウンス
作成したワークフロー
処理の流れ
- ユーザがパラメータを決めてGitHub Actionsのworkflow dispatchのトリガーを手動で引く
- プライベートリポジトリをクローンするためにGitHub Appからトークンを取得
- テンプレートが保存されているプライベートリポジトリからCookiecutterでテンプレートを取得(認証に先程のトークン使用)
- 取得したファイルをコミットしてプルリクエストを作成
GitHub Appによるトークン取得
デフォルトのトークンは組織内の他のプライベートリポジトリをクローンする権限を持っていません。
そのため権限を持ったトークンを発行する必要があります。
発行する方法は
- GitHub Appによるトークン認証
- パーソナルアクセストークンによる認証
があります。
今回はGitHub Appによるトークン認証にします。
パーソナルアクセストークンによる認証は
- 細かな有効期限コントロールができない
- 発行した人に管理が依存してしまう
という理由から使いませんでした。
PythonのプライベートパッケージをGitHubで作るときにも同様のことを書きました。
Cookiecutter
Cookiecutterとは、プロジェクトテンプレートからプロジェクトを作成してくれるPython製コマンドラインツールです。 github.com
研究開発部内で利用実績があり馴染みがあるものです。 buildersbox.corp-sansan.com
今回は主にアプリケーションごとに異なるパラメータの制御に用いています。
GitHub Actinsからプルリクエスト作成
Create Pull Requestのアクションを利用しました。 コミットメッセージやOpen/Draft、PRのメッセージなどが自由に設定できるので便利です。
実装
作成したワークフローファイルがこちらです。
name: Generate Manifest on: workflow_dispatch: inputs: service_name: description: Service name required: true use_secret: type: boolean description: Use Secret Value default: false environment: type: choice description: Environment required: true default: staging options: - development - staging - production jobs: create-manifest: name: "[${{ github.event.inputs.environment }}] Generate manifest." runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.10" - name: Install cookiecutter run: pip install cookiecutter - name: Generate github token id: generate_token uses: tibdex/github-app-token@021a2405c7f990db57f5eae5397423dcc554159c # v1.7.0 with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.APP_PRIVATE_KEY }} - name: Add template run: | cookiecutter \ https://x-access-token:${ACCESS_TOKEN}@github.com/eightcard/randd_cookiecutter.git \ --output-dir services/${{ github.event.inputs.namespace }} \ --overwrite-if-exists \ --skip-if-file-exists \ --no-input \ project_name=${{ github.event.inputs.service_name }} \ namespace=${{ github.event.inputs.namespace }} \ use_secret=${{ github.event.inputs.use_secret }} env: ACCESS_TOKEN: ${{ steps.generate_token.outputs.token }} - name: Create Draft Pull Request uses: peter-evans/create-pull-request@b4d51739f96fca8047ad065eccef63442d8e99f7 #v4.2.0 with: base: main draft: true branch-suffix: timestamp add-paths: | # 必要なファイルだけコミットする services/${{ github.event.inputs.namespace }}/${{ github.event.inputs.service_name }}/batch/base/ services/${{ github.event.inputs.namespace }}/${{ github.event.inputs.service_name }}/batch/overlays/${{ github.event.inputs.environment }}/ commit-message: "[${{ github.event.inputs.environment }}] Add manifest from template." title: "[${{ github.event.inputs.environment }}] Create ${{ github.event.inputs.service_name }} batch manifest."
cookicutterのオプションについて補足
--overwrite-if-exists
:書き込み先ディレクトリが存在する場合は上書きする
--skip-if-file-exists
: ファイルが既に存在する場合はファイル作成をしない
という2つのオプションを付けています。
その理由は環境ごとに別々でマニフェストを作成した際に共通部分のファイルを上書きしてしまわないようにするためです。
研究開発部のアプリケーション基盤ではKustomizeを使って環境差分を管理しています。 そして以下のようなディレクトリ構造を採用しています。
services/<namespace>/ └── <service name> └── <application type> ├── base/ └── overlays ├── production/ └── staging/
そのためbaseディレクトリ以下のファイルは環境共通部分になります。
Cookiecutterテンプレート管理に用いた理由
Kubernetesでのテンプレートを用いるための他の候補としてHelmのTemplateがありました。 HelmというのはKubernetes向けのパッケージマネージャーでテンプレートを用いたパッケージ作成機能があります。 helm.sh
Helmも便利*1なのですが、今回は以下の理由でCookiecutterを選びました。
- Cookiecutter研究開発部内で利用実績があること
- PythonのJija Templateでテンプレートを扱えること(HelmのTemplateはGo Template)
- マニフェストファイル自体の追加削除の制御がCookiecutterの方が簡単そうだ感じたこと*2
Cookiecutterのドキュメントにはhook機能を用いたファイル制御の例の記載があります
作成したワークフローではuse_secretというオプションでSecretリソース作成の制御をできるようにしました
おわりに
テンプレートから値を入れてプルリクエストを作成することは汎用性が高そうなので今後もどこかで使えるかもしれません。
アナウンス
求人
私の所属するML Platformチームを含む、研究開発部Architectグループでは一緒に働く仲間を募集しています。是非一緒に働きましょう。