今さらながら GitHub Actions をさわってみる: (AWS へのアクセス編)
前回、前々回に引き続き、GitHub Actions のワークフローを触っていきます。
今回は、ワークフローから AWS アカウントへアクセスする方法を整理しつつ、実際にアクセスを試していきます。
最終的には、GitHub Actions を使用して アプリケーションをビルドし、AWS アカウントにデプロイするワークフローを作成しようと思っているので、AWS アカウントへのアクセス方法の理解はその事前準備となります。
なお、この記事は 2023 年 3 月時点で検証した内容に基づいて記載しています。
目次
- AWS アカウントへアクセスする方法の整理
- 方法 1. AWS のアクセスキー ID やシークレットアクセスキー を GitHub の Secret として保存してワークフローから使用する方法
- 方法 2. GitHub の OpenID Connect (OIDC) プロバイダを使用し、AWS アカウントにアクセスできるトークンを使用する方法
- 今回の所感
AWS アカウントへアクセスする方法の整理
まず、GitHub のドキュメントを参照して AWS アカウントへのアクセス方法を整理してみましたが、基本的には下記の 2パターンがあるようです。
- AWS のアクセスキー ID やシークレットアクセスキー を GitHub の Secret として保存してワークフローから使用する方法
- GitHub の OpenID Connect (OIDC) プロバイダを使用し、AWS アカウントにアクセスできるトークンを使用する方法
セキュリティの観点から上記 2 の方法が推奨 のようですが、とりあえず両方の方法を試します。
方法 1. AWS のアクセスキー ID やシークレットアクセスキー を GitHub の Secret として保存してワークフローから使用する方法
GitHub の Secret については、次のドキュメントに記載があります。AWS アカウントのアクセスキーなど、秘匿すべき認証情報を保存する用途に使えそうです。
この Secret を使ったワークフローのイメージ図を描いてみました。
上図のように、仕組みとしてはシンプルでわかりやすいですよね。
ただし、前述のようにこの方法はお薦めできません。
Secret という仕組みはあるにせよ、永続的に使用できるアクセスキー ID を発行してそれを一つの場所にずっと保管することはセキュリティ面での懸念があるからです。
後で説明する 2番目の方法のように、必要なタイミングで一時的に使用できるトークンを発行して使用する 方が望ましいのですが、今回は勉強の一環として試してみました。
まず、AWS アカウントで 下記の IAM ポリシーを作成します。(ここでは便宜上、s3-listAllMyBuckets-policy と名付けます。)
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*" } ] }
次に IAM ユーザーを作成して作成した s3-listAllMyBuckets-policy を設定し、アクセスキーID とシークレットアクセスキーを発行します。
そのアクセスキーID とシークレットアクセスキーを GitHub の Secret として設定します。
設定方法は、Web ブラウザからでも GitHub CLI からでも可能です。
Web ブラウザの場合は、対象リポジトリのページから [ Settings ] タブ、左側のメニューで [ Secrets and variables ] - [ Actions ] を選択して、右上の [ New repository secret ] を選択して設定します。設定した Secret の名前は後でワークフローの中で指定します。
では次にワークフローの YAML ファイルを作ります。
今回は、下記のドキュメントを参考にしました。
ただし、今回は AWS アカウントへのアクセスを試すのが目的なので、 AWS SAM は使用せず、AWS CLI のコマンドを aws s3 ls
を発行するだけのシンプルなワークフロー(下記)に変えることにしました。
aws s3 ls
が正常に実行され、Amazon S3 バケットの一覧が表示されれば AWS アカウントへアクセスできたという確認になります。
name: AWS access using secrets in GitHub on: push: branches: - main jobs: list-s3-buckets-using-Secret: runs-on: ubuntu-latest steps: - 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: ap-northeast-1 - name: execute AWS CLI run: aws s3 ls
上記の YAML でポイントになるのは、10 行目から 15 行目のステップです。
aws-actions/configure-aws-credentials
というアクションを用いることで、AWS アカウントのアクセスするための認証情報をセットして、AWS CLI も利用できるようになります。
そのため、次の 16 行目からのステップでは、すぐに AWS CLI で aws s3 ls
を実行しています。
このワークフローを実行すると、正常に Amazon S3 バケットの一覧が表示されました。
GitHub のワークフローから AWS アカウントへアクセスを確認できたわけです。
方法 2. GitHub の OpenID Connect (OIDC) プロバイダを使用し、AWS アカウントにアクセスできるトークンを使用する方法
ただ、(繰り返しになりますが)前述の方法 1 よりもお薦めなのが この OIDC を使用する方法です。
下図は、この仕組みを図にしてみたものです。
方法 1 よりは複雑に感じるかもしれませんが、要するに AWS アカウントがGitHub の OIDC プロバイダを信頼する ことで、その OIDC プロバイダが発行した JWT (ジョット)トークンがあれば AWS の IAM ロールを使用できるようにする仕組みです。
GitHub の OIDC プロバイダが発行するJWTトークンがあれば、AWS 側からアクセストークンが発行されるので、そのアクセストークンで AWS アカウントにアクセスすれば、事前に設定した IAM ロールに紐づく IAM ポリシーの権限の範囲で AWS リソースを操作できます。
この仕組みを実現するには、まず GitHub の OIDC プロバイダを AWS アカウント側に登録します。
この方法は、GitHub の下記のドキュメントにも記載されています。
この登録ですが、AWS マネジメントコンソールでも AWS CLI でも行えますが、個人的には AWS マネジメントコンソール を使う方が簡単 でお薦めです。
その理由は、OIDC プロバイダ登録時には TLS 証明書のサムプリント ( thumbprint ) の値が必要なのですが、AWS CLI の場合は、事前に様々なコマンドを発行したり編集したりしてそのサムプリントの値を自分で導出したうえでパラメータに指定する必要があるのに対して、AWS マネジメントコンソール ではサムプリントの値は自動的に取得、設定可能なためです。
参考として下記のドキュメントを紹介しますので、興味があれば実施してみて下さい。
ここではシンプルに設定できる AWS マネジメントコンソールを使用する方法を紹介します。
まず IAM のコンソールの左側のメニューから [ アクセス管理 ] - [ ID プロバイダ ] を選択し、右側にある [ プロバイダを追加 ] を選択します。
[ プロバイダのタイプ ] に [ OpenID Connect ] を選択します。
[ プロバイダの URL ] に https://token.actions.githubusercontent.com
を入力して [ サムプリントを取得 ] を選択します。
その後、その下にある [ 対象者 ] に sts.amazonaws.com
と入力して、ページ右下にある [ プロバイダを追加 ] をクリックします。
これで OIDC プロバイダの登録は完了です。
次に、この OIDC プロバイダを信頼する IAM ロールを作成します。
AWS マネジメントコンソールで作成する場合は、IAM のページから左側のメニューで[ アクセス管理 ] - [ ロール ] を選択し、右側にある [ ロールを作成 ] を選択します。
[ 信頼されたエンティティを選択 ] のページで [ 信頼されたエンティティタイプ ] に [ ウェブアイデンティティ ] を選択します。
[ アイデンティティプロバイダー ] に [ token.actions.githubusercontent.com ] を選択します。
[ Audience ] に [ sts.amazonaws.com ] を選択して、[ 次へ ] を選択します。
その後は、方法 1 で作成した s3-listAllMyBuckets-policy の IAM ポリシー(下記)を許可ポリシーとして設定します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*" } ] }
ロールの名前は任意の値を入力してロールを作成します。今回の例では、s3-listAllMyBuckets-role とします。
これでロールは作成したのですが、ロールの信頼ポリシーで GitHub のリポジトリを限定するように条件を追加しておきましょう。
作成したロールの名前をクリックして、[ 信頼関係 ] タブを選択して、[ 信頼ポリシーを編集 ] を選択します。
そしてポリシーの Condition に下記を追加します。
これは、GitHub の特定のリポジトリだけを対象に IAM ロールの引き受けを可能にするための条件設定です。
セキュリティの面から IAM ロールを引き受けを認める範囲を限定する必要があるため、必ず設定して下さい。
"StringLike": { "token.actions.githubusercontent.com:sub": "repo:<GitHubのユーザーID>/<GitHubのリポジトリ名>:*" }
下記は、条件を追記した信頼ポリシー全体の例です。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::111111111111:oidc-provider/token.actions.githubusercontent.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" }, "StringLike": { "token.actions.githubusercontent.com:sub": "repo:tetsuo-nobe/aws-access:*" } } } ] }
これで AWS アカウント側の事前準備は終わったので、GitHub のワークフローを作成していきます。
下記のドキュメントにワークフローの例があるので、これを参考に方法 1 と同じく AWS CLI で aws s3 ls
を実行するワークフローを作成します。
ただ、上記のドキュメントの例をみて、おや❓ と感じました。
ワークフローの YAML には、引き受ける IAM ロールの ARN を指定する必要がありますが、この例では、ワークフローが引き受ける IAM ロールの ARN の値を YAML ファイルにそのまま記述しています。
しかし、ARN には AWS アカウント ID の 12桁の数字も含まれるので、YAML ファイルにそのまま記述するのは避けたいですよね。
ということで、IAM ロールの ARN は GitHub の Secret に保存し、それを参照することにしました。
OIDC の方法を用いれば Secret は使わなくてもいいかなと思っていたのですが、やはり AWS アカウントID は秘匿しておきたいですよね。
結果、完成した ワークフローの YAML が下記です。
name: AWS access using OIDC provider on: push: branches: - main env: AWS_REGION : "ap-northeast-1" # permission can be added at job level or workflow level permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout jobs: list-s3-buckets-using-OIDC: runs-on: ubuntu-latest steps: - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN }} role-session-name: samplerolesession aws-region: ${{ env.AWS_REGION }} - name: execute AWS CLI run: aws s3 ls
19 行目では、Secret を使って IAM ロールの ARN を取得するようにしています。
実行してみると、下図のように aws s3 ls
が正常に実行されたことを確認できました。
今回の所感
今回の記事の中で紹介した OIDC を使用する方法により、 AWS のアクセスキー ID を発行して GitHub 側に保存しなくても AWS アカウントへアクセスできるが確認できました。
この方法を理解できたことで、GitHub Actions を使用して AWS アカウントへ アプリケーション環境を構築するワークフローの作成方法のイメージが大きく膨らんできました!
次回は、今回の記事の内容をベースにしつつ、AWS アカウントへアプリケーション環境を構築するワークフローを作成したいと思います!