GithubActionsにAWSアクセスキーを持たせるのは時代遅れ
GithubActions内のワークフローにベタ書きするのも、変数で持たせるのも、永続的なクレデンシャル情報をGithubに持たせるのも微妙でした...が
aws-actionsにその問題を解決するGithubActionsが追加されました。(2021/11/23正式リリース)
これによりGithubActionsにAWSアクセスキーを持たせなくてもAWS Credentialsの設定ができるようになりました。
なんて、半年前のものについての内容を今更ドヤ顔しながら掘り返してもあまり意味がないので
(やり方については調べればいくらでも出てくる。ココとか)
意外と見落としがちな公式ドキュメントをざっくりと自分の言葉で日本語訳してみたので、何かの参考にしていただければと思います。
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 | ロールの有効時間(デフォルト:6時間) | 任意 |
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ロールを直接引き受ける場合、デフォルトのセッション期間は1時間です。
IAMユーザを使用してIAMロールを引き受ける場合のデフォルトのセッション期間は6時間です(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プロバイダーはアカウントごとに1つ作成する必要があります。
(つまり、GitHubのOIDCが引き受けることができる複数のIAMロールは単一のOIDCプロバイダーを共有できます)
セッションのタグ付け
セッションの名前は「GitHubActions」で、次のタグが付けられます:(GITHUB_環境変数の定義はここ)
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プロパティとかをきっちり理解できた気がしたので満足。