目的
FluxCD には、Manifest 中の Image フィールドを自動的に更新してくれる機能があります。
とても便利な機能なのですが、公式ドキュメントの通りに ImageUpdateAutomation
を設定すると、main
ブランチに直接コミットされていきます。
そうではなくて、Renovate のように更新ごとに別のブランチを作成し、Pull Request を作成する挙動にしたい!というのが今回の目的です。
また、自動的に Test を実行し、テストに成功したら Merge するという挙動を実現する際に、思ったよりも手間がかかったので、その手順も記録しておきます。
ImageUpdateAutomation のドキュメント通りの設定
あまり詳しくは説明しないので、興味のある方は公式ドキュメントや、id:kakku22 さんの 「Flux v2 で Image Ops を実現する「自動イメージ更新機能」を試した - kakakakakku blog 」などを参照してください。
今回は、アプリごとに以下のような Manifest を適用しました。
apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageUpdateAutomation metadata: name: hedgedoc spec: git: checkout: ref: branch: main commit: author: email: fluxcdbot@users.noreply.github.com name: fluxcdbot messageTemplate: "{{range .Updated.Images}}{{println .}}{{end}}" push: branch: main interval: 1m0s sourceRef: kind: GitRepository name: flux-system namespace: flux-system update: path: ./k8s/apps/hedgedoc strategy: Setters --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImageRepository metadata: name: hedgedoc spec: image: quay.io/hedgedoc/hedgedoc interval: 2m0s --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImagePolicy metadata: name: hedgedoc spec: imageRepositoryRef: name: hedgedoc policy: semver: range: "^1.x.x"
ImageUpdateAutomation
には、更新方法についての設定、つまり参照する GitRepository や、ブランチ、コミットの Author、更新を監視するパスなどの設定などを記述します。
ImageRepository
では image が公開されている repository や取得頻度を設定します。
最後にImagePolicy
では、どのような条件で更新を行うかを設定します。
そして、Deployment などの image の項目に
image: quay.io/hedgedoc/hedgedoc:1.9.9 # {"$imagepolicy": "default:hedgedoc"}
のようにコメントすることで Image の更新が自動的に Push されるようになります。
push 先を別ブランチにする
このままでは、main
ブランチに直接コミットされてしまうので、アプリケーション事に別のブランチにコミットされるようにします。
ImageUpdateAutomation
のpush
フィールドを以下のように変更します。
push: branch: fluxcd/hedgedoc
こうすると、main から pull し、タグを更新後、fluxcd/hedgedoc
ブランチにコミットされるという挙動になります。
Pull Request を作成する
FluxCD 単体では、自動的に Pull Request を作成する機能は存在しないようでした。そこで、GitHub Actions を利用して、自動的に Pull Request を作成するようにします。
以下のような GitHub Actions を作成しました。
name: flux-auto-PR on: workflow_dispatch: push: branches: - "fluxcd/*" jobs: create-pull-request: name: Open PR to main runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 name: checkout - name: create pull-request run: | gh pr create --body ":crown: *An automated PR*" --base main --title "Update image tag" env: GITHUB_TOKEN: ${{ github.token }}
push
イベントをトリガーに、fluxcd/
から始まるブランチに変更があった場合に、自動的に Pull Request を作成します。GitHub CLI を利用しているので、オプションを変更することで、Reviewer の設定や、Label の設定なども行うことができます。
これで、FluxCD によって作られたブランチに対して、自動的に Pull Request が作成されるようになります。
Auto Merge する
テストが通ったら自動的に Merge するようにしたいですよね。Renovate などでは簡単に実現できますが、Actions 経由だと少し手間がかかります。
まず、Actions の create pull-request ステップに automerge の設定を追加します。
run: | gh pr create --body ":crown: *An automated PR*" --base main --title "Update image tag" gh pr merge --auto --squash gh pr merge --merge --auto
リポジトリの設定でAllow auto-merge
が有効化されており、Branch protection rules でRequire status checks to pass before merging
が適切に設定されていれば、Status Check が通った後に自動的に Merge されるようになります。
しかし、この設定では、Pull Request の作成までは動くのですが、Status Check のための Actions がいつまでたっても実行されないという問題が発生しました。
原因を調べてみると、どうやら Actions で用いられる${{secrets.GITHUB_TOKEN}}
の権限では GitHub Actions 内から別の Action の Workflow をトリガーすることができないようです。*1
ということで、記事にある通り、GitHub App を作り、その App に Pull Request を作らせることで、Test の Workflow をトリガーすることにしました。
https://github.com/settings/apps/newに飛び、新しい App を作成します。名前とHomepage URL
は適当に、Webhook のActive
を無効化し、Permissions
は、Repository permissions
内のContents
とPull requests
をRead & write
に設定します。
作成した App に対して、Install App
をクリックし、インストールします。その後、App 設定内のApp ID
とPrivate keys
をメモしておきます。
次に、リポジトリの設定に戻り、Secrets
にAPP_ID
とPRIVATE_KEY
を追加します。
最後に Workflow を以下のように書き換えます。
name: flux-auto-PR on: workflow_dispatch: push: branches: - "fluxcd/*" jobs: create-pull-request: name: Open PR to main runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@v1 id: generate_token with: app-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.PRIVATE_KEY }} - name: Set env run: | echo "GH_TOKEN=${{ steps.generate_token.outputs.token }}" >> $GITHUB_ENV - uses: actions/checkout@v4 name: checkout - name: create pull-request run: | gh pr create --body ":crown: *An automated PR*" --base main --title "Update image tag" gh pr merge --merge --auto
create-github-app-token
アクションを利用して、GitHub App に対してトークンを発行し、$GH_TOKEN に格納することで、GitHub CLI から新しい Token が自動的に利用されます。
これでようやく、Pull Request が作成され、Test が実行され、Auto Merge されるようになりました!
リポジトリの設定でAutomatically delete head branches
を有効化しておくとmerge後にブランチを消してくれるので便利です。
まとめ
Actions で作成された Pull Request にそのような制約があったことは知りませんでした。
そもそも Actions で頑張るのは面倒すぎるので、FluxCD 側で早く実装してほしいですね~