浜松市版新型コロナウイルス対策サイトをAWSで運用する方法

## はじめに
浜松市 新型コロナウィルス感染症対策サイトのお手伝いをしています。
浜松市では市内で ~~2020/3/29~~ 2020/3/28 に初の感染者が確認されてから、市内外のITコミュニティ有志により東京都の[新型コロナウィルス感染症対策サイト](https://stopcovid19.metro.tokyo.lg.jp/)をForkして4/1から公開を始めました。

[浜松市 新型コロナウィルス感染症対策サイト](https://stopcovid19.code4hamamatsu.org/)



東京都のサイトはデザインや中に使用されている技術のみならずデプロイまでの運用についてもしっかり出来上がっている素晴らしいものなので地方で立ち上げる場合も非常に短時間で公開できました。
【静岡新聞】 [コロナ対策で新サイト　浜松市と市内ＩＴ関連有志](https://www.at-s.com/news/article/local/west/754950.html) 

これから同じように立ち上げようとする方のために主にデプロイに関しての解説をしたいと思います。

## 派生版を作成するには
派生版を作成する場合のノウハウについては主に下記のサイトにナレッジがまとまっていますのでこちらを参考にたちあげます。
[「東京都 新型コロナ対策サイト」地域展開に向けて情報共有のナレッジ](https://hackmd.io/@homata/ryHz3P4BI)

特に[派生版を作るときにまず、やることリスト](https://hackmd.io/@homata/ryHz3P4BI#%E6%B4%BE%E7%94%9F%E7%89%88%E3%82%92%E4%BD%9C%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AB%E3%81%BE%E3%81%9A%E3%80%81%E3%82%84%E3%82%8B%E3%81%93%E3%81%A8%E3%83%AA%E3%82%B9%E3%83%88)には技術的な記事以外にも行政とつながるための連絡方法なども書いてあるので一読することをお勧めします。

## 基本的なデプロイの仕組み

下表の左列に記載されたブランチが更新されると、ブランチとWebサイトの更新が自動的におこなわれます。
この自動化には[GutHub Actions](https://github.co.jp/features/actions)の機能が使用されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24418/96952aa1-7733-173e-fba5-180178744dcf.png)

すでに本家サイトに用意されたワークフローにより、下記の表にあるように
developmentブランチにpushされると`dev-pages`
stagingブランチにpushされると`gh-pages`
masterブランチにpushされると`production`
にHTMLがpushされます。

| ブランチ | HTML類がbuildされ、更新されるブランチ | 目的 |
| ---- | ---- | ---- |
|`development`|`dev-pages`|開発用サイト|
|`staging`|`gh-pages`|ステージングサイト|
|`master`|`production`|本番サイト|

buildで出来上がったファイルは以下のような構成になりますので本番公開するにはこのフォルダが **サイトのトップディレクトリ** になるように配置すればWEB公開されます。
https://github.com/tokyo-metropolitan-gov/covid19/tree/production

## GitHub Pagesで公開する方法
GitHub Pagesの公開機能を使用してそのままのドメインで公開しようとするとサブディレクトリになってしまいますので中で使用される相対パスがずれてしまい画像やJSが参照できず404になってしまいます。
例 https://tokyo-metropolitan-gov.github.io/covid19/
試してはいませんが、このフォルダがトップディレクトリになるようにカスタムドメインを設定すればGitHub Pagesでも公開できると思います。

GitHub Pagesで公開する場合は次の制限があります 「100GB bandwidth/month」「10 builds/hour」

## 自サイトやさくらインターネットVPSなどで運用する場合
上記で出来上がったproductionブランチのルート以下のフォルダを丸ごとWEBサーバーの公開フォルダにコピーします。
このフォルダが**サイトのトップディレクトリ** になるようにする必要があります。（試していないですが...多分）

さくらインターネットでは[新型コロナ情報まとめサイト向けのサーバーを無料提供](https://www.sakura.ad.jp/information/pressreleases/2020/03/23/1968203129/)のサポートを行っています。

## Netlifyで公開
東京サイトをはじめとして、多くの派生サイト（2020/4/13現在の浜松版も）では[Netlify](https://www.netlify.com/)を使用して公開されていることが多いです。
Netlifyの無料枠は「100GB bandwidth/month」「300 build minutes/month」になります。
また、COVID-19のサポートとして[こちら](https://covid19-support.netlify.com/)から申請することで2020/3より6か月間上記制限なしで利用することができます。

Netlifyを利用したデプロイはすでに以下のような記事が出ていますのでそちらを参考にするとよいと思います。
- [東京都新型コロナウイルス感染症対策サイトをforkしてnetlifyでdev環境を立ち上げる手順](https://tech.moyashidaisuke.com/entry/covid19-netlify)
- [（東京都 新型コロナウイルス感染症対策サイトで）Netlifyでデプロイプレビューを設定するとレビューが捗るよ](https://tech.moyashidaisuke.com/entry/netlify-deploy-preview)

## Amazon S3 で公開
**浜松版サイトではAWSからのサポートの提供の申し出があったため、現在のNetlifyでの公開を近日中にAWSを使用した公開に切り替える予定です。**

そこで、どのようにしてAWSにデプロイするかを記載します。
S3バケットの作成と、そのバケットの公開設定、バケットにアクセスするためのIAMユーザーの作成は済んでいる前提です。
初めての方は下記のサイトを参考にS3バケットを用意してください。

- [Amazon S3 での静的ウェブサイトのホスティング](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteHosting.html)
- [【初心者向け】S3でWebページを公開するための究極完全体マニュアル](https://qiita.com/UpAllNight/items/7add9831f379274c557c)

IAMユーザーには作成したバケットに対して読み書きができるような権限を与えておきます。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::[バケット名]/*",
                "arn:aws:s3:::[バケット名]"
            ]
        }
    ]
}
```
作成した`バケット名`と`リージョン`および、作成したIAMユーザーの `Access key ID` と `Secret_Access_Key` を後述するスクリプトで使用するため控えておいてください

## GitHub Actionsの設定

GitHub ActionsではGitHubレポジトリに対しての何らかのイベントをトリガーとして何らかのアクションを実行します。

- [GitHub ワークフローをトリガーするイベント](https://help.github.com/ja/actions/reference/events-that-trigger-workflows)
- [Github Actionsが使えるようになったので使ってみる](https://qiita.com/1915keke/items/8b18097d2981e88eca93)

GitHub Actionsのワークフローは .github/workflowsに入っており、主にCOVID-19サイトのデプロイに関するワークフローは以下のものが用意されています。

- developブランチにプッシュしたときにdev-pagesへデプロイするワークフローは`develop.yml`
- stagingブランチにプッシュしたときにgh-pagesへデプロイするワークフローは`staging.yml`
- masterブランチにプッシュしたときにproductionへデプロイするワークフローは`deploy.yml`

実行時には先ほど作成したIAMユーザーのACCESS_KEY_ID,SECRET_ACCESS_KEY が必要になります。
Forkしたブランチの[Settings]-[Secrets]にスクリプトに使用しているキーで保存しておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24418/382688e3-5581-3c22-54c7-4be6fbf2417c.png)

今回は、staging.ymlを修正してS3にデプロイする処理を加えます。(他のものも適宜ブランチ名、バケット名など変更すればOK)

``` yaml:.github/workflows/staging.yml
name: staging deploy

on:
  push:
    branches:
      - staging

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2

      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'

      - name: Cache dependencies
        uses: actions/cache@v1
        with:
          path: ~/.cache/yarn
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      - run: yarn install --frozen-lockfile
      - run: yarn run test
      - run: yarn run generate:dev --fail-on-page-error
      - run: "echo \"User-agent: *\nDisallow: /\" > ./dist/robots.txt"

      - name: deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

      # S3デプロイのために今回追加する箇所
      - name: deploy to s3
        uses: jakejarvis/s3-sync-action@master
        with:
          args: --acl public-read --follow-symlinks --delete
        env:
          AWS_S3_BUCKET: '用意したバケット名'
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: 'バケットがあるリージョン'   # 東日本ならば ap-northeast-1
          SOURCE_DIR: './dist'
```


## 完成イメージ

上記のワークフローファイルをコミットしてstagingブランチにプッシュすると、コミットしたワークフローが走り出し gh-pages と S3にデプロイされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24418/aaff39d1-1531-9761-4ce0-1e3168be7d13.png)

---
## 最後に
浜松市版新型コロナウイルス対策サイトの運営は東京サイトに比べて人数も少なく、特定の人にタスクが集中してしまう状況にあります。是非興味がありましたら気軽に下記のリンクから一緒に参加してみませんか？

浜松市 新型コロナウイルス対策サイト↓
~~https://stopcovid19-hamamatsu.netlify.com/~~
以下のURLに変更になりました
https://stopcovid19.code4hamamatsu.org/
GitHubリポジトリ
https://github.com/code-for-hamamatsu/covid19
Slack
https://join.slack.com/t/jaws-ug-hamamatsu/shared_invite/zt-dc5cgs87-cNw8QOxXeqhJnB8YB8A6Uw

## リンク
浜松市 新型コロナウイルス対策サイトのコントリビューター @w2or3w  さんの記事
静岡県オープンデータカタログ(csv)からCOVID-19対策サイトのデータ(json)に変換して取得するAPI
https://qiita.com/w2or3w/items/55ff3159aea0c7a9e096