【保存版】AWSのS3で静的サイトをデプロイ&独自ドメイン設定を画像付きで解説


はじめに

本記事へのアクセスありがとうございます。
投稿主はプログラミング初心者であり、この方法が「最適解」かは分かりません。
しかし、動作は検証済みであり同様な記事も確認できたので信憑性はあると思います。

本記事は時系列ごとに記載しているので、デプロイスタートから順番にやっていけば出来ると思います。

この記事から得られるものは?

・AWSのS3を用いた低コストで簡単な静的サイトのデプロイ方法
・設定中に起きうるエラー対処法
・お名前ドットコムを利用した独自ドメイン設定(好きなURIへの変更)方法
・Certificate ManagerのよるHttps化の設定方法
・Circle CIを用いたS3への自動アップロード方法

さっそくデプロイスタート

S3のバケット作成〜設定

AWSのホームページにてログインした状態からの説明となります。

まずはS3のページにアクセスし、バケットの作成ボタンをクリックします。

ここでお好きなバケット名を設定してください。
S3のリージョンは東京リージョン作成でも構いません。後に出てくるCertifacate Managerはバージニア北部リージョン設定する事に注意してください。

* このバケット名は最後の独自ドメインで取得したいアドレス名と同じにした方が設定が楽です。
ここでは最後のURIでawsqiitahosting.workというものを設定したいのでバケット名は以下のようにしました。

バケット名を入力したら次へをクリックし、オプションの設定は何もチェックせずに次へをクリックします。
アクセス許可の設定はデフォルトでチェックが入っている「パブリックアクセスを全てブロック」のチェックを外します。
すると、警告マークが出るがそれにチェックを付け、次へをクリックする。

確認画面で特に問題がないなら、バケットを作成をクリックします。

次は手動でS3にファイルをアップロードします。(後にCircleCiを用いて自動アップロードをします)
* 予めご自身のビルドコマンドを実行しておいてください。
* アップロードするのはファイル全てではなくてデプロイに必要な部分だけで良いので間違えないように。
具体的には下記のようにdistの中身だけをアップロードします。

アクセス許可設定は何もせずに次へをクリックし、プロパティもデフォルトのままで次へをクリックし、確認画面で間違いが無いことを確認してアップロードをクリックします。

次はS3のプロパティのStatic website hostingの設定をします。
デフォルトでは「ウェブサイトのホスティングを無効にする」にチェックが付いているので、「このパケットを使用してウェブサイトをホストする」にチェックを付けます。そしてインデックスドキュメントとエラードキュメントをplaceholderと同じように設定します。

次はアクセス許可のバケットポリシーに下記のコードを記載します。
Resourceの部分はご自身で設定したバケット名に差し替えてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
        }
    ]
}

お疲れ様です。これで一旦、S3の設定は完了です。

Route53の設定

S3の設定が完了したら、Route53でホストゾーンを作成していきます。
ダッシュボードのホストゾーンを選択し、ホストゾーンの作成をクリックします。

ホストゾーン設定ではドメイン名の付け方に注意しましょう。ドメイン名は先ほど作成したS3のバケット名と同じようにします。

タイプはデフォルトのパブリックホストゾーンにし、ホストゾーンの作成をクリックします。

お名前ドットコムにて独自ドメインを取得&ネームサーバー設定

お名前ドットコムのホームページにてログインした状態からの説明となります。
まずはドメインを登録(購入)を行います。(ここでは.workという1円のドメインを取得します)

ドメイン登録ではS3のバケット名(最終的に表示させたいドメイン名)から.~を省いたものを検索します。

.workなど好きなものを選択して、お申し込みへ進むボタンをクリックします。
ドメインを利用するためのサーバーを選択する画面では「利用しない」を選び、次へ。
選択した商品が1円であることを確認してから、申込むをクリックします。

次はネームサーバーの設定を行っていきます。

ドメイン設定のネームサーバー設定のページに進みます。
先ほどのドメインを選択して、画面下部のネームサーバーの選択でその他をクリックし、「その他のネームサーバーを使う」にてRoute53の4つの値をコピペして追加します。

お疲れ様です。これでお名前ドットコムでドメイン取得&ネームサーバー設定が完了です。

Certificate Managerの設定

Certificate ManagerではHttps設定をするために証明書を手に入れます。
* 本記事投稿日ではバージニア北部リージョンでしか取得できないので注意しましょう。(デフォルトがバージニア北部なので変更しない)

パブリック証明書のリクエストでドメイン名はS3のバケット名と同じにします。
検証方法はDNSの検証を選択、タグはご自由に設定し、確認画面で間違いがないことを確認してから確定とリクエストをクリックします。

すると検証画面のドメイン部分にRoute53でのレコードの作成ボタンが表示されているので、クリックして作成する。
しばらく待つと検証状態が成功となるので、それまで反映を待ちましょう。

これでCertificate Managerの設定は完了です。

CloudFrontでの設定

Route53の反映が完了したら、CloudFrontのDistributionを作成します。
AWSの検索部分でCloudFrontを検索し、

上記画像のCreate Distributionをクリックし、Get startedをクリックします。

すると、たくさんの設定項目が出てきます。ここで記入するのは下記の項目です。

  • Origin Domain NameはS3のエンドポイントと同じにする必要があるので、選択肢に出てくるs3バケットは選択しないように気をつける。
  • Viewer Protocol PolicyはRedirect HTTP to HTTPSに設定する
  • Alternate Domain NamesはS3のバケット名と同じ事を記入する
  • SSL Certificateはcustom SSL Certificateを選んで、Certificate Managerにて発行した証明書通りの値を選択する
  • Default Root Objectはindex.htmlを記入する




上記以外の項目はデフォルトのままでOKです。
そしたらCreate Distributionをボタンを押し、画面遷移するとStatusがIn Progressとなり反映中となるので、Deployedとなるまで少し待ちましょう。

Deployedとなったら再度Route53のページを開きます。
ホストゾーンから対象となるものを選択し、レコードを作成をクリックします。
レコードセットの作成での設定は下記のようにします。(下記以外はデフォルト)
・名前は未入力
・エイリアス:はい
・エイリアス先:CloudFrontのDomain Nameを入力する。

お疲れ様でした。
ここで独自ドメインの設定まで完了したので、取得したドメイン名で検索するとデプロイされているかを確かめる事ができます。

ここからはCircle Ciを使って自動アップロード設定するので、手動でいい。
一度アップロードしたファイルを変更する機会がない人はここまで大丈夫です。

自動デプロイしたい人はもう少しだけ頑張りましょう。

自動デプロイ編 Circle Ci

はじめにS3のバケットポリシーに追記するために必要なIAMの設定を行っていきます。

IAMの設定

【ポリシーの作成】
まずはポリシーの設定でS3の権限付与内容を下記のように記載します。

ポリシーの確認では、お好き名前を設定してポリシーの作成をクリックします。(ここではqiitaHostingとします。)

【ユーザーの作成】
ダッシュボードのユーザーを選択し、ユーザーを追加をクリックします。
ユーザー名はお好きな名前を設定し、アクセスの種類はプログラムによるアクセスにチェックを付けます。

アクセス許可の設定では「既存のポリシーを直接アタッチ」を選択し、先ほど作成したポリシーを選びます。

タグの追加は付けても付けなくてもどちらでも構いません。
確認画面で間違いがないことを確認したらユーザーを作成します。

* ここで表示されるアクセスキーIDとシークレットアクセスキーは後に使うので、忘れないようにしてください。

Circle Ciの設定

次はCircle Ciのページを開きプロジェクトから指定のレポジトリを選び、Project SettingからEnviroment Variablesを選択し、下記画像のように設定します。
ここで、作業中のファイルで環境変数を使っている場合はその情報を追記してください。

AWS_ACCESS_KEY_IDとAWS_SERCRET_ACCESS_KEYはIAMで取得しておいた値をコピペします。

設定し終わったら、再度S3のページを開きます。

S3の設定

既存の記載されているバケットポリシーに追記で、下記のコードを入力します。(ここでは分かりやすいように全部載せています)
* 本記事や類似記事のこのコード部分をコピペすると、AWSの使用上?エラーとなってしまう場合があるので面倒ですが、手打ちすることをオススメします。


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAqRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::【自分のバケット名】/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "【アクセスを許可したいIPアドレス】"
                }
            }
        },
        {
            "Sid": "forCircleCi",
            "Effect": "Allow",
            "Principal": {
                "AWS": "【CircleCI用のIAMのarn】"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::【自分のバケット名】",
                "arn:aws:s3:::【自分のバケット名】/*"
            ]
        }
    ]
}

これでAWS側の設定は完了です。

最後にアップロードしたいファイルにymlファイルを作成します。
下記のコードを.circleci/config.ymlとしてディレクトリ直下に作成しましょう。
* 投稿主はyarnを使っているのでyarnでの記載となっていますが、npmの方は臨機応変に書き換えてください。
* buildコマンド部分もご自身のbuildコマンドを設定してください。

version: 2
jobs:
  build:
    docker:
      - image: circleci/node:latest
    working_directory: ~/repo
    steps:
      - checkout
      - run: yarn install
      - run: yarn run build
      - persist_to_workspace:
          root: ./dist
          paths: [ '*' ]
  deploy:
    working_directory: ~/repo
    environment:
      - AWS_S3_BUCKET_NAME:自分のバケット名
    docker:
      - image: innovatorjapan/awscli:latest
    steps:
      - attach_workspace:
          at: .
      - run:
          name: Environment Variables
          command: |
              touch .env
              echo API_KEY=$API_KEY > .env
      - run: aws s3 sync . s3://${AWS_S3_BUCKET_NAME}/ --exact-timestamps --delete --exclude=".git/*" --exclude=".circleci/*" --exclude="node_modules/*"

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master

これでpushされるとCircle Ciが作動して自動でS3にdistの中身をアップロードしてくれます。

おわり

お疲れ様でした。これで一連の設定は完了です。

AWSのS3へのデプロイは低コストですが、お金は少なからず発生するのでデプロイが不必要になったら色々と設定をオフにすることをお忘れなく!

少しでも役に立ったと思う方がいましたらLGTMをお願いします🙇‍♂️

追記

独自ドメインを入力して検索したページで下記のようなメッセージが現れた時の対処法を説明します。
ERR_TOO_MANY_REDIRECTS

  • S3バケットのStatic website hostingにて、「リクエストをリダイレクトする」に変更し、ターゲットバケットまたはドメインフォームにて取得ドメイン名を入力する。プロトコルはhttpsにする。
  • CloudFrontディストリビューションの設定にて、Origin Domain Nameを選択肢にあるS3バケットを選択し直す。
  • Behaviorの設定にて、Viewer Protocol PolicyをRedirect HTTP to HTTPS から HTTP and HTTPSに変更する。