GitHub ActionsのOpenID ConnectorとAWSのOIDC Providerを使うことで、IAM RoleをAssumeできるというのは前回書きました。
構築中によく出るエラーに関しても書いたのですが、いざ実際に使おうとしたら別のエラーではまったので忘れないようにメモしておきます。
tl;dr;
- OpenID Connectで認証すると、AWS OIDC Providerの認証の上限に引っ掛かりやすい
- Composite Actionの中で、 configure-aws-credentialsを呼び出すときは注意
- 2021/12/10追記: このPRが入れば自動的にリトライしてくれるで記事のプラクティスは不要になる予定
GitHub Actions で並列実行すると時々失敗する。
2022/2/4 本バグはhttps://github.com/aws-actions/configure-aws-credentials/issues/299で修正されています。もう気にしなくともリトライもされます。
次のエラーがでます。
エラーメッセージ
Error: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements
対策: configure-aws-credentials で OIDC 認証を頻繁に呼び出す場合は、キャッシュかリトライしましょう。
並列でジョブを実行するなど、短時間に頻繁に認証を取得ようとすると、時々認証に失敗します。 IAM Userを使っていると当然でないのですが、OIDC Providerで認証をかけようとするとぐさっと刺さります。
これを回避するには、リトライかキャッシュ作戦をとる必要があります。
workflowで1回だけ認証ととって、キャッシュを使いまわす場合次のようなworkflowになります。
ただ、GitHub Actionsのcacheは「パブリックリポジトリのキャッシュには、センシティブな情報を保存しないことをおすすめします」とある通り取扱いには注意です。トークン自体は900sec (min) か1 hour (default) で切れますが、時間の問題ではないという。
Warning: We recommend that you don't store any sensitive information in the cache of public repositories. For example, sensitive information can include access tokens or login credentials stored in a file in the cache path. Also, command line interface (CLI) programs like docker login can save access credentials in a configuration file. Anyone with read access can create a pull request on a repository and access the contents of the cache. Forks of a repository can also create pull requests on the base branch and access caches on the base branch. https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows
configure-aws-credentials を1 jobで複数回呼び出したときに初回の認証を上書きできない
対策: configure-aws-credentials の呼び出しは一回の composite action で行うか、workflow で呼び出しましょう。
通常configure-aws-credentialsは、呼び出しのたびにjob内の認証を後勝ちで上書きします。 ただし、composite actionの中で、configure-aws-credentials を呼び出すと、意図しない結果になるパターンがあります。
configure-aws-credentialsを呼び出す処理をcomposite actionに書いて、1 job内で別のIAM RoleのAssumeを呼びだすと2回目のconfigure-aws-credentialsで上書きできないので避けましょう。
正常動作例1
次のように連続でconfigure-aws-credentialsを呼び出すと、2回目のconfigure-aws-credentialsでmyrole_Bに上書きできていることが確認できます。
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # 1st - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@master with: aws-region: ap-northeast-1 role-to-assume: arn:aws:iam::123456789012:role/myrole_A role-session-name: GitHubActions-${{ github.run_id }} - name: get-caller-identity shows myrole_A as expected run: aws sts get-caller-identity # 2nd - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@master with: aws-region: ap-northeast-1 role-to-assume: arn:aws:iam::123456789012:role/myrole_B role-session-name: GitHubActions-${{ github.run_id }} - name: get-caller-identity shows myrole_B as expected run: aws sts get-caller-identity
1回目のget-caller-identityはmyrole_Aです。
{ "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426675663", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426675663" }
2回目のget-caller-identityはmyrole_Bです。
{ "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426675663", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/myrole_B/GitHubActions-1426675663" }
意図通りの挙動です。
正常動作例2
Composite Actionの中でconfigure-aws-credentialsをまとめて2回呼び出すと、2回目の呼び出しでmyrole_Bに上書きできていることが確認できます。
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Configure AWS Credentials uses: ./.github/actions/aws_oidc_auth_all
aws_oidc_auth_all
はこうなっています。
# ./.github/actions/aws_oidc_auth_all/action.yaml name: aws oidc auth description: | Get aws oidc auth. runs: using: "composite" steps: # 1st - name: Configure AWS Credentials (Role A) uses: aws-actions/configure-aws-credentials@master with: aws-region: ap-northeast-1 role-to-assume: arn:aws:iam::123456789012:role/myrole_A role-session-name: GitHubActions-${{ github.run_id }} - name: get-caller-identity shows myrole_A as expected run: aws sts get-caller-identity shell: bash # 2nd - name: Configure AWS Credentials (Role B) uses: aws-actions/configure-aws-credentials@master with: aws-region: ap-northeast-1 role-to-assume: arn:aws:iam::123456789012:role/myrole_B role-session-name: GitHubActions-${{ github.run_id }} - name: get-caller-identity shows myrole_B as expected run: aws sts get-caller-identity shell: bash
1回目のget-caller-identityはmyrole_Aです。
{ "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426687022", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426687022" }
2回目のget-caller-identityはmyrole_Bです。
{ "UserId": "AROASJXUOK5UHN4XWD3XF:GitHubActions-1426687022", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/myrole_B/GitHubActions-1426687022" }
意図通りの挙動です。
問題の動作
Composite Actionの中でconfigure-aws-credentialsをそれぞれのIAM Roleについて呼び出すと、2回目の呼び出しがmyrole_Aのまま、myrole_Bで上書きできていないことが確認できます。
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # 1st <- Shows myrole_A, expected. - name: Configure AWS Credentials (Role A) uses: ./.github/actions/aws_oidc_auth_single with: [https://docs.github.com/en/actions/creating-actions/creating-a-composite-action:embed:cite] role-to-assume: arn:aws:iam::123456789012:role/myrole_A # 2nd <- Shows myrole_A, unexpected!! - name: Configure AWS Credentials (Role B) uses: ./.github/actions/aws_oidc_auth_single with: role-to-assume: arn:aws:iam::123456789012:role/myrole_B
aws_oidc_auth_single
はこうなっています。
# ./.github/actions/aws_oidc_auth_single/action.yaml name: aws oidc auth description: | Get aws oidc auth. inputs: role-to-assume: description: "AWS IAM Role to assume 1" required: true runs: using: "composite" # this is key point steps: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@master with: aws-region: ap-northeast-1 role-to-assume: ${{ inputs.role-to-assume }} role-session-name: GitHubActions-${{ github.run_id }} - name: get-caller-identity shows myrole_A on both 1st and 2nd run. (2nd run must be myrole_B but incorrect result.) run: aws sts get-caller-identity shell: bash
1回目のget-caller-identityはmyrole_Aです。
{ "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426687028", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426687028" }
2回目のget-caller-identityもmyrole_Aです。myrole_Bに上書きできていません。
{ "UserId": "AROASJXUOK5UHN4XWD3XF:GitHubActions-1426687028", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426687028" }
aws-actions/configure-aws-credentialsの中身を見ても、composite action特有の処理は当然存在しません。 composite actionの仕様かと思いつつ、そういった記述もないので謎です。
仕方ないので、正常動作例1,2のいずれかを用いることになるでしょう。
あるいは、両方の権限をもつ単一Roleでやるのも手でしょう。