概要
「カッコいいデザインのモダンかつシンプルなWebサイトを堅牢安価に運用したい」をAWSのマネージドサービスをつなぎ合わせて構築します。管理すべきサーバーやRDBをなくしてDDoS、バージョンアップ失敗、リクエストの急増対策、高額な請求書とはおさらばして枕を高くして眠れるサイトを作ります。
もうちょっと詳しく
Webサイトを運営するには最低限、「(A)コンテンツを制作するしくみ」と「(B)コンテンツの構成を管理するしくみ」と「(C)作ったコンテンツを配信するしくみ」が必要です。
20世紀の小規模ホームページなら
(A) コンテンツを制作するしくみ:ホームページ・ビルダー / Adobe Dreameaver
(B) コンテンツを管理する仕組み:PCのファイルシステム上+人力
(C) 作ったコンテンツを配信する仕組み:レンタルホームページ
だったでしょうし、
近年主流のWordPressなら、
(A) コンテンツを制作するしくみ:WordPress
(B) コンテンツを管理する仕組み:WordPress
(データはRDBMS + ホストのファイルシステム)
(C) 作ったコンテンツを配信する仕組み:WordPress
(データはRDBMS + ホストのファイルシステム)
WordPressだけあれば全て賄えるのですが、いわゆるLAMP環境のWordPressがネックになることも多々あります。
自動アップデートが失敗して何も応答しなくなったり、DDoSくらって借りてるサーバーが落とされたり、DBが過負荷で遅くなったり。だいたいトラヒック増えたらサーバーやDB増強なんて…めんどくさい。
今回はそれぞれを分離して、フルサーバーレスでオートスケールで低コストな構成をつくります。
(A) コンテンツを制作するしくみ:Cloud9 (統合開発環境サービス) 上の Gatsby (静的サイトジェネレーター)
(B) コンテンツを管理する仕組み:CodeCommit (git リポジトリサービス)
(C) 作ったコンテンツを配信する仕組み:Amplify (ホスティングサービス)
(A),(B)は制作中だけ動けば良く、配信は(C)だけで完結しているところがポイントです。
(C)はAmplifyの静的ホスティング機能(実態はCloudFront + S3 + ACM = サーバーレス&オートスケール&高耐久性)だけあれば動き続けてくれます。
これでサーバーの稼働状況を心配することなく枕を高くして眠れます。
(A)は30分間無操作で自動停止するマネージドインスタンスですし、Webブラウザさえあればいつでもどこでも制作・ビルドができて幸せです。
(B)でgitを使ってコンテンツを構成管理するので、RDBMSを持たなくてもバージョン管理でき、リポジトリのブランチを使ってステージング環境をデプロイしたり、複数の制作メンバーで共同作業をすることも容易です。
利用するサービスとフレームワーク
AWS Amplify ?
AWS AmplifyはモバイルアプリケーションやWebアプリケーションをAWSのいろいろなバックエンドサービスを組み合わせていい感じにCD(継続的デプロイ)回してビルドアンドデプロイするための環境です(ざっくり)。
様々な機能がありますが、今回はその中のhosting機能だけを使ってます。
gitと連携してCD(継続的デプロイ)環境を構築・運用できます。
Cloud9 ?
AWSが提供するCDE(統合開発環境)のマネージドサービスです。
Webブラウザさえあればどこでもファイルの編集やモジュールのビルド・プリビューなどができます。
Webブラウザを閉じても状態は保存されますし、放置すればCloud9環境は自動的にインスタンスを停止しコストを抑えます。Cloud9の実態はEC2インスタンス(Amazon LinuxまたはUbuntu)なので、今回はCloud9にWeb制作環境一式を構築し、「ローカルにはWebブラウザだけあればよい」運用を目指します。
Gatsby ? SSG ? JAMStack ?
今回は「テンプレートにそって、ウェブサイトのコンテンツをテーマに沿ってレンダリングした静的サイトを出力する一種のコンパイル環境」として使ってます(ざっくり)。話が長くなりますし、使いこなしているわけでもないので詳細は割愛します。SSGはStatic Site Generator(静的サイトジェネレーター)の略です。Gatsbyは最近流行りのSSGです。サーバーレスな運用を実現したかったので完全静的なサイトを作ろうと思いました。完全静的といっても後日バックエンドサービスを追加してビルドしたWebアプリケーションとサーバーサイドのAPIサービスと連携できる将来性があります。それはそれとして今回は「カッコいいモダンかつシンプルなWebサイトを堅牢安価に運用したい」に話を絞ります。
前提条件
- AWSアカウントがあり、基本的なAWS操作ができること
- AWS アカウントにアクセス可能なインターネット環境とクライアントPC
- Chromeブラウザ
AWS CodeCommitに新しいリポジトリを作る
CodeCommitにコンテンツ用のリポジトリを作ります。
- AWSの管理コンソールからCodeCommitを開く。
-
リポジトリを作成
を押して適当な名前(例えばmysite
)リポジトリを作る。 -
接続のステップ
のHTTS(GRC)
タブにある「ステップ 3: リポジトリのクローンを作成する」のコマンドをメモします。
$ git clone codecommit::ap-northeast-1://mysite
Amazon Cloud9の環境を作る
コンテンツ制作環境として用いる Amazon Cloud9をつくります。
- AWSの管理コンソールからCodeCommitを開く。
-
Create environment
を選択する。-
Name: (Cloud9のホスト名。今回は`cde1`)
-
Environment type: `Create a new instance for environment (EC2)`
-
Instance type: `t2.micro (1 GiB RAM + 1 vCPU)`
-
Platform: `Ubuntu Server 18.04 LTS`
-
Cost-saving setting: `After 30 minutes (default)`
-
数分待つと自動的にWebブラウザーにCDE環境が表示されます。Cloud9の操作方法は公式ドキュメントをご覧ください。
作ったらモジュールを更新します。Cloud9の右下のターミナルペインで操作してください。
$ sudo apt update -y && sudo apt upgrade -y
好みで便利コマンドをインストールします。
c9
はc9 ファイル名
でCloud9のWebUIエディタを起動するコマンドです。
$ sudo apt install tree -y
$ npm install -g c9
Cloud9 にCodeCommit連携設定を行う
Cloud9上のユーザーにCodeCommitを利用するための設定を行います。詳しくは公式ドキュメント
https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ide-c9.html
を参照してください。
gitのユーザー情報を登録する
$ git config --global user.name "my-name"
$ git config --global user.email my-name@mail-address.local
認証情報ヘルパーを登録する。
$ git config --global credential.helper '!aws codecommit credential-helper $@'
$ git config --global credential.UseHttpPath true
GatbyをCloud9上に構築する
Cloud9にGatsby環境を作ります。今回つくるサイト名はmysite
とします。
参考 https://www.mitsue.co.jp/knowledge/blog/frontend/202001/23_1319.html
Gatsby-CLIをインストールする。
$ npm i -g gatsby-cli
Starterをつかってサイトの雛形を作る
Gatsby はサイトの見栄えや構造の雛形を「スターター」というモジュールで環境構築時に選択します(テーマという仕組みもありますが、今回はスターターのみを使います)。
スターターは
Gatsby Starter Library にギャラリーがあるので、サイトに適したスターターを選びます。
今回は以下のスターターgatsby-v2-tutorial-starter
を用います。
https://www.gatsbyjs.org/starters/justinformentin/gatsby-v2-tutorial-starter/
スターターの説明の下の方にインストール方法が書いてあるのでそれを用います。
Install this starter locally:
gatsby new gatsby-v2-tutorial-starter https://github.com/justinformentin/gatsby-v2-tutorial-starterCopy
Gatsby で新しいサイト環境をつくる
いよいよ、StarterからWeb環境をつくります。Cloud9で実施します。
$ cd ~/environment
$ gatsby new mysite https://github.com/justinformentin/gatsby-v2-tutorial-starter
$ cd mysite
$ gatsby develop
この時点で、Cloud9内にプリビュー用のhttpdがたちあがっているので、Cloud9のPreview
メニューのPreview Running Application
を選択すると、Webサイトのプレビューを見ることができます。
Gatsby の設定
コンテンツは(Gatshbyのrootdir)/src/に入っており、gatsyby develop
が動作している状態でコンテンツファイルを変更すると自動でビルドが走りプレビューが更新されます。
(rootdir)/src配下のファイルを確認する。
$ cd ~/environment/mysite
$ tree -L 2 src
src
├── components
├── layouts
├── pages
│ ├── 404.jsx
│ ├── about.jsx
│ ├── blog.jsx
│ ├── index.jsx
│ └── tags.jsx
├── styles
└── templates
動作確認のため、pages/index.jsx
を編集してみます。
gatsby develop
を実行し、プリビューを表示させたまま、以下の手順を行います。
$ c9 ~/environment/mysite/src/pages/index.jsx
28行目あたりのタイトルを修正する。
<Header title="Home Page">Gatsby Tutorial Starter</Header>
<Header title="私のサイト">サーバーレスでWebサイト運用</Header>
修正したら、Cloud9 のFile
メニューのSave
を選択してファイルを上書き保存する。
上書き保存すると、自動的にプリビューが修正後の内容に更新されていることを確認します。
Gatsbyは一種のWebアプリケーションフレームワークなのでAPIを活用してCMSとの連携やバックエンドサービスとの連携、画像やリンクの加工などを行えますがここでは触れません。
コンテンツをCodeCommitのgitリポジトリへ登録する
作成したgatsbyのサイトコンテンツをローカルリポジトリとしてcodeCommitのリモートリポジトリへ登録します。
$ cd ~/environment/mysite
$ git add .
$ git commit -m "1st commit"
$ git remote add origin codecommit::ap-northeast-1://mysite
$ git remote -v
$ git push --set-upstream origin master
Cloud9 にamplify-cliを設定する (amplify configure)
Cloud9にamplify-cliをインストールし、Amplifyの環境設定とAmplifyが利用するIAM Userの作成を行います。
$ npm install -g @aws-amplify/cli
amplifyを設定する。
設問に答えていく。
$ amplify configure
Specify the AWS Region
? region: ap-northeast-1
Specify the username of the new IAM user:
? user name: (amplifyに利用させるIAM user名(ここではamplify-mysite)
表示されるリンクへWebアクセスして管理コンソールからIAMユーザーを作る。
Complete the user creation using the AWS console
(IAM設定画面のURL)
IAM設定画面になるので、デフォルトで進め(次のステップ
x2,ユーザーの作成
)、作られた認証情報(アクセスキー、シークレットアクセスキー)を.csvのダウンロード
を押してダウンロードする(重要)。
終わったらamplify-cliの設定画面に戻りEnter
を押して対話設定を続ける。
作成したIAMユーザーの認証情報を入力する。
IAM user name : my-user
access key : (my-userのアクセスキー)
secret access key : (my-userのシークレットアクセスキー)
This would update/create the AWS Profile in your local machine
? Profile Name: default
Successfully set up the new user.
Gatsbyの構成とAmplifyプロジェクトを連携させる(amplify init)
gitローカルリポジトリ上にAmplifyのプロジェクトを連携させAmplifyにソースディレクトリ、公開ディレクトリ、ビルドコマンドを設定します。
amplify init
コマンドでamplifyプロジェクトを作成し、cloud9上のディレクトリ、Gatsbyのビルド方式を設定する。
$ cd ~/environment/mysite
$ amplify init
対話設定に答え、設定する。
? Enter a name for the project mysite
? Enter a name for the environment prod
? Choose your default editor: None
? Choose the type of app that you're building javascript
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: public
? Build Command: gatsby build
? Start Command: npm run-script start
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default
設定が終わったら、prod
環境が作られたことを確認する。
$ amplify status
Amplifyにホスティング環境を作りCodeCommitを連携させる(amplify add hosting)
Amplifyのprod
環境にホスティング環境を追加し、gitのmaster
ブランチを紐付けます。
$ amplify add hosting
対話設定に答え、設定する。
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Continuous deployment (Git-based deployments)
? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository
ここで、Webブラウザーで管理コンソールを開き、Amplify の管理画面を開きます。
- - - -すべてのアプリ mysite
画面で、CodeCommit
を選択し管理コンソールのAmplify Consoleを開き、CLIで作ったプロジェクトを開く。
Amplify コンソール>Connect a frontend web app
を選択し以下の対話設定を行う。
Connect a frontend web app: AWS CodeCommit
を選び、Connect Branch
を選択する。
リポジトリ: mysite
ブランチ: master
ビルド設定: yamlファイルが自動的に生成されるので確認する。**[重要]**この中のbuild:
コマンドがgatsby build
ではない場合、設定後のビルドで失敗するので、後の手順で修正する必要がある(編集
ボタンを押せる場合は今編集する)。
Backend deployments: Deploy updates to backend resources with your frontend on every code commit
にチェックする。
Select a backend environment: プルダウンでproduct
を選択する。
Select an existing service role or create a new one so Amplify Console may access your resources.
で、プルダウンの下にあるCreate new role
を選ぶ。
IAMの画面に遷移するので、すべてデフォルトの設定で次のステップを選択
を押していき、確認
を選択して、IAM-Roleが作られたらAmplifyの画面に戻り、リロードボタンを押し、プルダウンに作ったIAM-Roleがあらわれるのでそれを選択する。
ビルド設定の構成>Service role: プルダウンからAmplify用のRoleを選ぶ
確認: 保存してデプロイ
画面が変わり、ビルドを環境が構築されます。しばらくかかります。
ビルド画面の4つの工程(プロビジョン-ビルド-デプロイ-検証)の全てがグリーンになったら成功です。
ビルド結果の「検証」タブを開くと、さまざまなスマートフォンやタブレットでの見栄えのプリビューを確認することができます。
ビルドに失敗した場合
ビルドに失敗した場合、ビルドの設定をAmplifyがうまく取得できていない場合があります。
管理コンソールのAmplify > mysite
> ビルドの設定
を開き、build:
コマンドがgatsby build
ではない場合、編集
ボタンを選択して手で編集します。
phases:
build:
commands:
- npm install
- npm build
phases:
preBuild:
commands: ['npm install']
build:
commands: ['gatsby build']
編集したら、Amplify > mysite
を選択し、このバージョンを再デプロイ
を選択してビルドしなおしてください。
ビルドに成功した場合
成功したら、ターミナルに戻り、Enter
キーを押すと、amplify status
コマンドの結果が出力され、master
環境のデプロイ先URL(Domain)が表示されます。
Current Environment: product
| Category | Resource name | Operation | Provider plugin |
| - - - -- - - - | - - - -- - - -- - - --- | - - - -- - - -- | - - - -- - - -- - - ---- |
| Hosting | amplifyhosting | No Change | |
Amplify hosting urls:
┌──────────────┬──────────────────────────────────────────────┐
│ FrontEnd Env │ Domain │
├──────────────┼──────────────────────────────────────────────┤
│ master │ https://master.xxxxxxxxx.amplifyapp.com │
└──────────────┴──────────────────────────────────────────────┘
WebブラウザでWebサイトが公開されたことを確認してください。
Cloud9で変更したソースを再デプロイする
Amplify はCodeCommitのリポジトリに連携しているので、cloud9からcode commit へgit push
することで自動的に公開データがリビルドされます。
ステージング環境を作る
Webサイトを公開後、サイトを変更する際、公開前に関係者が確認するためのステージング環境が欲しくなります。プリビューからぶっつけ本番デプロイは怖いですから。Amplifyではgitのブランチ毎にホスティング環境を構築することができるので、gitのmaster
ブランチが紐づいたprod
環境に加えて、stg
ブランチに紐づいたstg
環境を構築します。
Cloud9のターミナルでgitのstgブランチをローカル,リモート双方へ作る。
$ git push
$ git branch stg
$ git push -u origin stg
$ git branch -a
$ git checkout stg
管理コンソールのAmplify > mysite
を開き、全般
>ブランチを接続する
を選択。
リモートブランチの追加
で以下を設定して次へ
。
ブランチ: stg
Backend environment: stg
If you don't provide a value in this field, your branch name will be used by default.: stg
保存してデプロイ
を選択すると、stg用ホスティング環境がビルドされる。
ブランチ毎に独立したURLが割り当てられる。
以後はCloud9で、gitのブランチを切り替えて、制作を行います。git pushしたリモートリポジトリに連動してそれぞれのホスティング環境が再構築されます。
master環境とstg環境の切り替えとpush
$ git checkout master
$ git branch -a
$ git checkout stg
$ git branch -a
ステージング環境にBASIC認証を設定する
ステージング環境は公開前の関係者確認用なので簡単なアクセス制限を設けます。Amplifyのホスティング環境にはBASIC認証によるシンプルなアクセス制限を設定できるので、それを使います。
- - - -すべてのアプリ>mysite>アプリの設定: アクセスコントロール
で、stgの設定を以下へ変更する。
ブランチ名: stg
Access Setting: 制限 - パスワードが必須です
User Name: (任意の文字列)
Password: (7文字以上の任意の文字列)
ステージング環境の変更を確認する
マスターとステージに差異を作ってみます。
<Header title="私のサイト">サーバーレスでWebサイト運用</Header>
<Header title="私のサイト">サーバーレスでWebサイト運用(STG)</Header>
保存後、リモートリポジトリへpushします。
ubuntu:~/environment/mysite (stg) $ git add .
ubuntu:~/environment/mysite (stg) $ git commit -m "index.jsx"
ubuntu:~/environment/mysite (stg) $ git push
自動的にAmplify でstg環境のリビルドが走り、変更箇所が変わって公開されていることを確認できます。
あとはgitの世界ですので如何様にでも運用しましょう。
Amplify consoleにカスタムドメインを設定する
Amplifyが提供するWebサイトのURLはhttps://master.a95m0krigkdsk3.amplifyapp.com/
のような形式でかっこいいものではありませんし、環境をつくりなおせばURLが変わってしまいます。Amplifyにはカスタムドメイン機能があり、指定したドメイン名のSSL証明書を発行できます。運用するドメインをRoute53で管理することもできますが、今回は別のドメインレジストラで管理しているドメインを使ってAmplify consoleにカスタムドメインを設定します。
Amplify管理画面でドメイン管理を選択する。
カスタムドメインの設定を選び、登録したいドメインを設定する。
(30分くらいかかる)
外部DNSを使っている場合の処理
Route53以外のドメインレジストラを利用している場合、通常のCNAME設定とは別にACMのバリデーションのためにACMが作るCNAME設定をDNSに登録します。
cname (カスタムドメイン名). master.(amplifyID).amplifyapp.com.
cname _(バリデーション用サブドメイン).(カスタムドメイン). _(バリデーション検証のためのサブドメイン).acm-validations.aws.
これで、カスタムドメインへhttpsアクセスするとamplifyが公開しているホスティングが応答するようになります。
補足
Amplifyのホスティング環境を削除する
Amplify環境内のホスティング環境を作り直したいときの削除手順です。削除後はamplify add hosting
から再構築します。
$ amplify status
$ amplify hosting remove
$ amplify status
Amplify環境を削除する
Amplify環境全体を作り直したいときの削除手順です。Cloud9に紐づいているAmplify環境が1つのときと2つの時で手順が変わります。削除後はamplify init
から再構築します。
Cloud9に紐づいているAmplify環境のリストを表示する
$ amplify env list
1つのときの環境削除手順
$ amplify delete
複数環境aとbという環境が紐づいている場合に、環境aのみを削除する手順
$ amplify env checkout b
$ amplify env remove a
分散開発
Cloud9はIAM Userに紐づいてますので、多人数でWebサイトを分散開発する場合は開発者毎にCloud9を立ててgatsby develop
とgitコマンドを活用しながら容易に分散開発が可能です。CodeCommitの代わりにGitHubを使っても良いですね。
応答速度
そもそもPWAに対応してるので、一度読み込むとオフラインで動作するためネイティブアプリのように超高速です。キャッシュを消して初回アクセスしたときも完全に静的でCDNも効いてるのでかなり早いです。リッチなコンテンツの割に500msくらいでほぼ描画が終わります。しかし、残念ながら爆速ベンチマークの「阿部寛のホームページ」にはかないませんでした。
スケーラビリティ
基本的にAmplify hostingのCDN(CloudFrontでしょうね)が100%キャッシュするので相当なアクセスに耐えるはず。従量課金なのでそれに応じてコストは上がります。
可用性
SPOFがないので強いです。強固なAWS バックボーンにささえられてるのでDDoSも困難でしょう。Amplify内のオリジンサーバーもS3なので耐久性があります。Cloud9に永続データはないのでいざ壊れたら再構築してCodeCommitからPullします。
まとめ
「カッコいいデザインのモダンかつシンプルなWebサイトを堅牢安価に運用したい」をAWSのサーバーレスサービスをつなぎ合わせて構築しました。管理すべきサーバーやRDBがないのはよいですね。これで枕を高くして眠れます。レスポンシブ、PWAといったモダンな機能にも対応しました。ランニングコストも抑えられました。
ここを起点に記事更新用にheadlessCMSをGatsbyと連携させたり、AWS のAPI GWやCognitoと連携させたりと発展性もある構成になりました。
(おわり)