1. はじめに
はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。
この記事では、”PaLM API for textで作るGoogle Cloudコストチェッカー“を基に開発した「CostChecker-Agent」について紹介します。「CostChecker-Agent」はGoogle Cloudのコストの増減について定期的に監視を行い、LLMがレポートを作成します。
2. CostChecker-Agentとは?
上記はCostChecker-Agentのコンセプト図です。CostChecker-Agent自体はDocker imageを利用して構築しています。Github Actionを利用する事で、Google Cloudのコストの増減について定期的に監視を行い、LLMがレポートを作成します。Github Actionを利用する事で、レポートが定期的に取得出来ます。更にローカルでの実行もサポートしています。2023年11月7日現在、CostChecker-Agentで使用するLLMに、OpenAI社のChatGPTと、Google CloudのVertex AI(PaLM2)をサポートしています。
3. CostChecker-Agentの動作
CostChecker-Agentのコードや仕組みは、”PaLM API for textで作るGoogle Cloudコストチェッカー“で説明されているので詳細を割愛します。CostChecker-Agent自体はDocker Imageで構築されています。CostChecker-Agentは、Big Queryからコスト情報を抽出して、LLMを使い、コスト増減に対するアドバイスを生成しています。また、GItHub Actionには、Docker imageを動作させる機能や、GitHub Container Registry(ghcr.io)が備わっています。これらの機能を利用する事で、ユーザは自身のリポジトリにGitHub Actionの定義ファイル(.yaml)を配置と環境変数を設定する事で利用できます。
以下はcostchecker-agentをGitHub Action上で動作させるためのyamlです。こちらから取得できます。costchecker-agentのimageの最新版を3-shakeのリポジトリから取得する他、エラーについてもissueに投稿されます。実行時にRepository secretsを設定する必要があります。また、Settings > Actions > General > Workflow permissionsのRead repository contents permissionをRead and write permissionsに設定する必要があります。
name: costchecker-agent
on:
workflow_dispatch:
schedule:
# 毎週月曜
- cron: '0 0 * * 1'
jobs:
run_and_report:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Login to GHCR
env:
GHCR_PAT: ${{ secrets.GHCR_PAT }}
run: |
if [ ! -z "$GHCR_PAT" ]; then
echo "$GHCR_PAT" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
fi
- name: Pull Docker Image
run: docker pull ghcr.io/3-shake/costchecker-agent/costchecker-agent:latest
- name: Run Docker Image
continue-on-error: true
run: |
docker run --env GCP_SA_JSON_KEY='${{ secrets.GCP_SA_JSON_KEY }}' \
--env GCP_PROJECT_NAME="${{ secrets.GCP_PROJECT_NAME }}" \
--env GCP_TABLE_NAME="${{ secrets.GCP_TABLE_NAME }}" \
--env GCP_DATASET="${{ secrets.GCP_DATASET }}" \
--env OPENAI_API_KEY="${{ secrets.OPENAI_API_KEY }}" \
--env OPENAI_ORGANIZATION_ID="${{ secrets.OPENAI_ORGANIZATION_ID }}" \
--env LANGUAGE="${{ secrets.LANGUAGE }}" \
--env LLM_MODEL="${{ secrets.LLM_MODEL }}" \
ghcr.io/3-shake/costchecker-agent/costchecker-agent:latest > output.txt 2>error.txt
- name: Create issue
run: |
REPO_OWNER=$(echo ${{ github.repository }} | cut -d'/' -f1)
REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f2)
API_URL="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/issues"
if [[ ! -s error.txt ]]; then
ISSUE_TITLE="Weekly Report for Week $(date +'%U') of $(date +'%B %Y')"
ISSUE_BODY=$(<output.txt)
else
ISSUE_TITLE="ERROR: $(sed '2!d' error.txt)"
ISSUE_BODY=$(<error.txt)
fi
ISSUE_DATA=$(jq -n \
--arg title "$ISSUE_TITLE" \
--arg body "$ISSUE_BODY" \
'{title: $title, body: $body}')
curl -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
$API_URL \
-d "$ISSUE_DATA"
- name: Check for Errors
run: |
if [[ -s error.txt ]]; then
echo "Error detected in costchecker-agent."
cat error.txt
exit 1
fi
Repository secrets
GCP_SA_JSON_KEY=<サービスアカウントのキーファイルの内容を張り付ける>
GCP_PROJECT_NAME=<YOUR ENV>
GCP_DATASET=<YOUR ENV>
GCP_TABLE_NAME=<YOUR ENV>
OPENAI_API_KEY=<YOUR ENV>
OPENAI_ORGANIZATION_ID=<YOUR ENV>
LLM_MODEL=PaLM2
LANGUAGE=Japanese
以下はローカルで実行するためのDockerコマンドです。
docker run --rm \
--name costchecker-agent \
-v $(pwd)/key.json:/root/key.json \
-e GOOGLE_APPLICATION_CREDENTIALS=/root/key.json \
-e GCP_PROJECT_NAME=<YOUR ENV> \
-e GCP_DATASET=<YOUR ENV> \
-e GCP_TABLE_NAME=<YOUR ENV> \
-e OPENAI_API_KEY=<YOUR ENV> \
-e OPENAI_ORGANIZATION_ID=<YOUR ENV> \
-e LLM_MODEL=PaLM2 \
-e LANGUAGE=Japanese \
ghcr.io/3-shake/costchecker-agent/costchecker-agent:latest > output.txt 2>&1
勿論、Docker Composeでも利用可能です。
services:
costchecker-agent:
image: ghcr.io/3-shake/costchecker-agent/costchecker-agent:latest
volumes:
# サービスアカウントのキーファイル
- ./key.json:/root/key.json
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/root/key.json
- GCP_PROJECT_NAME=<YOUR ENV>
- GCP_DATASET=<YOUR ENV>
- GCP_TABLE_NAME=<YOUR ENV>
- OPENAI_API_KEY=<YOUR ENV>
- OPENAI_ORGANIZATION_ID=<YOUR ENV>
- LLM_MODEL=PaLM2
- LANGUAGE=Japanese
4. GitHub Actionで考慮すべき事
costchecker-agentの開発中、GitHub Actionのスケジュール機能を使う上で、”最後にリポジトリに活動を行った60日後に処理が停止する”という問題がある事が分かりました。この問題を解決するため、月一で無駄なコミットを送るというYAMLを作成しました。
monthly-timestamp-update.yml 初回実行時は”GithubActionTimeStamp”という空のブランチを作成して、timestamp.txtにタイムスタンプを書き込みます。二回目以降は、タイムスタンプの書き込みのみが行われます。
name: Monthly Timestamp Update
on:
workflow_dispatch:
schedule:
- cron: '0 0 1 * *'
jobs:
check-and-update-timestamp:
runs-on: ubuntu-latest
steps:
- name: Check out the repository
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Git identity
run: |
git config --global user.name 'github-actions-bot'
git config --global user.email 'github-actions-bot@users.noreply.github.com'
- name: Check for GithubActionTimeStamp branch
run: |
if git branch --list GithubActionTimeStamp; then
echo "GithubActionTimeStamp branch already exists."
else
echo "Creating GithubActionTimeStamp branch."
git checkout --orphan GithubActionTimeStamp
git rm -rf .
touch .gitkeep
git add .gitkeep
git commit -m "Initial commit on GithubActionTimeStamp branch"
git push origin GithubActionTimeStamp
fi
- name: Update timestamp
run: |
git fetch --all
git checkout GithubActionTimeStamp || git checkout -b GithubActionTimeStamp
date +'%Y-%m-%d %H:%M:%S' > timestamp.txt
git add timestamp.txt
git commit -m "Update timestamp"
git push origin GithubActionTimeStamp
5. 実際に動作させた結果
GitHub Actionを利用すると以下のようなレポートが作成されます。
7. おまけ(CI/CD)
costchecker-agentの開発で、GitHub Container Registry(ghcr.io)を利用しました。以下は開発で使用したGitHub ActionのYAMLです。mainブランチにプロジェクトがpushされるとDockerfileを基にイメージをBuildしてPushします。
name: Build and Push Docker Image
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
push: true
tags: ghcr.io/${{ github.repository }}/costchecker-agent:latest
6. まとめ
今回の開発では、costchecker-agentの開発を通して、GitHub Actionを利用した定期実行という新しい概念を学ぶ事が出来ました。また、mainブランチにpushされたプロジェクトを、GitHub Actionを利用してGitHub Container Registry(ghcr.io)にPushするCI/CDの初歩も実践的に学ぶ事が出来ました。
7. おわりに
本記事では、”PaLM API for textで作るGoogle Cloudコストチェッカー“を基に開発した「CostChecker-Agent」について紹介しましました。また、GitHub Actionのスケジュールを長期的に使用する上での憂慮事項や、得られたナレッジについても説明しました。