GitHub Actions - OIDC 認証を使った AWS 連携

# はじめに
GitHub Actions を使って terraform による AWS 環境構築を行いました。
その際に OIDC 認証を行ったのでその部分についてまとめておきたいと思います。

# 環境
今回は以下が準備されている想定で行います。
- AWS アカウント
- GitHub リポジトリ

# 設定
設定は以下の流れで行います。
**AWS (`ID プロバイダ設定` → `IAM ロールの作成`) → GitHub (`Secrets の登録` → `Workflow の作成`)**

## OIDC 認証の作成 (AWS)
AWS マネジメントコンソールにログインします。

### ID プロバイダ
**「IAM > ID プロバイダ」** から **[プロバイダを追加]** をクリックします。

![aws-oidc001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/6b9ee17d-1da1-449f-ad52-673be26d8931.png)

### ID プロバイダの設定
**[プロバイダを追加]** をクリックします。
>プロバイダのタイプ：**OpenID Connect**
>プロバイダのURL：`https://token.actions.githubusercontent.com`
>対象者：`sts.amazonaws.com`

![aws-oidc002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/57a0c73c-6147-4d49-b471-a6502c37121d.png)

以上で ID プロバイダの追加は完了です。

## IAM ロールの作成 (AWS)
**「IAM > ロール」** から **[ロールを作成]** をクリックします。

![aws-oidc004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/e1d95cde-7192-4118-955b-9ed74dab5d99.png)

### 信頼されたエンティティを選択
信頼されたエンティティタイプの **ウェブアイデンティティ** を選択。

![aws-oidc005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/89eea579-ddbf-4e8a-a993-ff7e74503d1b.png)

### ウェブアイデンティティ
以下を入力し **[次へ]** をクリックします。
> アイデンティティプロバイダー：token.actions.githubusercontent.com
> Audience：sts.amazonaws.com
> GitHub 組織：[GitHub Actions を利用するリポジトリが所属する Orgainzation の名前]
> GitHub リポジトリ：[GitHub Actions を利用するリポジトリ名] ※オプション
> GitHub ブランチ：[GitHub Actions を利用するリポジトリのブランチ] ※オプション

今回はオプションの２つも指定しています。
指定することで IAM ロールへのアクセス範囲をリポジトリ、ブランチ単位まで限定することができるため、よりセキュアになります。
状況に応じて調整して下さい。

![aws-oidc006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/cdfd6ec0-0b89-4d54-bdc4-8303570ea3e8.png)

上記画像では `ga-test` というリポジトリの `main` ブランチからのアクセス(アクション)を許可する設定となります。

### 許可を追加
許可ポリシー を追加します。
今回は AWS との連携が確認できれば良いため **ReadOnlyAccess** を付与しています。
実際に導入する際は利用する AWS サービスに応じてアクセス権限を調整してください。
追加したら **[次へ]** をクリックします。

![aws-oidc007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/a106e081-aeae-4c66-8bb2-ea9414de125f.png)

### 名前、確認、および作成
ロールの詳細 で **ロール名** を入力します。ここでは仮に `GitHubActions` としておきます。
あとはそのままで **[ロールを作成]** をクリックします。

また、ステップ２ の内容は ウェブアイデンティティ で指定した内容を  *JSON* 形式で表しています。
赤ラインの部分が先ほど入力した内容を反映した部分です。

![aws-oidc008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/5d85adda-21bf-4960-b8c4-c0aadcc64080.png)
![aws-oidc009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/e44f3f19-4cb8-40c8-95ac-5886cbfafdda.png)
![aws-oidc010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/eb5569de-e3e7-4ace-95f2-ac8e72a43970.png)

## ロールの確認
作成が完了すると以下のようにロールが確認できます。

![aws-oidc011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/dee43737-72b9-4798-95e0-51527398196d.png)
![aws-oidc012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/d5409917-a2ac-464d-a60d-b5bdcdb1a780.png)


## GitHubActions (GitHub)
GitHubにログインし対象のリポジトリを選択します。

### Secrets の登録
`Settings` タブから `Secrets and variables > Actions` をクリックし、表示された画面で `Secrets` タブの `[New repository secret]` をクリックします。

![github-actions001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/4b998566-771a-45d3-bb0e-d80d77725fa2.png)

**Name** に `AWS_ROLE_ARN` を入力し、**Secret** に `AWS で作成した IAM ロール ARN` を入力します。

![github-actions002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/fefd8af7-7c8c-4299-a44b-1e864c9cdee2.png)

以下のように **Secrets** タブに登録されていればOKです。

![github-actions003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/e46ba558-2cdd-4e54-a274-c6311ad3854d.png)

## Workflowの設定
**Actions** タブをクリックし **Simple workflow** の `[Configure]` をクリックします。

![github-actions004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/74decff5-a87f-4364-b648-e481f13ee6fe.png)

編集画面になるので以下の内容をコピペして **[Commit changes...]** をクリックします

```yml:blank.yml
name: AWS OIDC

on:
  push:
    branches:
      - 'main'

permissions:
  id-token: write
  contents: read

jobs:
  aws-oidc:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set environment variables based on branch
        id: set-vars
        run: echo "ASSUME_ROLE=${{ secrets.AWS_ROLE_ARN }}" >> $GITHUB_ENV

      - name: Debug Variables
        run: echo "ASSUME_ROLE=${{ env.ASSUME_ROLE }}"

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-1
          role-to-assume: ${{ env.ASSUME_ROLE }}

      - name: Print Hello World plan
        run: echo "Hello, Plan"
```

![github-actions1002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/93064044-c021-4e59-90f4-b8c0d0e9155b.png)

ポップアップが表示されるので **[Commit changes]** をクリックします。

![github-actions1003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/e6e070a2-cdf6-467e-9758-2610f5092432.png)

すると Workflow が実行されるため **[Create blank.yml]** をクリックします。

![github-actions1004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/abcb510b-6a70-4f30-b0cb-a2f8fc8ee966.png)

**[aws-oidc]** というのをクリックします。

![github-actions1005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/89b2f3da-081d-40dc-90a6-45b3206cf16e.png)

**Configure AWS Credentials** という部分をクリックすると実行ログが確認できます。

![github-actions1006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/51bafab8-1bc9-4b7a-866e-c2a945312b5f.png)

AWS 側で作成した **GiHubActions** のロールが **assumedRoleId** として確認できます。

![github-actions1007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/079053e4-ee4d-4c64-ad24-79812769db09.png)

次に以下の部分を修正します。

```yml:修正前
      - name: Print Hello World plan
        run: echo "Hello, Plan"
```

```yml:修正後
      - name: AWS CLI
        run: aws s3 ls
```

先ほどは AWS 認証が完了した後に `Hello, Plan` と表示させるだけの内容でしたが、今度は Amazon S3 のバケット一覧を取得するためのコマンドになります。

先ほどの手順を参考に改めて実行ログを確認します。
今度は **AWS CLI** という履歴があるためそこをクリックしログを確認します。

![github-actions1008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/9a306aee-d5be-445e-afd1-f64ce2f7fcaf.png)

S3 バケット一覧が出力され、先ほど OIDC 認証した権限で AWS 環境へアクセスできていることが確認できます。


# おわりに
今回は AWS への OIDC 認証にスポットを当てた内容でしたが、terraform の利用や yml の説明といった GitHub Actions を活用した内容について書いtければと思います。


### 参考
https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

https://docs.github.com/ja/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions