見出し画像

GitHub ActionsでAWSのクレデンシャルを渡さずにCICDを実行してみた

はじめに

こんにちは、SHIFTの開発部門に所属している Katayama です。

GitHub Actions の CICD で、AWS 環境に Deploy する際に最も簡単なのは AWS のクレデンシャルを GitHub Actions のSecretに登録して、パイプライン(yaml)でそれを利用する事だと思う。
具体的には以下のような感じ。

- 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

ただ、このような方法の場合、AWS クレデンシャルが外に出ていて良くないという問題がある。そこでConfiguring OpenID Connect in Amazon Web Servicesに書かれているような方法(一時的なトークンを GitHub Actions が受け取り、それを使って CICD を行う)でパイプラインを構築する方法がある。

今回はこの方法を利用して、GitHub Actions で AWS クレデンシャルを渡さずに CICD を実行してみたいと思う。

実際にやってみる

公式のConfiguring OpenID Connect in Amazon Web Servicesが参考になる。

AWS 側の設定

前提として…ID プロバイダーとフェデレーション

AWS にはID プロバイダーとフェデレーションという機能があり、これは AWS のアカウント管理の仕組み(IAM ユーザー)でユーザー認証をして AWS を利用できるようにするのではなく、外部の ID プロバイダー(IdP)で管理されている ID を使って認証して AWS を利用できるようにする仕組み(AWS が認証をするのではなく、AWS は外部の ID プロバイダーでの認証後に渡されるもの= ID トークンの内容をみて AssumeRole を行い、AWS にアクセスできるようにする)。

今回、GitHub Actions で AWS のリソースにアクセスして CICD を実行するが、これと同じよう仕組みに乗っかる。ただし、ID プロバイダーは何でもかんでも利用できるわけではなく、利用したい ID プロバイダー(OpenID Connect)を AWS に登録する必要がある(AWS の言葉を借りると「信頼関係を確立する」必要がある)。その方法はOpenID Connect (OIDC) ID プロバイダーの作成に書かれているので、次の章ではその登録を行っていく。

※ちなみに、ID プロバイダーは登録が必要といったが、Google や Facebook など一部の ID プロバイダーは既に AWS に登録済みので何もしないで利用できる(以下、公式からの引用)。

Google、Facebook、または Amazon Cognito の OIDC ID プロバイダーを使用している場合は、この手順を使用して別の IAM ID プロバイダーを作成しないでください。これらの OIDC ID プロバイダーは、AWS にすでに組み込まれており、使用できます。

OpenID Connect (OIDC) ID プロバイダーの作成

まずは、OpenID Connect (OIDC) ID プロバイダーの作成に書かれている手順で、OIDC プロバイダーの作成を行う。これにより、AWS にて GitHub OIDC という GitHub の OpenID Connect が利用できるようになる。

上記の ID プロバイダを作成の画面で入力している「プロバイダの URL」と「対象者」についてはAdding the identity provider to AWSに記載がある。

対象者というのは OIDC の audience(aud クレームの値)の事で、クライアント ID を意味する。この値は GitHub Actions で CICD を実行するにあたってaws-actions/configure-aws-credentialsという GitHub Actions 公式のアクションを利用するが、そのアクション自体がクライアントになり、そのため audience 名としては sts.amazonaws.com というものになる。

ちなみに、Assuming a Roleに書かれている通り、自分で任意の名前を付ける事もできるみたいである。

The default audience is sts.amazonaws.com which you can replace by specifying the desired audience name in audience.(デフォルトのオーディエンスは sts.amazonaws.com ですが、オーディエンスに希望のオーディエンス名を指定することで置き換えが可能です。)

AWS に ID プロバイダーの登録ができたら、次はサードパーティー ID プロバイダー (フェデレーション) 用のロールの作成に書かれている IAM ロールの作成を行う。

GitHub OIDC ID プロバイダーのロールの設定

AWS の「ID プロバイダーとフェデレーション」の仕組みを利用して、Google アカウントで AWS を利用・操作してみたの事前準備② AWS 上で IAM ロールを作成するで実施していた、IAM ロールの作成を行っていく。ここで作成したロールが、GitHub Actions の workflow に Assume Role されるロールになる。

つまりこの手順は、外部の ID プロバイダーのアカウントを持つユーザーなどに AWS のどの操作を許可するのか?を決めるための手順という事になる。

信頼関係の「信頼されたエンティティ」はConfiguring the role and trust policyを参考に編集が必要になる。
デフォルトの設定では全てのaws-actions/configure-aws-credentialsで Assume Role を要求できる状態になっているので、リポジトリ名・ワークフロー名やワークフロー実行のトリガーとなった git ref などで Assume Role される対象の GitHub Actions の workflow を制限する必要がある。
そのためには GitHub OIDC のsub クレーム(一意識別子)のルールを知る必要があるが、それについてはExample subject claimsに書かれている。

今回はリポジトリ名と workflow のトリガーとなった git ref を指定し、それ以外のリポジトリや git ref からの Assume Role リクエストは却下されるようにしている。

※「信頼されたエンティティを選択」では、ウェブアイデンティティを選択する。アイデンティティプロバイダーの部分は、セレクトボックスで ID プロバイダーとして登録済みのものが一覧で表示されるので、先ほどの手順で登録した「token.actions.githubusercontent.com」を選択する。

※「許可を追加」の部分では今回は AdministratorAccess を選択したが、ここは構築したい CICD に合わせて権限を絞ったポリシーをアタッチするようにすべき部分(今回は検証という事でフルアクセス権限にしている)。

ここまでで、AWS 側の準備は完了になる。

GitHub Actions 側の設定

次に GitHub Actions のワークフロー(yaml)の設定をしていく。やる事は多くなく、Updating your GitHub Actions workflowに書かれている 2 つの対応をすればいい。

1 つは、GitHub Actions の workflow が GitHub OIDC の ID トークンを要求できるように、permission に id-token: write と、actions/checkout を利用するのであれば contents: read を追加する。

2 つ目は、aws-actions/configure-aws-credentials の設定で、これはRequesting the access tokenUsageに書かれている通り。

設定後のワークフロー全体としては以下のようになる(AWS のアカウント ID はシークレットに登録している前提)。

name: cicd

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v3

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/aws-identity-providers-federation-github-actions
          role-session-name: github-actions-test-session
          aws-region: ap-northeast-1

      - name: deploy
        run: |
          yarn install
          yarn deploy

実際に GitHub Actions を実行してみる

IAM Access Analyzer から IAM ロールの利用状況を確認すると、以下の画像の通り、GitHub Actions から IAM ロール aws-identity-providers-federation-github-actions が利用されている事が確認できる。

また、CloudTrail を確認すると、以下の画像の通り、github-actions-test-session という名前(一時的なトークンを受け取って AWS にアクセスしている)で Deploy を実行できている事が確認できる。

もちろん、GitHub Actions のワークフローは成功になっている事も確認できる。

まとめとして

OpenID Connect についてはOpenID Connect 全フロー解説等を参考に理解を深め、ID トークンは本人確認情報であるというのは理解していた。ただ、その誰?という本人確認情報というのは人に対するものだと思っていたので、今回利用した仕組みのように、GitHub Actions の workflow が人のような概念として本人確認情報(ID トークン)を渡す側になる事もあると知り少し新鮮だった。

GitHub Actions を利用した CICD で AWS にアクセスする際には、上記の方法を取る事で AWS クレデンシャルを外に露出させる事なく運用できるので、セキュリティとしてもよいのではないかと思った。

※ちなみに、今回利用したフロー全体の説明はGetting started with OIDCに書かれている。

※上記のAWSの設定の部分についてはSample IAM Role CloudFormation TemplateにCloudFormationのテンプレートがあり、それも参考になるだろう。

参考文献

Configuring OpenID Connect in Amazon Web Services
About security hardening with OpenID Connect

《この公式ブロガーの記事一覧》


執筆者プロフィール:Katayama Yuta
SaaS ERPパッケージベンダーにて開発を2年経験。 SHIFTでは、GUIテストの自動化やUnitテストの実装などテスト関係の案件に従事したり、DevOpsの一環でCICD導入支援をする案件にも従事。 昨年に開発部門へ異動し、再び開発エンジニアに。そろそろ開発エンジニアに復帰して1年。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/