この記事は約7分で読めます。
こんにちは!花粉許すまじ。サービス開発部の布施です。
本ブログはGitHubで運用しているプロジェクトでのライブラリバージョン更新の体験談です。 バージョン更新用のPRはdependabotが自動で作成する仕組みになっており、PR作成をトリガーに動作するGitHub Actionが失敗してしまっていたので、ことの顛末を書いていきます。
プロジェクトの概要
まず、今回のプロジェクトではterraformを使ってインフラを構築していました。 CI/CDにはGitHub Actionsを使用し、以下のようなフローで継続的なデプロイを行う構成です。 ざっくり図解するとこんな感じでした。
インフラにはAWS Lambdaを使っており、アプリケーションコードのデプロイもterraformを使って行っています。
そしてAWSへの認証にはIAMユーザーのクレデンシャルを使用します。クレデンシャルはGitHub上でSecretsとして登録しており、GitHub Actionsのワークフローで参照しています。 これらの設定で、通常のインフラ・アプリケーションのデプロイは問題なく実施できていました。
※なお、AWSへの認証に今回はIAMユーザーを使っていますが、堅牢なデプロイを実現するためにはIAMロールを用意してOIDCを使ってデプロイするべきです。 今回はプロジェクトの都合上IAMユーザーを使っていますが、そもそもクレデンシャルを使わない方がよいです、という旨はお断りします。
CIで失敗した話
さて、次は今回のメインテーマでもあるライブラリのバージョンアップデートPRでCIが失敗している話です。
本プロジェクトではアプリケーションで使用しているライブラリのバージョンアップデートにdependabotを使っています。 改めてdependabotがどういうものか軽く触れると、リポジトリ内でライブラリのバージョンアップデートや脆弱性を考慮して、バージョン更新のためのPRを作成したり通知してくれるツールです。 GitHubが公式に提供しているツールですね。開発者のみなさんはお馴染みの方も多いのではないかと思います。
PRが作成されるとterraform planを実行するワークフローが動作することは図のとおりですが、このワークフローはPRの作成が開発者のよるものかdependabotによるものか関わらず動作するようになっていました。 具体的にはworkflowの定義ファイルで以下のようにトリガーをセットしていました。
on: pull_request:
しかしdependabotが作成したPRをトリガーにして実行されるterraform planでエラーが出ました。 エラーは以下の通りです(一部改変あり)。
Run terraform initterraform init(省略)Initializing modules...- functionA in ../../modules/moduleA- functionB in ../../modules/moduleB╷│ Error: No valid credential sources found││ Please see https://www.terraform.io/docs/language/settings/backends/s3.html│ for more information about providing credentials.││ Error: failed to refresh cached credentials, no EC2 IMDS role found,│ operation error ec2imds: GetMetadata, failed to get API token, operation│ error ec2imds: getToken, http response error StatusCode: 400, request to│ EC2 IMDS failed│╵Error: Terraform exited with code 1.Error: Process completed with exit code 1.
どうやらクレデンシャルを読み取れておらず、terraform planの前段にあるterraform initで発生したエラーのようです。
クレデンシャルを読み取れない仕様
はて...と思い原因を探ってみると、きちんとドキュメントに記載がありました。
Secrets are populated from Dependabot secrets. GitHub Actions secrets are not available.
(訳)シークレットは Dependabot のシークレットから取得されます。 GitHub Actions のシークレットは利用できません。
GitHub Actions での Dependabot のトラブルシューティング - GitHub Docs
dependabotをトリガーに実行されるイベントでは、シークレットがDependabotのシークレットから取得されるとあります。
2025/02/26現在、GitHubのSecrets and variablesという設定項目にはActions, Codespaces, Dependabotの3種類が存在しています。このDependabotでクレデンシャルを設定する必要がありそうです。
が、本当にそれで意図した動作になるのか一点懸念がありました。それはdependabot.ymlの中でdependabot secretsを読み込むことができるだけかもしれないということです。 「dependabotをトリガーに実行されるイベント」が、PRを作成するイベント、すなわちdependabot.ymlの話をしているようにも読み取れるなと思っていたのです。 さらにドキュメントを読み進めていくと以下のような記述がありました。
When a Dependabot event triggers a workflow, the only secrets available to the workflow are Dependabot secrets. GitHub Actions secrets are not available. You must therefore store any secrets that are used by a workflow triggered by Dependabot events as Dependabot secrets.
(訳)Dependabot イベントがワークフローをトリガーする場合、ワークフローで使用できるシークレットは Dependabot シークレットのみです。 GitHub アクションのシークレットは使用できません。 そのため、Dependabot イベントをトリガーとするワークフローで使用するシークレットは Dependabot シークレットとして保存する必要があります。
GitHub Actions での Dependabot のトラブルシューティング - GitHub Enterprise Cloud Docs
ここまで読むと、Dependabotで設定したsecretsをGitHub Actionsのワークフローで読み込んでくれることがわかりました。これでクレデンシャルをきちんと読み込んでくれそうです。
ちなみにエラー発生時点ではActionsにのみsecretsを設定していました。 整理すると
- GitHub Actionsをユーザーが実行した(PRを作成した)場合: Actionsに設定したsecretsが読み取られる
- GitHub Actionsがdependabotの何らかのイベントをトリガーに実行した場合: Dependabotに設定したsecretsが読み取られる
ということになりそうです。
無事にterraform init, planができた
ということでDependabotの項目からクレデンシャルを設定したところCIが成功するようになりました。めでたしめでたし。
ちなみにGitHub Actionsのワークフロー定義ではsecrets.<キー名>
という形で呼び出すことができたので、Actionsに設定しているのかDependabotに設定しているのかでワークフローの修正は不要です。
それから、もともと失敗していたのはterraform planを実行するワークフローのみで、terraform applyは成功していました。 terraform applyはPRがマージされたことをトリガーに実行されるActionなのですが、その場合はDependabotではなくActionからsecretsを読み込んでいたから、という理由になりそうです。
この記事がどなたかの助けになれば幸いです。