はじめまして、志水です。
普段は主にAWSを利用したサービスの設計、構築、運用をして、プライベートでは妻や娘の障害対応を行うインフラエンジニアです。
最近JAMStackにふれる機会があり、まとめてみたいと思います。
フロント側の知識が乏しいので、ミスなどあれば教えて頂けると志水は喜びます。
CMSとは?
まずJAMStackを説明する前に、CMSについて説明します。
CMSとは、Content Management Systemの略で、ユーザが画像やテキストデータなどのコンテンツを管理し、テンプレートを用いて配信などを行うシステムになります。
よくブログや会社の公式サイトに利用されているものになります。
有名なサービスは下記になります。
- WordPress
- Movable Type
WordPressに至っては、彼ら曰くインターネット上のすべてのウェブサイトの40%を占めているそうで、非常にメジャーなサービスとなります。
CMSの一般的な構成
インフラとして知らないといけないのはサービスの構成かと思います。
CMSの構成としては様々あると思いますが、よくありそうな構成を上げてみます。
シンプルタイプ
まずはALL IN ONEタイプの構成です。
DBも全部1個のインスタンスに入れるタイプで、AWSであればAMIから作るとこのパターンになるかと思います。
簡単に作れる一方、運用するとなるとミドルアップデートや障害時の対応方法など少しやだなーと思う構成かなと思います。
また、サイトにアクセスする一般ユーザとコンテンツ修正を行うようなデベロッパーが同じ場所を見に行くので、セキュリティ的にも不安です。
冗長化タイプ
次に冗長化タイプですが、DBとしてAmazon Relational Database Service(以降RDS)を外出しにしてCMSサーバも複数台にして、その前段にロードバランサーとしてApplication Load Balancer(以降ALB)で負荷分散する構成です。
先程の構成のやなところを押さえた構成で、よくある構成かと思います。
ユーザとデベロッパーのアクセスする場所が違うのでセキュリティ的にも安心でき、かつDBも外に出ているので耐障害性やセキュリティの向上になります。
ただ、ユーザアクセスがCMSにダイレクトにくるので脆弱性の心配があるのと、DBに障害があると閲覧障害が出てしまうなどの不安もまだまだあります。
コンテンツ出力タイプ
最後にCMSのコンテンツ(HTML)を出力できるサービスやプラグインがあれば間にAmazon Elastic File System(以降EFS)を挟む下記のアーキテクチャが使えます。
CMSとWebを別にし、Webには別のロードバランサーを利用します。WebとCMSの間にEFSを挟み、出力したコンテンツをEFS経由でユーザに提供するパターンです。
ALB,Webの部分はCloudFront,S3に出来るタイプであれば、その方が良いですね。
こちらはCMSとWebを分離したので、ユーザからアクセスが来る部分にCMSが無くなり、よりセキュリティ的に向上しました。
しかし、こちらは静的サイト出力の対応するサービスでなければ構成出来ないです。
CMSのツラミ
ここまでで、いくつかの構成を紹介しましたが、CMSとして辛い部分は下記の通りになります。
- DBアクセスがあるため、表示時間がかかる
- 脆弱性対応大変
- ミドルウェアのアップデートが他に影響しないか心配
- DB管理したくない
脆弱性でいうと、WordPressは2020年で161件の脆弱性が発表されていて、2,3日に1件発表されているペースになります。
これに毎回対応するのも大変ですね(多くはプラグインなので、該当しないケースが多いかと思います)
ツラミの解決策
じゃあこのツラミをどう解決するかというと、静的化がその1つになります。
CMSの静的化
CMSを静的化するサービスやプラグインは昔から出てて、下記のようなサービスがあります。
ただ、WordPressしか使えなかったり、静的化出来ないページが出来たりして、まだまだツラミが出てたりします。
JAMStack
そのようなCMSのツラミを解決する方法の一つとしてJAMStackが産まれました。おぎゃー。
何の技術?
JAMStackとは、動的サイトを頑張って静的サイトにする技術で、いくつかのサービスを組み合わせて利用するマイクロサービス化されたアーキテクチャです。
メインのコンポーネントとしては静的サイトジェネレータとHeadless CMSです。
Headless CMSでコンテンツを作成し、静的サイトジェネレータがHeadless CMSのAPIを叩き静的サイトを生成する流れになります。
静的サイトジェネレータとは、静的ファイルを動的コンテンツから生成する子です。
外部APIを利用し動的なコンテンツをデータソースとして用いて、テンプレートを組み合わせて静的ファイルを生成します。
Headless CMSとは、既存のCMSからビュー(ヘッド)の機能を無くした(レス)ものです。
既存のCMSのようにユーザが見れるようなビューを持たず、コンテンツを管理したり、外部からAPIを経由してコンテンツを取得出来るようにした、CMSのAPIサーバのようなものになります。
利点
JAMStackの利点としては下記があげられます。
- セキュア
- 疎結合(JAMなのに)
- 脆弱性対応やアップデートの影響が限定的
- 早い
- フロントが静的サイト
- CDNと連携して全世界へ配信可能
- 開発者体験向上
- フロントとバックエンドを分離
- フロントやバックエンドで個々にツールを使い分け可能
- メンテナンス容易
- 顧客影響がある障害も起こりづらい
- フロントとバックエンドを分離
名前の由来
JAMStackのJAMとは、
- JavaScript
- APIs
- Markup
の頭文字を取ったものになります。
LAMPStackに対抗して作ったみたいですが、名前以外関係性は無いみたいです。
もっというと、JAMStackという言葉を先に作って、後から言葉を当てはめただけです。
構成
では、JAMStackはCMSと違ってどのような構成になるのか見ていきましょう。
構成図
まずは、JAMStackで先程の静的サイトジェネレータ・Headless CMSを用いて、どのような構成になるかを下記にお見せします。
ユーザとしては、Hostingにアクセスしてサイトを閲覧します。
デベロッパーはHeadless CMSにコンテンツ修正をしたり、UI DesignでUIをデザインしたり、静的サイトジェネレータを用いたコードを修正してリポジトリに格納します。
UI DesignではUIを作り、HTMLを出力し、それをコードに適用しリポジトリに格納します。
ユーザとデベロッパーは全く別のコンポーネントを見てるため、その間を繋ぐ必要があり、それがCI/CDと静的サイトジェネレータになります。
リポジトリやHeadless CMSが更新されると、hookされCI/CDが起動して静的サイトジェネレータを使用してHostingに静的ファイルをデプロイし、静的サイトを公開するという流れになります。
ちなみに、Hostingの中には、CI/CDを含んだものも多くあります。
各コンポーネントは様々なサービスから選択でき、下記にその一例を示します。
コンポーネント | サービス一覧 |
---|---|
Hosting | Netlify/Vercel/Amplify Console/S3+CloudFront |
静的サイトジェネレータ | Nuxt.js/Gatsby/Hugo |
CI/CD | Netlify/CircleCI/Amplify Console/CodeBuild |
Headless CMS | Contentful/Starpi/MicroCMS/Netlify CMS |
UI Design | AdobeXD/STUDIO/Figma |
リポジトリ | Github/Bitbucket/CodeCommit |
基本的にはこれらのコンポーネントを選択し構築していきます。
サービス構成
先程説明したサービスの中から一番左のもので作った簡易的な構成が下記になります。(UI Designは省いてます)
NetlifyはHostingとCI/CDを兼ねてるサービスのため、よりシンプルに感じますね。
こちらはContentfulでコンテンツを修正し、コードはGithubで管理し、それらをNuxt.jsで静的サイトを作成しNetlifyでHostingするという構成になります。
各々のコンポーネントの設定も非常に簡単ですので、是非色んなサイトを参考に作成してみてください。
職種別
最後にそれぞれのコンポーネントに対して、職種ごとに誰が担当するかを下記に示します。
弊社では、デザイナー・アプリエンジニア・インフラエンジニアでプロジェクトを推進することがあるため、それらのメンバーがJAMStackのアーキテクチャに対してどのような役割になるかを考えてみます。
デザイナーとしては、Headless CMSでコンテンツを修正したり、UI Designでデザイン修正をして、HTMLを作成します。
アプリエンジニアとしては、出力されたHTMLと静的サイトジェネレータを用いてコーディングを行います。
インフラエンジニアとしては、やることがないですCI/CDのビルド・デプロイ内容をチューニングしたり、Hostingの設定や構成をチューニングしたり、全体の構成を設計します。
また、Headless CMSのstrapiのようなOSSやAWSサービスなどを利用する場合の設計、構築などもインフラエンジニアの仕事になるかと思います。
サーバレスが出てきて、インフラエンジニアの仕事が無くなるなど色々言われてる世の中で、JAMStackも同じように感じる方もいらっしゃるかと思います。
インフラエンジニアだけでなく、どの職種も言えることですが、過去と同じ様な仕事を続けられる事はなく、また、職種の名前も変わっていくとは思うので、その時代や作るものによって自分の仕事を定義し、他の仕事にも手を広げれるようなエンジニアになっていきたいですね。
JAMStackのデメリット
最後にJAMStackのデメリットも説明しておこうと思います。
デメリットとしては下記2点になります。
- プレビュー機能がない
- ビルド時間がかかる
プレビュー機能がない
プレビュー機能については、Headless CMSについていない、もしくは簡易的にmarkdownのプレビューとなるため、最終的にユーザが見る見た目は見ることが出来ません。
そのため、プレビュー機能を自作する必要があり、基本的にはビルドが必須となるので、リポジトリのブランチを分離して、ビルドを行いHostingの部分でプレビュー用と本番用で分けるようなアーキテクチャを作り込む必要があります。
一部Netlify CMSなどがプレビューに対応していってますが、まだ発展途上という段階かと思われます。
ビルド時間がかかる
ビルド時間についてですが、コンテンツ修正したりコードを修正すると、毎度ビルドが走るため、その分公開までに時間がかかります。
また、ビルド時間もコンテンツ量によって比例するため、膨大なコンテンツ量になると、ビルド時間がネックになってきます。
解決策としては、そもそもビルド時間が早い静的サイトジェネレータを利用したり、ビルド時間をコンテンツごとにキャッシュする機能を作ったりする必要があります。
まとめ
ということで、インフラ的な要素を多めにしたJAMStackを説明しました。
JAMStackはフロントの人がよく勉強しているイメージですが、インフラの人も勉強しておいて損はないかなと思いますので、是非この機会に勉強してみましょう。