3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

AWSでドキュメントサイトを最速で公開する方法。自動デプロイもあるよ!

Global Mobility Service株式会社でインフラエンジニアをしているodaです。
Global Mobility Serviceのアドベントカレンダーの1日目です。

当社のインフラ環境では、AWSを全面的に採用しています。
先日、ユーザ向けにドキュメントサイトを公開しました。
このドキュメントサイトをどのように構築したかを紹介したいと思います。

概要

  • ドキュメント作成にはMkDocsを使い、Markdownで静的サイトを作成する
  • S3とCloudFrontで静的サイトを公開する
  • ドキュメントのリポジトリにはGitHubを利用する
  • ドキュメントの変更のたびにCodeBuildで最新のドキュメントをデプロイする

MkDocsを使う

MkDocsはMarkdownでドキュメントサイトを作成可能な静的サイトジェネレーターです。
https://www.mkdocs.org/

インストール

pipでインストールします。

$ pip install mkdocs

またはbrewでもインストール可能です。

$ brew install mkdocs

プロジェクト作成

MkDocsをインストールすると、mkdocsコマンドが使えます。
プロジェクトを作成します。

$ mkdocs new my-project
$ cd my-project

docsディレクトリにMarkdownファイルを作成して、ドキュメントを作ることができます。

ローカルで動作確認

ローカルで開発用のサーバを立ち上げて、動作を確認することができます。

$ mkdocs serve

静的サイトのエクスポート

Markdownで書いた内容をhtml等の静的コンテンツにして、エクスポートできます。

$ mkdocs build

デフォルトだと、siteディレクトリに静的コンテンツが作成されます。

S3に静的コンテンツを配置する

S3のバケットを作成します。

$ BUCKET_NAME=hi1280-project
$ aws s3api create-bucket --bucket ${BUCKET_NAME} --region us-east-1

静的コンテンツをS3に配置します。
siteディレクトリに静的コンテンツがあるので、S3のバケットとローカルのディレクトを同期するコマンドでコンテンツを配置しています。

$ aws s3 sync site s3://${BUCKET_NAME} 

ルートディレクトリ、サブディレクトリに配置されたindex.htmlを表示するために、静的ウェブサイトホスティングを有効にします。

$ aws s3 website s3://${BUCKET_NAME}  --index-document index.html

S3のバケットをパブリックでアクセス可能にします。

$ cat << EOF > public.json
{
    "Version": "2012-10-17",
    "Id": "PublicRead",
    "Statement": [
        {
            "Sid": "ReadAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::${BUCKET_NAME}/*"
        }
    ]
}
EOF
$ aws s3api put-bucket-policy --bucket ${BUCKET_NAME} --policy file://public.json

CloudFrontで公開する

CloudFrontのリソースを作成する

CloudFrontからS3による静的ウェブサイトホスティングのURLを参照します。
S3のバケットを直接参照するとルート指定でindex.htmlが表示できないので注意が必要です。

$ aws cloudfront create-distribution --origin-domain-name ${BUCKET_NAME}.s3-website-us-east-1.amazonaws.com

サイトを表示する

CloudFrontのドメイン名にアクセスします。
スクリーンショット 2019-11-29 10.25.53.png

ちゃんと表示されてます!

この時点のソースをGitHubのリポジトリにPushしておきます。

CodeBuildでデプロイする

CodeBuildのプロジェクト作成

設定が必要な箇所のみを示します。その他の項目はデフォルトの設定で作成しています。

GitHubアカウントとの接続を行います。
詳細は以下にあります。
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-access-tokens.html

スクリーンショット 2019-11-29 12.07.58.png

リポジトリが変更されるたびにビルドを実行するように設定します。

スクリーンショット 2019-11-29 12.08.03.png

この後のbuildspecでPythonのランタイムを使いたいので、Amazon Linux 2 standard image 1.0を指定します。

スクリーンショット 2019-11-29 12.08.20.png

buiidspecファイルの用意

buildspecファイルはCodeBuildの実行内容を決めるファイルです。
プロジェクトの直下にこのファイルを作成して、リポジトリにPushします。

buildspec.yml
version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.7
  pre_build:
    commands:
      - pip install --upgrade pip
      - pip install mkdocs
  build:
    commands:
      - mkdocs build
      - aws s3 sync --delete site s3://hi1280-project
      - aws cloudfront create-invalidation --distribution-id E2XXXXXX --paths '/*'

aws s3 sync--deleteオプションをつけることで、同期元にないファイルは同期先でも削除されます。
aws cloudfront create-invaidationで、CloudFrontのキャッシュを削除して、最新のドキュメントが直ぐに反映されるようにしています。

CodebuildのIAMロールに権限を設定

CodeBuildのプロジェクト作成時に、CodeBuild向けのIAMロールが作られています。
CodeBuildのビルドではS3とCloudFrontにアクセスするので、IAM権限を設定します。

スクリーンショット 2019-11-29 12.18.55.png

完成

これ以降はリポジトリの変更のたびにドキュメントがデプロイされます。

この方法の良いところ

AWSを使うことでAWS上の様々なサービスとの連携が可能になります。

Lambda@Edge

CloudFrontにはLambda@Edgeがあります。
これはCloudFrontから静的コンテンツへのHTTPリクエストやレスポンスの間にLambda関数を実行できる機能です。

今回のドキュメントサイトを構築するにあたり、限られたユーザのみからアクセスを可能にするために認証機能が必要でした。
Lambda@Edgeを使用することで静的サイトのコンテンツを変更することなく、認証機能を追加できました。

以下の例にあるようにLambda@Edgeは様々な利用が可能です。
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html

まとめ

最速かどうかは正直よく分からないですが、気軽にドキュメントサイトを公開できたと思います。
AWSをメインのインフラとして使用している場合には参考にしてもらえればと思います。
今回はMkDocsについてあまり触れませんでしたが、簡単に使えて機能も豊富な静的サイトジェネレーターなのでこちらもオススメです。

おわりに

Global Mobility ServiceではAWSを使い倒したいエンジニアを募集しています。
明日のアドベントカレンダーの担当は期待の新星Shirubaさんです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
3
Help us understand the problem. What are the problem?