🚀

GitHub ActionsにてOIDCを使ってECRへpush/S3へアップロードを行う!

2024/08/13に公開

はじめに

個人開発にてReact(s3)、Rails(ECS)の構成でアプリケーションを作成しており、CICDを作るにあたってGitHub Actionsではフロント側はs3へsync、バックエンドはコンテナイメージをpushしたい要件があり実際の作業内容を備忘録として記事にすることにしました。
また今回調べているとOIDC(OpenID Connect)という仕組みを使ってセキュアに実装できることがわかったためOIDCを利用することとしました。

そもそもOIDCとは

ChatGPTに聞いてみました

AWSにおけるOIDC(OpenID Connect)は、外部のアイデンティティプロバイダー(IdP)を利用して、AWSリソースへのアクセスを制御するための標準プロトコルです。OIDCは、OAuth 2.0の上に構築された認証レイヤーで、認証(ユーザーの識別)と認可(アクセス権の付与)の両方をサポートします。

OIDCの概要
認証プロトコル: OIDCは、OAuth 2.0をベースにしており、ユーザーが外部のIdP(例えば、Google、GitHub、Oktaなど)を使用して認証できるようにします。
トークンベースの認証: 認証が成功すると、IdPはIDトークン(JWT形式)を発行します。このトークンには、ユーザー情報や認証情報が含まれています。

別プロバイダー(別サービス)からAWSにアクセスする際にそのプロバイダーに対しIAM権限を付与できるといったところでしょうか。

AWSコンソールにて設定

https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-aws#3.-github-actions-で-oidc-を使用して-aws-認証を行う

上記記事を参考に作成しました。

IDプロバイダの作成

AWSコンソール->IAM->サイドメニュー/プロバイダ->プロバイダの作成より以下のように設定しました。

  • プロバイダの設定
    • プロバイダのタイプ: OpenID Connect
    • プロバイダの URL: https://token.actions.githubusercontent.com
    • 対象者: sts.amazonaws.com

ロールの作成

AWSコンソール->IAM->サイドメニュー/ロール->ロールの作成より遷移

  • 信頼されたエンティティタイプ:カスタム信頼ポリシー
  • カスタム信頼ポリシーは以下を参考に設定
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::{AWSアカウントID}:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
                    "token.actions.githubusercontent.com:sub": "repo:{GitHubのユーザー名}/{リポジトリ名}:ref:refs/heads/{ブランチ名}"
                }
            }
        }
    ]
}
  • 許可を追加
  • 以下を追加
    • AmazonEC2ContainerRegistryPowerUser
    • AmazonS3FullAccess

上記を設定しロールを作成

GithubActions作成

GithubActions内のsecretsに関して

  • GithubActionsにて外部に晒したくない情報は秘匿情報として管理できます。
  • GitHubのリポジトリ->settings->サイドメニュー->Secrets&Variable->Actionsより以下のような画面へ遷移できます。
  • 追加を行う際はNew Repositorysecretより行います。

AWSへの認証

GithubActions内のAWSの認証はとてもシンプルです。
usesにてaws-actions/configure-aws-credentials@v1を指定し、role-to-assumeにて作成したロールのARNを指定してあげるだけです。

~
- uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-region: ap-northeast-1
    role-to-assume: 'arn:aws:iam::{AWSアカウントID}:role/{作成したロール名}'
~

また注意するポイントとしてpermittionsにて以下のように設定をしないとエラーになるため、気をつける必要があります

~
permissions:
    id-token: write
    contents: read
~

S3へビルドしたReactプロジェクトをsyncコマンド実行しアップロード

以下はReactプロジェクト用のものです。working-directory等はよしなに置き換えてください

name: Deploy React App

on:
  push:
    branches:
      - main

jobs:
    deploy:
        runs-on: ubuntu-latest
        permissions:
            id-token: write
            contents: read
        steps:
            - name: Checkout
              uses: actions/checkout@v3
            
            - uses: aws-actions/configure-aws-credentials@v1
              with:
                aws-region: ap-northeast-1
                role-to-assume: 'arn:aws:iam::{AWSアカウントID}:role/GithubActionsRoleforASS'

            - name: Set up Node.js
              uses: actions/setup-node@v3
              with:
                  node-version: '16.15.1'
            
            - name: Install modules
              run: npm ci
              working-directory: ./frontend/app
            
            - name: Build application
              run: npm run build
              working-directory: ./frontend/app
            
            - name: Deploy to S3
              run: aws s3 sync --delete ./build/ s3://${{ secrets.BUCKET_ID }} --region ap-northeast-1
              working-directory: ./frontend/app
     

ECRリポジトリへコンテナイメージのpush

上記同様working-directory等はよしなに置き換えてください

name: Push ECR for Rails and Nginx

on:
  push:
    branches:
      - main

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

        steps:
            - name: Checkout
              uses: actions/checkout@v3 
            
            - uses: aws-actions/configure-aws-credentials@v1
              with:
                aws-region: ap-northeast-1
                role-to-assume: 'arn:aws:iam::{AWSアカウントID}:role/GithubActionsRoleforASS'

            - name: Login ECR
              run: |
                aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${{ secrets.AWS_ECR_ENDPOINT }}

            - name: Image Build & Push to Rails ECR
              env:
                RAILS_REPOSITORY: "{Rails用ECRリポジトリ名}"
                IMAGE_TAG: latest
              run: |
                docker build --no-cache -f ./docker/staging/Dockerfile --platform linux/amd64  -t ${{ env.RAILS_REPOSITORY }} .
                docker tag ${{ env.RAILS_REPOSITORY }}:latest 730335441282.dkr.ecr.ap-northeast-1.amazonaws.com/${{ env.RAILS_REPOSITORY }}:${{ env.IMAGE_TAG }}
                docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/${{ env.RAILS_REPOSITORY }}:${{ env.IMAGE_TAG }}
              working-directory: ./backend

            - name: Image Build & Push to Nginx ECR
              env:
                NGINX_REPOSITORY: "{Nginx用ECRリポジトリ名}"
                IMAGE_TAG: latest
              run: |
                docker build --no-cache --platform linux/amd64 -t ${{ env.NGINX_REPOSITORY }} .
                docker tag ${{ env.NGINX_REPOSITORY }}:latest 730335441282.dkr.ecr.ap-northeast-1.amazonaws.com/${{ env.NGINX_REPOSITORY }}:${{ env.IMAGE_TAG }}
                docker push {AWSアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/${{ env.NGINX_REPOSITORY }}:${{ env.IMAGE_TAG }}
              working-directory: ./nginx

上記ではRails用のイメージとリバースプロキシ用のNginxのイメージをまとめて、ビルド・タグつけ・pushを行なっています。

終わりに

OIDCと聞くとすごく複雑なイメージがあり少し敬遠していましたが使ってみるとシンプルでとても使いやすいと実感できました。別プロバイダとAWS間でやりとりを行う際は積極的に使っていきたいと思います!

Discussion