Honai's Blog

GitHub Actions を使って AWS S3 に自動デプロイする

2019/10/29

パブリックベータになった GitHub Actions を使ってみたので、そのメモ。かなり雑なのはお許しください。

前提

公開したい Web のプロジェクトがあり、yarn build とかで静的に書き出せる状態。 そもそもビルドする必要もない(HTML ファイルと CSS ファイルだけ、など)プロジェクトにももちろん使えます。

プロジェクトを GitHub で管理し、GitHub にプッシュした時に自動でビルドと S3 へのデプロイ(アップロード)がされるようにします。

S3 バケット作成

Amazon S3 での静的ウェブサイトのホスティング - Amazon Simple Storage Service

↑ 概要説明。と各ドキュメントへのリンクが書いてあります。サーバーサイドのスクリプトは実行できない・独自ドメインを設定できる・HTTPS 通信をサポートしていない、など、Web サイトを S3 で公開するにあたって重要なことも書いてあります。

例: 静的ウェブサイトをセットアップする - Amazon Simple Storage Service

↑ (かなり大雑把な)チュートリアルです。

IAM 設定

GitHub Actions から S3 のバケット内のファイルを読み書きするには、適切にアクセス許可をする必要があります。

今回は、CLI から AWS サービスにアクセスする「ユーザー」と、アクセス権限が記述された「ポリシー」を作成して、ユーザーにポリシーを結びつけることで、GitHub Actions から S3 の読み書きができるようにします。

ポリシーの作成

AWS コンソールにサインインして、サービスから Identity and Access Management (IAM)を選びます。「ポリシー」→「ポリシーの作成」。

IAMのコンソール画面

次の画面では、サービス名などを検索して GUI で権限を設定するか、JSON で設定を直接記述することができます。

s3 sync に必要なアクセス権限 - Qiita

今回はこのサイトを参考に、Delete の権限も追加して次のような JSON を設定しました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::[バケット名]",
                "arn:aws:s3:::[バケット名]/*"
            ]
        }
    ]
}

[バケット名] の部分は先ほど作成したバケットの名前を入れてください。

続く確認画面で、ポリシーの名前を決めて入力し、ポリシーを作成します。

ユーザーの作成と権限付与

同じく IAM の管理画面から「ユーザー」→「ユーザーを追加」

IAMのコンソール画面

ユーザー名を決めて入力し、「アクセスの種類」は「プログラムによるアクセス」を選びます。続く「アクセス許可の設定」では「既存のポリシーを直接アタッチ」で、先ほど作成したポリシーの名前を検索して適用します。

タグの設定はスキップし、最後に Access Key ID/Secret Access Key と、それらが記述された CSV のダウンロードボタンが表示されるので、コピーするなりダウンロードするなりして必ず控えておきましょう(Secret は 2 度と表示させることはできませんが、キーのペアを後から作成しなおすことはできます)。S3 のバケットの読み書きができるキーペアなので、扱いは慎重に。

GitHub Actions の設定

Features • GitHub Actions

Actions はベータ機能なので、普通の GitHub アカウントでは有効化されていません。上記のページから申請してください(筆者の場合は Sign-up をクリックしてすぐに使えるようになりました)。

シークレットの作成

先ほど控えた IAM ユーザーの 2 つのキー(Access Key ID/Secret Access Key)を、GitHub Action 内で使える暗号化された変数として利用します。

GitHub Actions の仮想環境 - GitHub ヘルプ # シークレット(暗号化された変数)の作成と使用

公開したいプロジェクトのリポジトリの「Settings」→「Secrets」から、2 つのキーを登録します。名前は AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY などがわかりやすいと思います。

設定の YAML を書く

私は JSON に慣れてしまっているので、たまに YAML を書くと混乱します。プッシュする前にせめて文法だけでも YAMLlint - The YAML Validator などでチェックしておくといいかもしれません。

GitHub Actions の利点の 1 つは、デプロイなどのワークフローのすべてを 1 から記述しなくても、他の開発者が用意した部品(Action)に変数を流し込んで、組み合わせて使うことで、複雑な手順でも簡単に記述できることです。 GitHub Actions に公式(?)のワークフローやスターター、ツールキットがまとまっており、この Organization 内のリポジトリ以外にも、一般ユーザーが作成した部品を使うこともできるようです。

今回は公式の部品から checkoutsetup-nodeaws/cli の 3 つを利用します。

公開したいプロジェクトのルートに .github 、その中に workflows というディレクトリを作り、 deploy-s3.yml など拡張子が yml のファイルを作成します。

Github Actions のヘルプ や各 Actions の README などを参考に、次のような Workflow の設定を記述しました。

name: Upload to S3
on:
  push:
    branches:
      - master

jobs:
  deploy:
    name: Build & Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions/setup-node@master
        with:
          node-version: 10.x
      - run: yarn install
      - run: yarn build
      - uses: actions/aws/cli@master
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
        with:
          args: s3 sync dist/ s3://[作成したバケット名] --delete

2 行目の on: はデプロイを走らせるタイミングを記述しています。 master ブランチにプッシュされたときに走るようにしました。 この Workflow は 1 つのジョブ deploy (Build & Deploy) から成ります。次の 5 つの step を実行します。

  • master ブランチにチェックアウト
  • node の環境をセットアップ
  • yarn install
  • yarn build
  • dist ディレクトリの中身を AWS S3 にアップロード (Sync)

ビルド時のコマンドや公開するディレクトリなどは適宜読み替えてください。

AWS CLI のドキュメントのリンクを貼っておきます s3 — AWS CLI 1.16.263 Command Reference

まとめ

何となくコピペを組み合わせて書いた YAML なので、Job を分割したり名前をちゃんと付けたりしたほうがいいとは思いましたが、とりあえずやりたいことはできました。他の人が作ったワークフローの部品を組み合わせて使えるというのは、GitHub らしいし便利だなと感じました。

記事を読んでくださったみなさんの参考になればうれしいです。