📝

Amplifyで特定の人に公開するためのドキュメントをホスティングする

2022/12/31に公開

いつもは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;

Docusaurus get started

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が作成されています。

codecommit

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になってきましたね…!!)

cognito

ログイン用のテストユーザーを作ってしまいましょう。(新しいUIを試してみたくてマネコンから作っています)

create-user

  • 上のスクショでは「パスワード生成」にチェックが入っていますが、実際は適当な仮パスワード設定しています。
  • メルアドは適当で構いません(黒くしてますが、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のライブラリが使えるようにします。

userPoolIduserPoolClientId を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