【日本語訳】Configure AWS Credentials

### GithubActionsにAWSアクセスキーを持たせるのは時代遅れ

GithubActions内のワークフローにベタ書きするのも、変数で持たせるのも、永続的なクレデンシャル情報をGithubに持たせるのも微妙でした...**が**

[aws-actionsにその問題を解決するGithubActions](https://github.com/aws-actions/configure-aws-credentials)が追加されました。（2021/11/23正式リリース）

これによりGithubActionsにAWSアクセスキーを持たせなくてもAWS Credentialsの設定ができるようになりました。

なんて、半年前のものについての内容を**今更ドヤ顔しながら掘り返しても**あまり意味がないので
（やり方については調べればいくらでも出てくる。[ココ](https://dev.classmethod.jp/articles/github-actions-aws-sts-credentials-iamrole/)とか）

意外と見落としがちな公式ドキュメントをざっくりと自分の言葉で日本語訳してみたので、何かの参考にしていただければと思います。

## Githubアクションの"Configure AWS Credentials"アクション
このGithubアクションを使用するためにはAWSクレデンシャルとリージョン環境変数を設定します。
この環境変数を設定することでGithubAction内でAWSSDKとAWSCLIコマンドを発行した際のAWSAPIのクレデンシャル情報を付与してくれます。

> Tips. このGithubActionを使うことで、いちいち細かい設定する必要なく簡単にAWSクレデンシャルが設定できる

## 使用方法

    
    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
        aws-region: us-east-2
    

例えば、Githubの仮想環境で利用可能なAWSCLIのアクションを使用できます。
さらに、このアクションを複数回実行することで同じGithubアクションワークフロー内で異なるAWSアカウント、リージョン、またはIAMロールを使用することもできます。



    jobs:
      deploy:
        name: Upload to Amazon S3
        runs-on: ubuntu-latest
        # このpermissionはGithubのOIDCトークンエンドポイントとやりとりするために必要です。
        permissions:
          id-token: write
          contents: read
        steps:
        - name: Checkout
          uses: actions/checkout@v2

        # テストアカウントのCredentialsを設定
        - name: Configure AWS credentials from Test account
          uses: aws-actions/configure-aws-credentials@v1
          with:
            role-to-assume: arn:aws:iam::111111111111:role/my-github-actions-role-test
            aws-region: us-east-1

        # AWS CLIを使ってファイルをテストウェブサイトにコピーする
        - name: Copy files to the test website with the AWS CLI
          run: |
            aws s3 sync . s3://my-s3-test-website-bucket

        # プロダクションのCredentialsを設定
        - name: Configure AWS credentials from Production account
          uses: aws-actions/configure-aws-credentials@v1
          with:
            role-to-assume: arn:aws:iam::222222222222:role/my-github-actions-role-prod
            aws-region: us-west-2

        # AWS CLIを使ってファイルをプロダクションウェブサイトにコピーする
        - name: Copy files to the production website with the AWS CLI
          run: |
            aws s3 sync . s3://my-s3-prod-website-bucket
    

> Tips. リージョンの変更もロールの変更も簡単に行える

## アクションのIF定義（action.yml）
| インプットプロパティ  | 説明 | 要否 |
|---|---|---|
| aws-access-key-id | AWSアクセスキーID。従来のやり方で接続したいときなどに必要。基本的にAWSクレデンシャルを持っていればいらない。EC2インスタンスなどで使うかも | 任意 |
| aws-secret-access-key | AWSシークレットアクセスキー。AWSアクセスキーIDとセットで使う| 任意 |
| aws-session-token | AWSセッショントークン。認証する際に必要だが、基本的に設定することはないはず。 | 任意 |
| aws-region | AWSリージョン。 es-east-2とか | 必須 |
| mask-aws-account-id | クレデンシャルのAWSアカウントIDをシークレット値として設定するかどうか。ログ上のAWSアカウントIDがマスクされるようになります。デフォルトは「true」 | 任意 |
| role-to-assume | 提供されたクレデンシャルを使用してIAMロールを引き受け、Githubアクションにクレデンシャルを付与します。 | 任意 |
| web-identity-token-file | 提供されたファイルパスのWebIDトークンファイルを使用して、WebIDによるIAMロールを引き受けます。例：Amazon EKS worker node内など | 任意 |
| role-duration-seconds | ロールの有効時間（デフォルト：６時間） | 任意 |
| role-session-name | ロールセッション名（デフォルト：GitHubActions） | 任意 |
| role-external-id | 引き受けるロールの外部ID | 任意 |
| role-skip-session-tagging | ロールの引き受け中のセッションタグ付けをスキップするか | 任意 |


| アウトプットプロパティ  | 説明 |
|---|---|
| aws-account-id | AWSアカウントID |

## クレデンシャル
GitHub Actionsワークフローで使用されるAWSクレデンシャルについては、AmazonIAMのベストプラクティクスに従うことをお勧めします。

- リポジトリ内コードにクレデンシャルを保存しないでください
- GithubActionsワークフローで使用される資格情報には最小限の特権を付与してください。
- GitHubActionsワークフローで使用されるクレデンシャルのアクティビティを管理してください。

> Tips. 基本的にはAmazonIAMのベストプラクティスに則ったほうがいい

## ロールを引き受ける
GitHubのOIDCプロバイダーを使用して、アクションに必要な短期間のクレデンシャルを取得することをお勧めします。
aws-access-key-idまたはweb-identity-token-fileを指定せずに引き受けるロールを指定すると、OIDCプロバイダーの利用がアクションに通知されます。
OIDCプロバイダーを使用してIAMロールを直接引き受ける場合、デフォルトのセッション期間は１時間です。
IAMユーザを使用してIAMロールを引き受ける場合のデフォルトのセッション期間は６時間です（aws-access-key-id、aws-secret-access-key、およびロールを指定することにより可能）
このセッション期間はrole-duration-secondsで変更できますが、IAMロールを作った時に定義した最大値を超えることはできません。
デフォルトのセッション名はGitHubActionsであり、role-session-nameで名前を指定することができます。

### 使用アイデンティティとプロパティの関係

| 使用するアイデンティティ | aws-access-key-id | role-to-assume | web-identity-token-file |
|---|---|---|---|
| **（推奨）** GithubOIDCプロバイダーを使用して直接ロールを引き受ける |  | ✅ |  |
| IAMユーザー | ✅ |  |  |
| IAMユーザークレデンシャルを使ってロールを引き受ける | ✅ | ✅ |  |
| WebIdentityトークンファイルのクレデンシャルを使用してロールを引き受ける|  | ✅ | ✅ |

> Tips. いろいろなやり方でアイデンティティを受け取れるけれど、GithubOIDCプロバイダーを使うのが推奨

## Examples
    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-region: us-east-2
        role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
        role-session-name: MySessionName

この例では、Githubが提供する環境変数からOIDCトークンをロードし、それを使ってセッション名が***MySessionName***のロールarn:aws:iam::123456789100:role/my-github-actions-roleを引き受けます。

>Tips. GithubOIDCプロバイダーを使用した例

    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-2
        role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
        role-external-id: ${{ secrets.AWS_ROLE_EXTERNAL_ID }}
        role-duration-seconds: 1200
        role-session-name: MySessionName  

この例では、シークレット.AWS_ROLE_TO_ASSUMEにarn：aws：iam::123456789100：role/my-github-actions-roleのような文字列が含まれています。
静的クレデンシャルと同じアカウント内でロールを引き受けるには、role-to-assume：my-github-actions-roleのようにロール名を指定するだけです。

>Tips. IAMユーザークレデンシャルを使ってロールを引き受ける例

## IAM Role CloudFormation Template サンプル

    Parameters:
      GitHubOrg:
        Type: String
      RepositoryName:
        Type: String
      OIDCProviderArn:
        Description: Arn for the GitHub OIDC Provider.
        Default: ""
        Type: String
    
    Conditions:
      CreateOIDCProvider: !Equals 
        - !Ref OIDCProviderArn
        - ""
    
    Resources:
      Role:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Statement:
              - Effect: Allow
                Action: sts:AssumeRoleWithWebIdentity
                Principal:
                  Federated: !If 
                    - CreateOIDCProvider
                    - !Ref GithubOidc
                    - !Ref OIDCProviderArn
                Condition:
                  StringLike:
                    token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrg}/${RepositoryName}:*
    
      GithubOidc:
        Type: AWS::IAM::OIDCProvider
        Condition: CreateOIDCProvider
        Properties:
          Url: https://token.actions.githubusercontent.com
          ClientIdList: 
            - sts.amazonaws.com
          ThumbprintList:
            - 6938fd4d98bab03faadb97b34396831e3780aea1
    
    Outputs:
      Role:
        Value: !GetAtt Role.Arn 

GitHub OIDCプロバイダーはアカウントごとに１つ作成する必要があります。
（つまり、GitHubのOIDCが引き受けることができる複数のIAMロールは単一のOIDCプロバイダーを共有できます）

## セッションのタグ付け
セッションの名前は「GitHubActions」で、次のタグが付けられます：（GITHUB_環境変数の定義は[ここ](https://docs.github.com/ja/actions/learn-github-actions/environment-variables#default-environment-variables)）

| Key | Value |
|---|---|
| GitHub | "Actions" |
| Repository | GITHUB_REPOSITORY |
| Workflow | GITHUB_WORKFLOW |
| Action | GITHUB_ACTION |
| Actor | GITHUB_ACTOR |
| Branch | GITHUB_REF |
| Commit | GITHUB_SHA |

注：すべてのタグ値は要件に準拠している必要があります。 
特に、GITHUB_WORKFLOWが長すぎると、切り捨てられます。 
GITHUB_ACTORまたはGITHUB_WORKFLOWに無効な文字が含まれている場合、文字は「*」に置き換えられます。


ロールの引き受け時にデフォルトでセッションのタグ付けを使用します。
WebIdentityの役割を引き受けるために、セッションタグはエンコードされたWebIdentityトークンに含まれている必要があることに注意してください。
つまり、タグはOIDCプロバイダーによってのみ提供され、アクション内のAssumeRoleWithWebIdentityAPI呼び出し中に設定することはできません。 
アクションの入力でrole-skip-session-taggingをtrueとして指定することにより、このセッションのタグ付けをスキップできます。

> Tips. 表のKeyを使うことでセッションタグに任意のGithub環境変数値を付けられる（Commit値とか）

## Self-Hosted Runners
EC2インスタンスなどのAWSクレデンシャルにすでにアクセスできるセルフホストランナーでGitHubアクションを実行する場合、IAMユーザーアクセスキークレデンシャルを設定する必要はありません。

アクションの入力にアクセスキーのクレデンシャルが指定されていない場合、このアクションは、AWS SDKforJavascriptのデフォルトのメソッドを使用してランナー環境からのクレデンシャルを使用します。

このアクションを使用して、環境内のリージョンとアカウントIDを設定し、アクションワークフローによって行われるすべてのAWSAPI呼び出しにランナーのクレデンシャルを使用できます。

この場合、ランナーのクレデンシャルにアクションワークフローにより呼び出されるAWSAPIを呼び出すためのアクセス許可が必要です。

または、このアクションを使用してロールを引き受け、アクションワークフローによって行われるすべてのAWSAPIコールにロールクレデンシャルを使用できます。

    uses: aws-actions/configure-aws-credentials@v1
    with:
      aws-region: us-east-2
      role-to-assume: my-github-actions-role

この場合、ランナーの資格情報には、役割を引き受けるための権限が必要です。


また、Amazon EKS IRSAを使用する場合など、WebIDトークンファイルを使用してロールを引き受けることもできます。 ルートとして実行されないEKSワーカーノードで実行されているポッドは、このファイルを使用してWebIDを持つロールを引き受けることができます。

このファイルを使用するには、ワークフローを次のように構成できます。
    
    uses: aws-actions/configure-aws-credentials@v1
    with:
      aws-region: us-east-2
      role-to-assume: my-github-actions-role
      web-identity-token-file: /var/run/secrets/eks.amazonaws.com/serviceaccount/token

> Tips. GithubActionのホストランナーを自分でやっているときは、ランナーのクレデンシャルにAWSAPIを呼び出すアクセス権限が必要

## AWSCLIで使用
このワークフローでは、AWSCLIを環境にインストールしません。
なのでawsコマンドを実行す流場合、AWSCLIがまだ存在しない場合はインストールする必要があります。 
ですが、ほとんどのGitHubホストランナー環境には、デフォルトでAWSCLIが含まれています。

> Tips. GithubActionを自分でホストランナーしている場合は、AWSCLIを入れる

# 終わり
「GithubActionsで簡単にクレデンシャル情報が取れるらしいよ」
「へーやってみよ」
と言って公式ドキュメントを読まず、リリース当時にあがっていたリリース前の情報を見ながら「できない...泣」となっていたのですが、リリース後の公式ドキュメントをよく見たらやり方がバッチリ書いてあってショックだったので今回の記事を書いてみました。
英語なだけで少し敬遠しがちになってしまうのですが、今後は苦手意識を無くしてちゃんと読もうと思いました。（当たり前）
今回執筆するまではcredentialsを取得する最低限のプロパティぐらいしか知らなかったんですが、IFプロパティとかをきっちり理解できた気がしたので満足。