GithubActionsでOpenAPIをS3へアップロードしホスティング


やりたいこと

  1. GithubのmainブランチへOpenAPIのyamlをpushするとGithubActions起動
  2. redoc-cliが動作。yamlhtmlを生成
  3. s3バケットへhtmlをコピー
  4. s3を参照しOpenAPIがブラウザ上から見れるように

構築手順

s3バケット作成とサイト確認

CloudShell
# バケット作成
$ aws s3 mb s3://<<バケット名>>
make_bucket: <<バケット名>>

# for-test-pageバケットのアクセスブロックを設定し、公開できる状態に
$ aws s3api put-public-access-block --bucket <<バケット名>> --public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"

# 設定の反映を確認
$ aws s3api get-public-access-block --bucket <<バケット名>>
{
    "PublicAccessBlockConfiguration": {
        "BlockPublicAcls": false,
        "IgnorePublicAcls": false,
        "BlockPublicPolicy": false,
        "RestrictPublicBuckets": false
    }
}
  • バケットポリシー用のjson作成
bucket-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<<バケット名>>/*"
        }
    ]
}
CloudShell
# バケットポリシーのアタッチ
$ aws s3api put-bucket-policy --bucket <<バケット名>> --policy file://bucket-policy.json
  • 本来Redocになるapp.htmlをホスティング確認のため適当な中身を作りs3へ手動アップロードして確認します
app.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
            <title>test page</title>
    </head>
    <body>
        This is test page
    </body>
</html>

CloudShell
# s3 アップロード
$ aws s3 cp app.html s3://<<バケット名>>/app.html
upload: ./app.html to s3://<<バケット名>>/app.html
  • アップロードされたファイルが確認できました

GithubActions動作用IAMユーザー作成

CloudShell
# user作成
$ aws iam create-user --user-name <<ユーザー>>
# キー発行
$ aws iam create-access-key --user-name <<ユーザー>>
user-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}
CloudShell
# ポリシーの作成
$ aws iam create-policy --policy-name openapi-test-policy --policy-document file://user-policy.json
# ポリシーのアタッチ
$ aws iam attach-user-policy --user-name <<ユーザー>> --policy-arn arn:aws:iam::****:policy/openapi-test-policy

Githubのリポジトリ作成、プロパティへIAM情報をシークレットへ登録


GithubActions作成

  • .github/workflows
deploy_openapi.yaml
name: OpenAPI Build and Push HTML to S3

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: ["12.x"]
    steps:
      - name: Checkout # 最新コードの取得
        uses: actions/checkout@v2

      - name: node setting # Redocでnpmを使うのでNodeの設定
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node }}

      - name: install redoc # Redocのインストール
        run: npm install -g redoc-cli

      - name: build openAPI file # OpenAPIの定義をHTMLに変換
        run: redoc-cli bundle ./openapi.yaml --output app.html # プロジェクトのディレクトリに合わせて変更してください。

      - name: Output file contents # 問題があった場合に確認するために中身を出力
        run: cat ./app.html

      - name: Configure AWS credentials # S3にファイルを配置するために権限の設定
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_DEV_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_DEV_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: S3 copy # 生成したHTMLファイルをS3に配置する
        env:
          S3_BUCKET_NAME: ${{ secrets.AWS_DEV_BUCKET_NAME }}
        run: aws s3 cp ./app.html s3://$S3_BUCKET_NAME/app.html

動作確認

  • 適当なOpenAPIファイルを作成しmastergit push
  • GithubActionが動き出す

  • s3にファイルがアップロードされ、ReDocがみえることを確認

最後に

OpenAPIは見えるようになりました。
2つ課題は残っていて、いずれ解決したいなと思います。
- s3の前にCloudFrontを立てて署名付きURLに
- ベーシック認証をつけてアクセスを制御
- バケットポリシーにIP制限つけるのもあり

ベーシック認証を追加し改善を行ないました。