tl;dr
MY_TEAM_AWS_${ACCOUNT_NAME}_${IAM}_AKIAXXXXXXXX
みたいなシークレット名にしましょうという話です
本編
自分のチームではJenkinsからGitHub Actions(GHA)への脱出を継続的にやっている。プロダクトに歴史があるからJenkinsがいろいろな所で使われていて、なかなか脱出できない。
その一環として、credentialを使ってAWSにアクセスするというworkflowを書く機会があったのでメモ。
(PrivateなGitHubリポジトリを運用しているという前提の話です)
前提
外部から呼びたければIAMでcredential発行する必要がある
GHAのような外部サービスからAWSのサービスにアクセスするときには、IAMでcredentialを発行してこれを使っている。
IAMは以下のような形式で、アクセスキーIDとシークレットアクセスキーとを発行する。
- アクセスキーID
AKIAXXXXXXXXXXXX
みたいな形式
- シークレットアクセスキー
- ランダムな英字
GitHubにSecretとして保存する
言うまでもなく、IAMのcredentialをそのままworkflowにベタ書きしてはならないので、GitHubにはSecrets機能がある。CredentialをOrganization SecretsかRepository Secretsとして登録して、そこに登録したシークレット名でworkflowからアクセスできるようにするという手法を使う。
... env: SECRET_ENV: ${{ secrets.ここにsecretの名前を書き込むといい感じに置換される }} ...
アクセスキーIDは隠さなくてよい
ところで、自分のチームの従来の運用はこうだった。すなわち、アクセスキーIDとシークレットアクセスキーとの両方をRepository/Organization Secretsとして登録する。
- シークレット
MY_TEAM_AWS_ACCESS_KEY_ID
- IAMのアクセスキーIDを格納する
- シークレット
MY_TEAM_AWS_SECRET_ACCESS_KEY
- IAMのシークレットアクセスキーを格納する
ただしこの手法には欠点があって、このキーがどこで生成されたのか分からないので、キーを交換したいとき等に困ってしまうという問題があった。そして、項目が2つもあると実際面倒臭い。
そこで、今回からは次のような運用に切り替えてみた。すなわち、シークレットアクセスキーのみをRepository/Organization Secretsとして登録し、その名前にアクセスキーIDを含める。
- シークレット
MY_TEAM_AWS_${ACCOUNT_NAME}_${IAM}_AKIAXXXXXXXX
- シークレット名称にAWSアカウント名、IAMユーザ名、そして
AKIA...
で始まるアクセスキーIDを含めている
- シークレット名称にAWSアカウント名、IAMユーザ名、そして
この手法の良いところは、どこのアカウントなのか(アカウント分離しているときに役立つ)、IAMの誰のcredentialなのか、そしてどのcredentialなのか一意に特定できるところ。 運用がかなりしやすくなるし、「動かないと思ったらうっかり別アカウントのcredentialをひもづけていた!!」みたいなやらかしも減らせる。
ところで、アクセスキーIDが見える状態になるが良いのかという問いが生じるが、そもそも社内のGitHubリポジトリにアクセスできるユーザはIAMも見られるはずだ、という仮定に立って、見られても問題なかろうと考えている。だからこそわざわざIDとシークレットを分けているのだろうし、問題ないはず。