OpenID Connect & GitHubActionsでS3へデプロイ


# 概要

:::note info
* mainブランチにPushしたらS3へ自動にデプロイする
* GitHub側にSecret変数でAWS認証キーを持たせたくない
* 認証はOpenIDConnect認証の仕組みを利用
* 権限は設定済のRoleに自動的に移譲される
:::

# 前提

:::note info
* OpenIDConnectProvider認証可能な環境
    * 本投稿の環境は前記事である[こちら](https://qiita.com/ezaqiita/private/681ec6474d61a12056df)の続き
* AWS環境は親アカウントと子アカウントからなるクロスアカウント
* IAMでAssumeRole可能な環境
* GitHubActionでCI可能な環境
* S3が静的ホスティング可能な環境
:::

# 詳細

## ポリシー作成

* 後で割り当てるロール用にポリシーを作成
* 例としてサーバレス環境向けの権限をまとめたポリシーを作成
* S3にデプロイするのでS3権限は付与しておくこと
* ポリシー名は"hoge-dev-policy-lambda-oidc"とする

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/4b3b5b07-9f4f-079f-c51d-f4c585630f45.png" width=90%>

* タグ作成はスキップ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/4207000f-b17f-d289-1db6-c98d3d469a41.png" width=90%>

* ポリシー作成完了

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/ae84190f-4957-7ea4-ac93-f777f1e82a06.png" width=50%>

## ロール作成

* ウェブアイデンティティを選択
* アイデンティティプロバイダーは以前作成したものを選択
* Audienceは"sts.amazonaws.com"を選択

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/fc97ce4d-e687-25c4-62b8-ec6ec5b9db62.png" width=90%>

* 前段で作成したポリシーを選択

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/4873b60a-c932-f5cd-290f-2b418f480418.png" width=90%>


* ロールの作成を完了する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/38fdd9e8-e078-28e0-3f75-01744c3435cd.png" width=90%>

* 作成したロールのARNを控える

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/7df79685-8a88-aaea-c1a2-a4446fff6ae3.png" width=90%>

* [GitHub公式Workflow参考](https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)


## バケットポリシー作成

* 公開状態にしておく
* 以下のようにIPアドレス制限も設定しておく

```バケットポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::dev-public-bucket/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "111.11.11.11/32",
                        "111.22.22.22/32",
                        "111.33.33.33/32"
                    ]
                }
            }
        }
    ]
}

```

## workflow作成

* "role-to-assume"には前段で控えたARNを入力

```test-ci.yml
name: test-ci
on:
  push
env:
  BUCKET_NAME : test-public-bucket
  AWS_REGION : ap-northeast-1    
permissions:
      id-token: write
      contents: read
jobs:
  S3PackageUpload:
    runs-on: ubuntu-18.04
    steps:
      - name: Git clone the repository
        uses: actions/checkout@v1
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@master
        with:
          role-to-assume: arn:aws:iam::39**********:role/dev-role-oidc
          role-session-name: samplerolesession
          aws-region: ${{ env.AWS_REGION }}
      # Upload a file to AWS s3
      - name:  Copy documents to s3
        run: |
          aws s3 cp ./index.html s3://${{ env.BUCKET_NAME }}/
```

## デプロイ

* .github/workflows配下にworkflowファイルを配置
* 同リポジトリ内のファイルを更新しCommit/Push

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/76945ab8-5756-a6c6-929a-bffa9ce71e28.png" width=80%>

* GitHubActions側で問題なく認証をパスし処理が実行される事を確認
* S3にファイルがデプロイされている事を確認

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/008dde1c-a3ae-3400-10a6-3ea691f84823.png" width=90%>

* S3プロパティから静的ホスティングのアドレスを確認
* アクセス可能である事を確認

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/48cf0cd2-4db4-a60f-abc0-d99ab7021a03.png" width=70%>

# まとめ

* このようにGitHubにSecretの変数で認証キーを持たせなくても、よりセキュアにGitHubからAWSへの認証・デプロイが実現可能