AppService + microCMS + Gatsby + GitHub ActionsでJamstackのチュートリアル

[求ム！Cloud Nativeアプリケーション開発のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-cloudnative) の16日目の記事です。

#はじめに
本稿では、今流行のJamstack構成のブログサイトをAzure App Service上に構築してみます。

#概要
今回のソースコード： https://github.com/kano4/jamstack_app
####今回作るサイトの構成
下記サービスを使用してJamstack構成のブログサイトを構築していきます。
- Headless CMS : [microCMS](https://microcms.io/)
- CI : [GitHub Actions](https://github.co.jp/features/actions)
- Source repository : [GitHub](https://github.co.jp/)
- Site generator : [Gatsby.js](https://www.gatsbyjs.com/)
- Hosting : [Azure App Service (Static Web Apps)](https://azure.microsoft.com/ja-jp/services/app-service/static/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/9c89f8a9-c838-f301-c75b-3c46d5b7e34a.png)

####全体の流れ
1.記事をPOST
最初に、記事投稿者がHeadless CMSに記事をPOSTします。
2.通知
Headless CMSに記事がPOSTされたタイミングで、CIへ通知が行われます。
3.ビルド
CIは通知を受けると、ビルドを行います。
4.デプロイ
ビルドされたサイトをHostingにデプロイします。

#事前準備
- Azureアカウント
- GitHubアカウント
- microCMSアカウント

##microCMSの準備
1.「news」APIを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/316d1d07-f76c-0c45-a12e-cb2ff5b24480.png)
2.APIの型を選択します。今回は「リスト形式」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/2acbca5d-588a-729e-4d8b-78d9b76063e0.png)
3.APIスキーマを設定します。今回はtitleとbodyを追加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/24d5c674-b441-52c5-362d-56e98b02bd15.png)
4.HTTPメソッドを設定します。今回はPOSTを有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/9f6704c8-286b-6775-525b-0f23644d7ece.png)
5.API-KEYを確認します。ここで表示されるX-API-KEYとX-WRITE-API-KEYは後ほど使用するのでメモしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/0f7abfe5-603e-6779-47f3-3129b86a6b3b.png)
6.ターミナルからcurlコマンドで記事をPOSTしてみる。

```
% curl -X POST "https://<サービス名>.microcms.io/api/v1/news" -H "Content-Type: application/json" -H "X-WRITE-API-KEY: <API KEY>" -d "{\"title\":\"タイトルその１\",\"body\":\"内容その１\"}"
```

7.管理画面で登録したデータを確認します。6でPOSTしたデータが表示されればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/98c48e8b-8915-8855-4cf8-dbc6ca46e5ad.png)

##Gatsby.jsの準備
1.まずはnpmでcliをインストールし、gatsby newコマンドで新規アプリを作成します。

```
% npm install -g gatsby-cli
% gatsby new my-example
```

2.作成したアプリに移動して、gatsby developコマンドで起動します。

```
% cd my-example
% gatsby develop
```

3.起動後localhost:8000でデフォルトページが表示されることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/e9aa81ff-f6ff-0561-364b-f1ad38458592.png)

4.microCMSと連携させるためのpluginと、API KEYなどの環境変数を簡単に扱うためのdotenvモジュールをインストールします。

```
% npm install --save gatsby-source-microcms
% npm install --save dotenv
```

5.gatsby-configに下記設定を設定を行います。

```my-example/gatsby-config.js
//dotenvで環境変数セット
require("dotenv").config({
 path: `.env.${process.env.NODE_ENV}`,
});

module.exports = {
  siteMetadata: {
    title: `Gatsby Default Starter`,
    description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
    author: `@gatsbyjs`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
    //ここの設定を追加する
    {
      resolve: "gatsby-source-microcms",
      options: {
        apiKey: process.env.X_API_KEY,
        serviceId: process.env.SERVICE_ID,
        apis: [{
          endpoint: 'news',
        }],
      },
    },
  ],
}
```

6..env.developmentファイルを新規作成してIDやKEYを記述します。

```my-example/gatsby-config.js
SERVICE_ID=<microCMSで設定したサービスID>
X_API_KEY=<microCMSのX_API_KEY>
```

7.microCMSから取得した記事を表示できるように、news.jsを新規作成します。

```my-example/src/pages/news.js
import React from "react"
import { graphql　} from "gatsby"

import Layout from "../components/layout"
import SEO from "../components/seo"

const NewsPage = ({ data }) => (
 <Layout>
   <SEO title="ニュース" />

   {data.allMicrocmsNews.edges.map(edge => {
     const news = edge.node

       return (
        <React.Fragment key={news.id}>
         <div>
             <h2>{news.title}</h2>
         </div>
         <div>
            {news.body}
         </div>
        <hr />
       </React.Fragment>
       )
   })}
 </Layout>
)

export const query = graphql`
 {
    allMicrocmsNews(
     sort: { fields: [id], order: DESC }
   ) {
     edges {
       node {
         id
         title
         body
       }
     }
   }
 }
`

export default NewsPage
```

8.再度developコマンドを実行して、今度はlocalhost:8000/newsにブラウザでアクセスします。さきほどmicroCMSに登録したデータが表示されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/5d053c67-5e1f-0eb8-169f-6c22a3589fd9.png)


##GitHubの準備
1.GitHubにリポジトリを作成します
2.作成したリポジトリに、Gatsbyで作成したアプリをpushします

##Azure App Serviceの準備
1.Static Web App(静的 Web アプリ)を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/d847b0c0-108e-4a50-6b82-2be8806b7475.png)
2.Static Web App(静的 Web アプリ)で必要な情報を入力します。ここで、リポジトリには先ほどGitHubに作成したリポジトリを選択します。また、ビルドのプリセットにはGatsbyを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/0ff42bad-3be8-a6ce-6682-878f8c5a7d06.png)
3.GitHubのリポジトリを確認すると、.github/workflows/azure-static-web-apps-***.ymlが自動で追加され、さらにGitHub Actionsが実行されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/df33609a-6c4f-e120-d83e-dcd2d38072b6.png)

##GitHubの設定
1.Secretsに、SERVICE_IDとX_API_KEYを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/d2aba2f3-a73d-8011-b26f-c8f79b360da0.png)

##microCMSとGitHub Actionsの設定
1.Githubでアクセストークンを発行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/eb64c5f0-1b39-3c5a-6196-9d65d913ff63.png)

2.microCMSのWebhook機能を使い、POST /news　のタイミングでGithub Actionsを実行するように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/987708b0-1d5d-8145-c2c7-40e3a4d38592.png)

3..github/workflows/azure-static-web-apps-***.ymlを編集します。
例：[ソースコード](https://github.com/kano4/jamstack_app/blob/master/.github/workflows/azure-static-web-apps-lively-island-0048eb910.yml)

##試してみる
上記で準備は終わりです。
最後に、ターミナルからcurlコマンドで新たに記事をPOSTしてみます。

```
% curl -X POST "https://<サービス名>.microcms.io/api/v1/news" -H "Content-Type: application/json" -H "X-WRITE-API-KEY: <API KEY>" -d "{\"title\":\"タイトルその２\",\"body\":\"内容その２\"}"
```

記事をPOSTすると、GitHub Actionsが実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/aabb5c64-5a45-1e63-f95e-ff27d2adb32e.png)

そして、Azure上の Web Appsにアクセスすると、下記のページが表示されることを確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556/6a84d1ee-e482-eb91-ab95-b24d7541d6d2.png)


#まとめ
今回は現在流行りのJamstack構成のブログサイトを App Service 上に作成してみました。少しでもこの記事が多くの人の参考になれば幸いです。また、自分で実際に色々試してみて、技術の進化を強く感じることができました。

#参考
- [Jamstackとは何を指すのか今一度考えてみる](https://microcms.io/blog/what-is-jamstack/)
- [microCMS + Gatsby + GitHub Actions + S3 でJamStackのチュートリアル](https://dev.classmethod.jp/articles/jamstack-tutorial/)
- [Get started with GitHub Actions and App Service](https://azure.github.io/AppService/2020/04/14/Get-Started-with-GitHub-Actions-and-Azure-Webapps.html)
- [microCMSのコンテンツを更新したら、WebhookでGitHub Actionsを実行する](https://kimulaco.com/post/microcms-webhook-to-github-actions/)
- [Gatsby と Azure Static Web Apps で静的 Web アプリを作成して発行する](https://docs.microsoft.com/ja-jp/learn/modules/create-deploy-static-webapp-gatsby-app-service/)
- [Azure App Service に Static Web Apps が登場！](https://k-miyake.github.io/blog/appservice-static-webapps/)