『microCMS + Gatsby + GitHub Actions + S3 でJamStackのチュートリアル』 をやって詰まった所を補足してみる

これは何?

dev.classmethod.jp

上記の記事を試しにやってみたんだけど、あれこれどうすんだっけ?みたいなのあったので、それの備忘録を書いてみる。

僕のスキルセット

  • バックエンド領域を専門とするエンジニアなのでフロントは業務でやってない
  • JamStack 初めて構築する
  • Github Actions 使った事ない(CircleCIとかはある)
  • microCMS 初めて触る

こんな感じ。

何やったの?

  • npm じゃなくて yarn で進めた
  • gatsby-cli を作る階層をルートディレクトリにしてそのサブディレクトリ内に Gatsby の Project を作った
    • で、上記を全てGit管理対象とした
  • Github Actions の yml を npm からyarn に変えた
  • S3にsyncをする所で IAM AccessKeyのPermissionをなるべく最小になるようにしてみた

という事で、大体把握しながら、ちょこちょこ書き換えてみたので共有します。

ちなみに作業用レポジトリは以下です。

github.com

npm じゃなくて yarn で進めた

ある凄いエンジニアの方に yarnはnpmと互換があってyarnの方が速いんだよ って言うのを教わった事があった。

じゃあ、まあ出来る限り yarn 使えばいいんでしょ、みたいな気持ちで最近良く使ってる。(w)

何が良いのか?みたいなのは以下のエントリが参考になったので貼っておく。

qiita.com

ics.media

で、まあ、記事中の npm install -g gatsby-cli とか npm install --save gatsby-source-microcms とかは yarn add gatsby-cli とか yarn add gatsby-source-microcms に読み替えて実行した。

gatsby-cli を作る階層をルートディレクトリにしてそのサブディレクトリ内に Gatsby の Project を作った

これは 作業レポジトリの レポジトリ構成にもメモってる。

./
├my-example/ ...①
│├package.json
│├yarn.lock
│└manage.py
├package.json
├yarn.lock ... ②
└README.md

今回のプロジェクトは gatsby-cli のインストールが必須で、記事内では グローバルインストールする事が推奨されているけど、自分が出来る限り グローバルインストールしたくなく。。(´・ω・`)

レポジトリのルートディレクトリに gatsby-cli をインストールするだけのディレクトリを切って、その後で、サブディレクトリとして Gatsby のプロジェクトを作ったので、上記に紹介したような作業ディレクトリになってる。(後で困る事が分かる)

Github Actions の yml を npm からyarn に変えた

yarn と npm は互換があるので、問題ないんだけど、元々 yarn でやってた事もあるので Github Actions 側でも合わせた。

yaml の diff でいうとこれくらい。

# This is a basic workflow to help you get started with Actions

name: publish

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  repository_dispatch:
    types: [dispatch_cms]    

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: setup node
        uses: actions/setup-node@v1
        with:
          node-version: '14.x'
      - name: install modules
-         run: npm install
+         run: yarn
      - name: build gatsby
-         run: npm run build
+         run: yarn build
          env:
            X_API_KEY: ${{ secrets.X_API_KEY }}
            SERVICE_ID: ${{ secrets.SERVICE_ID }}
      - 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
      - name: Upload file to S3
        env: 
          S3_CONTENTS_BUCKET: ${{ secrets.S3_CONTENTS_BUCKET }}
        run: |
          aws s3 sync ./public s3://$S3_CONTENTS_BUCKET/ --quiet

... ちなみに、 サブディレクトリを切った事もあってこれじゃ動かなかった。

なので、最終的に以下のようにしてる。

# This is a basic workflow to help you get started with Actions

name: publish

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  repository_dispatch:
    types: [dispatch_cms]    

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: setup node
        uses: actions/setup-node@v1
        with:
          node-version: '14.x'
      - name: install modules
-         run: npm install
+         run: yarn
+         working-directory: ./my-example
      - name: build gatsby
-         run: npm run build
+         run: yarn build
          env:
            X_API_KEY: ${{ secrets.X_API_KEY }}
            SERVICE_ID: ${{ secrets.SERVICE_ID }}
+         working-directory: ./my-example
      - 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
      - name: Upload file to S3
        env: 
          S3_CONTENTS_BUCKET: ${{ secrets.S3_CONTENTS_BUCKET }}
        run: |
-           aws s3 sync ./public s3://$S3_CONTENTS_BUCKET/ --quiet
+           aws s3 sync ./my-example/public s3://$S3_CONTENTS_BUCKET/ --quiet

いやぁ。。盲点だった(笑)

ちなみに、npm から yarn に変えたら 1分57秒1分33秒 くらいになった。 yarn のメリットの一つでもある 一回ダウンロードしたライブラリはキャッシュするの恩恵を受ける事がなくなるので、そこはまあ劇的に変化するとかは無さそうかな、って気もする。

S3にsyncをする所で IAM AccessKeyのPermissionをなるべく最小になるようにしてみた

Secrets 管理とはいっても Public レポジトリ内の機能で管理するので何かあった時のリスクはなるべく下げて運用したい。

ので、IAMキーのアクセスを制限した。

dev.classmethod.jp

最終的に Github Actions 内で s3 sync するのでそれに必要な権限だけ付与する。 つまり、 s3:ListBuckets3:PutObject の2種類。 

最初、 GetObjectPutObjectDeleteObject の3つを雰囲気で設定してました。 こういうの学んんで行かないとだね。

まとめ

IAM 管理難しいなぁ。