はじめに
最近はターミナルに住んで GitHub Copilot CLI とお話しするだけの日々を過ごしていますが、GitHub Copilot Cloud Agent (旧 GitHub Copilot Coding Agent) も便利ですよね。
正式名が地味に長いので Cloud Agent と呼びますが、自分の中で Cloud Agent には「Terraform を知らなくてもいい人たちが Terraform 経由でプラットフォームを扱えるようになる」ことを期待しています。
Cloud Agent に「Terraform のコード書いて」と依頼すればいい感じに Terraform のコードを書いてくれるし、カスタムインストラクションやスキルを用意しておけば更に精度の高いコードを書いてくれます。 これは GitHub Copilot に限った話じゃないですね。
Cloud Agent に Terraform コードを書かせるだけならまっさらな環境でも綺麗に書いてくれますが、hook を使って「 .tf ファイルを修正したら terraform fmt を実行する」みたいなことをやろうとすると、Cloud Agent の実行環境に terraform コマンドが必要になります。
今回は Cloud Agent の実行環境を整える方法の話です。
Cloud Agent 実行環境のカスタマイズ
Cloud Agent はリポジトリに .github/workflows/copilot-setup-steps.yml というワークフローファイルを置くことで実行環境をカスタマイズできます。
terraform を例にすると、このワークフローファイルに terraform コマンドをインストールするステップを追加すればいいんですが、どのバージョンをインストールするか、という管理の手間が出てきます。
tenv とかの terraform 用管理ツールもあるので terraform を例に出したのが良くなかったなと思いつつ、Cloud Agent の実行環境にツールをインストールする方法はいくつかあります。
- aqua
- mise
- Dev Containers
今回は個人的にも使っている aqua を用いて Cloud Agent の実行環境を準備する方法を確認しました。
組織/チームでの Cloud Agent 実行環境の管理
冒頭でも述べたように、Cloud Agent は .github/workflows/copilot-setup-steps.yml というワークフローファイルで実行環境をカスタマイズできます。
このワークフローファイルとあわせて aqua の設定ファイル aqua.yaml を用意して、ワークフローで「1. aqua のインストール → 2. aqua 経由のツールインストール」とすることで Cloud Agent の実行環境に aqua で指定したツールをインストールできます。
ただ、この方法だと Cloud Agent を動かすリポジトリごとに aqua の設定ファイルを用意する必要があります。 Terraform を使っているリポジトリが複数あって、リポジトリ共通で同じバージョンを使いたい場合には設定ファイルの個別管理は面倒です。
aqua では AQUA_GLOBAL_CONFIG という環境変数を使うことで複数の設定ファイルを参照できます。
用途に応じた設定ファイルを GitHub リポジトリに作成して組織やチームで共有する方法が公式ドキュメントで紹介されています。
Cloud Agent も組織の一員として、このリポジトリで共有された aqua 設定ファイルを参照して実行環境を用意してみましょう。
aqua 設定ファイルの共有リポジトリ
例えば、GitHub に org/aqua-config というリポジトリを作って、all.yaml と sre.yaml という設定ファイルを用意します。
all.yaml には全員が使う共通のツール、sre.yaml には SRE チームが使うツールを作ります。
今回は sre.yaml に terraform を定義しています。
# org/aqua-config/sre.yaml
registries:
- type: standard
ref: v4.492.0
packages:
- name: hashicorp/[email protected]
aqua の設定ファイルを共有するリポジトリに必要なものは以上です。
GitHub App
呼び出す側のリポジトリには .github/workflows/copilot-setup-steps.yml の他に org/aqua-config リポジトリを参照するための認証を設定します。
今回は GitHub App を作って org/aqua-config リポジトリの Content read 権限を付与しています。
作成した GitHub App の ID と秘密鍵を呼び出す側のリポジトリに登録します。
ここで注意しないといけなくて copilot という Environment に登録する必要があります。
今回は AQUA_CONFIG_APP_ID と AQUA_CONFIG_APP_PRIVATE_KEY という名前で変数とシークレットに登録しました。
ワークフロー
GitHub App の設定後、ワークフローファイルで GitHub App を使って org/aqua-config リポジトリにアクセスするステップを追加します。 今回作ったワークフローは次のような感じです。
# org/repo/.github/workflows/copilot-setup-steps.yml
name: "Copilot Setup Steps"
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
copilot-setup-steps:
runs-on: ubuntu-latest
environment: copilot
permissions:
contents: read
steps:
# 1. Generate GitHub App token to access private Org config repository
- uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
id: app-token
with:
app-id: ${{ vars.AQUA_CONFIG_APP_ID }}
private-key: ${{ secrets.AQUA_CONFIG_APP_PRIVATE_KEY }}
repositories: aqua-config
# 2. Checkout Org common aqua config repository within workspace
# actions/checkout enforces path to be under $GITHUB_WORKSPACE
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: org/aqua-config
token: ${{ steps.app-token.outputs.token }}
path: .aqua-config
persist-credentials: false
# 3. Cache aqua packages and registries
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
with:
path: ~/.local/share/aquaproj-aqua
key: v2-aqua-installer-${{runner.os}}-${{runner.arch}}-${{hashFiles('.aqua-config/*.yaml')}}
restore-keys: |
v2-aqua-installer-${{runner.os}}-${{runner.arch}}-
# 4. Move aqua config outside workspace and persist AQUA_GLOBAL_CONFIG for Copilot agent
- run: |
mv .aqua-config "$HOME/.aqua-config"
echo "AQUA_GLOBAL_CONFIG=$HOME/.aqua-config/all.yaml:$HOME/.aqua-config/sre.yaml" >> "$GITHUB_ENV"
# 5. Install aqua and all tools using Org config (all.yaml + sre.yaml)
- uses: aquaproj/aqua-installer@11dd79b4e498d471a9385aa9fb7f62bb5f52a73c # v4.0.4
with:
aqua_version: v2.57.1
aqua_opts: "-a"
ジョブ名は copilot-setup-steps である必要があるのと、Cloud Agent に変数とシークレットを渡すため environment: copilot を設定することに注意してください。
各ステップでやっていることは次の通りです。
1. GitHub App トークンの生成
作成した GitHub App のトークンを生成します。 このトークンを使って次のステップで org/aqua-config リポジトリにアクセスします。
2. 組織共通の aqua 設定ファイルのチェックアウト
path に指定した場所に org/aqua-config リポジトリをチェックアウトします。
persist-credentials: false を指定して、チェックアウト時に使用するトークンが他のステップで使われないようにします。
指定しなくても動きますが、セキュリティ的に指定するのが推奨です。
3. aqua のキャッシュ
aqua でインストールするパッケージやレジストリをキャッシュして、ワークフローの実行時間を短縮します。 設定は aqua のドキュメント を参考にしています。
4. aqua 設定ファイルの移動と環境変数の設定
ここで少しクセのある設定をしています。
チェックアウトした org/aqua-config リポジトリをワークスペース外に移動し、環境変数 AQUA_GLOBAL_CONFIG を設定しています。
ワークフロー内でカレントリポジトリをチェックアウトしていない状態だと、カスタム環境の構築後に Cloud Agent が自動でカレントリポジトリをチェックアウトするようになっています。 このとき、Workspace ディレクトリにファイルやディレクトリが存在しているとエラーになります。 ステップ 2 でチェックアウトした org/aqua-config リポジトリが該当します。
また、チェックアウトしたリポジトリを削除してしまうと aqua が参照する設定ファイルもなくなってしまうので、削除せずに残しておく必要があります。
このエラーを回避するために、ステップ 2 でチェックアウトした org/aqua-config リポジトリをワークスペース外に移動して、環境変数 AQUA_GLOBAL_CONFIG を使って参照できるようにしています。
ここはより良い方法があるかもです。
5. aqua インストール
最後に aquaproj/aqua-installer アクションを使って aqua をインストール、そして aqua 経由でツールをインストールします。
with.aqua_opts に -a を指定することで、環境変数 AQUA_GLOBAL_CONFIG で指定した設定ファイルを参照してツールをインストールします。
実行環境の確認
この状態で Copilot に Issue をアサインなどすると、aqua で指定したバージョンのツールがインストールされた環境で Cloud Agent が実行されます。 うまく terraform が指定のバージョンでインストールされているようですね(画像では分かりづらいですが……)。
まとめ
GitHub Copilot Cloud Agent のカスタム実行環境を aqua を使って組織的に管理する方法を紹介しました。
- Cloud Agent は
.github/workflows/copilot-setup-steps.ymlで実行環境をカスタマイズ可能 - aqua の設定ファイルを組織/チーム、そして Cloud Agent に共有できる
実際に使っているわけではないので運用面での課題を洗い出せてないですが、こんな方法もあるんだなということで。