Amplifyで特定の人に公開するためのドキュメントをホスティングする
いつもはlocalstack
で色々遊ぶことが多いのですが、 開発ドキュメントを簡単に管理して見れるようにというところで、よくあるAmplifyを使った静的サイトホスティングを行っていきたいと思います。
以下モチベーションです。
- 特定の人しか見れないように認証をかけたドキュメントサイト作りたい
- いつでもホスティング環境が潰せるようにしたい
- AWS使いたい
技術選定
開発ドキュメントをどんなフレームワークで作ろうかなと考えたとき、JAMStackのサイトでは様々なSSGがまとめられているので、そこから今回はDocusaurusを選びました。
理由としては下記の通りです。
-
.md
,.mdx
などを使って、基本ファイル置くだけでドキュメントが見れるようになること -
Amplify
を使いたいので、それに対応した言語でコンポーネントとか書けること - デフォルトのテーマでもかっこよく運用できそうなやつ
簡単に構築したかったので、Amplifyを使って構築していきます。
ただ、それだけだと簡単に構築できてしまうので、今度CDKでもS3 + CloudFrontな構成でデプロイしてみましょうね。
構成
下記の通りよくある構成で行きたいと思います。
会社とか限られた環境で使うならWAFでさらに制限をかけるのもアリだと思いますが、現状対応していないっぽいので(https://github.com/aws-amplify/amplify-hosting/issues/36)、もうちょい複雑にしたいときはCDKでWAF+Cognito+S3+CloudFront+Route53とか書いたほうが良さそうですね。
必要なもの
- npm
- node
- aws cli(一部CLIを使ってリソースを操作しているので入れてますが、マネコンからでもいけます)
- amplify-cli
Docusaurusでのドキュメントサイト初期化
公式手順に則って、まずは適当にドキュメントサイトを作ります。
npx create-docusaurus@latest my-website classic --typescript;
npm start;
Amplifyの初期化
Amplifyを初期化して、CloudFormationのリソースを作っていきます。
まずは公式からAmplifyを使えるようにしておきます。
僕は基本AWS Profileでの設定をしているので、credentialをちゃんと発行しておきましょう。
user% amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project amplifydochosting
The following configuration will be applied:
Project information
| Name: amplifydochosting
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start
? Initialize the project with the above configuration? Yes
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile
Deploying resources into dev environment. This will take a few minutes. ⠦
Deploying root stack amplifydochosting [ ---------------------------------------- ] 0/4
AuthRole AWS::IAM::Role CREATE_IN_PROGRESS Fri Dec 30
UnauthRole AWS::IAM::Role CREATE_IN_PROGRESS Fri Dec 30
DeploymentBucket AWS::S3::Bucket CREATE_IN_PROGRESS
ReactのDocusaurusプロジェクトでamplify init
しているからか、Project informationが適切に判断してくれているようですので、上記構成でYesしてしまってポチポチ進めば勝手にAmplifyのリソースがデプロイされます。
CodeCommitへのpush
次にCodeCommitにソースコードをpushしちゃいましょう。
git init;
aws codecommit create-repository --repository-name amplify-doc-hosting;
git remote add origin codecommit::ap-northeast-1://amplify-doc-hosting;
git add .; git commit -m "first"; git push origin main;
念の為マネコンから確認していますが、下記のようなrepositoryが作成されています。
Cognito認証の追加
続いてamplify-cli
でCognitoによる認証を追加します。とりあえずemailでの認証でお試し作成していきます。
user% amplify add auth
Using service: Cognito, provided by: awscloudformation
The current configured provider is Amazon Cognito.
Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Email
Do you want to configure advanced settings? No, I am done.
amplify push
でリソースをデプロイしたら(数分かかります)、Cognitoにユーザープールが作成されています。(ついに新しいUIになってきましたね…!!)
ログイン用のテストユーザーを作ってしまいましょう。(新しいUIを試してみたくてマネコンから作っています)
- 上のスクショでは「パスワード生成」にチェックが入っていますが、実際は適当な仮パスワード設定しています。
- メルアドは適当で構いません(黒くしてますが、
test@test.com
みたいなのでもおっけーです
Amplifyを使ったContinuous Deploy
Continuous deployができるようにamplify-cliでのhostingを設定します。
user% 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
するとAmplify Consoleにリダイレクトされるので、codecommitでのapplication hostを設定していきます。
ブランチは適当にmain
にしておきます。
上記のroleは、新しいroleを作成して適当にデフォルトの設定でポチポチ作成しました。
作成後はこんな感じでAmplify Consoleから勝手にデプロイが進んでいきます。
体感7~10分くらいですね。
デプロイが完了したらデプロイしたURLにアクセスしてみましょう。
デプロイしたURLにアクセスするとAccessDeniedが返ってきます。これは、Amplifyのビルド設定でbuild後のartifactを正しく指定していないためです。
なので、Amplify Consoleのビルド設定からbaseDirectoryにbuild
を指定しておきます。
DocusaurusにAmplifyのCognito認証を設定する
CDの設定完了しましたが、このままだとDocusaurusがアクセスすれば誰でも見れてしまう状態なので、AmplifyのCognito認証をDocusaurusに導入していきます。
npm i aws-amplify @aws-amplify/ui-react
でAmplifyのライブラリが使えるようにします。
userPoolId
とuserPoolClientId
をAmplify.configureで読み込む必要がありますが、今回はamplifyを使用するので、aws-exports.js
から読み込むように設定しておきます。
Docusaurusのindex.tsxにAmplifyのUIを追加します。
src/pages/index.tsx
import { Amplify } from "aws-amplify";
import { withAuthenticator } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
import awsmobile from "../aws-exports";
Amplify.configure(awsmobile);
function HomepageHeader({ signOut }) {
const { siteConfig } = useDocusaurusContext();
return (
<header className={clsx("hero hero--primary", styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<button onClick={signOut}>Sign out</button>
</div>
</div>
</header>
);
}
function Home({ signOut, user }): JSX.Element {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
>
<HomepageHeader signOut={signOut} />
<main>{/* <HomepageFeatures /> */}</main>
</Layout>
);
}
export default withAuthenticator(Home);
Docusaurusのnavbarにsign out buttonのコンポーネントを追加したかったのですが、対応しきってないみたいなので、適当な場所にsign out buttonを設置しています。
npm start
してみて、下記の認証画面が出れば成功ですね
試しにテストユーザーでログインしたらdocusaurusの最初のページ+Sign outボタンが出るはずです。
ローカル環境でCognitoの動作を確認したら、あとはCodeCommitにpushするだけでCICDが動作して、正常にデプロイされます。
早速先程AccessDeniedされたURLにアクセスして、動作確認をしていきましょう。
おわり
お片付けとしてamplify delete
ですべてのリソースを削除しちゃいます。
ただし、Amplify Consoleから新たに作成したIAM Roleだけはマネコンから作ったやつなので、必要なければ別途削除してください。
n番煎じだと思いますが、Amplify Hostingはそれなりに便利なので、さらっと概念実証とかするのはいいなと思います。Cloudflare pages + accessとかでも同じようなことができそうなので、そのうち試したいところです。
Discussion