AWSのS3バケットにHTMLを置いてWeb公開してみよう

2021-07-20

はじめに

AWSの勉強始めました。 普段の仕事が車載用マイコンで動作させる通信規格の仕様を書いているので基本枯れた技術です。 それはそれで面白いのですが、やっぱり新しいものを触れてぇなと思いまして…今回の記事です。 AWSを新しい技術と言うのはどうなんだろうと思いはしますが…まぁやっていきましょう。

目的/モチベーション

  • 今どきの技術をキャッチアップしておきたい
  • Wordpressから静的Webホスティングに移行したい

Wordpressのサイトの表示を早くしたいと思っています。 このブログはAmazon Lightsail上のWordpressで作っています。 特に不満は無いのですがやはりもっと早くしたい気持ちが湧いてきているのと、 S3に移行すればランニングコストを抑えることができそうなので調べています。

構成としては、Static Site Generator(SSG)で作ったHTML郡をS3バケットに置いて、 CloudFrontにキャッシュして高速化します。CloudFrontはRoute53でHTTPS化するのが良いと聞きました。

SSG部分はNuxt.jsとNext.jsとかGatsbyとか色々あるみたいでよくわかってないです。 まずはサーバ側であるAWSから手を付けていきましょう。

AWSハンズオン

やりたいことを知るのにちょうど良いハンズオンが公開されていたのでこれをやっていきます。

“AWS 上で静的な Web サイトを公開しよう!” 編を公開しました!- Monthly AWS Hands-on for Beginners 2020年5月号

基本的にはこのハンズオンと同じ内容をなぞってみましたというのが今回の記事です。

S3 バケット

S3バケットの作成

まずは、HTMLを保存するS3バケットを作ります。

ConsoleのTOP画面からS3バケットを検索し開きます。 右上のバケットの作成から適当に名前を付けて作ります。

むやみやたらにアクセスを許可するのは推奨されていないので、このままやっていきたいところですが Webサイトホスティングとして公開するため設定はこんな感じにします。 ※CloudFrontの設定ができたら公開範囲を絞ったほうが良いらしいです。

静的ウェブホスティングの設定

S3バケットができたので、今度はそのバケットの設定をやっていきましょう。

上のタブの管理から、静的ウェブホスティングの設定を編集しましょう。

この設定することで、S3バケットに置いているHTMLを表示できるようになります。

バケットポリシーの記述

パブリックアクセスを全てブロックすると設定しましたが、まだアクセスが有効ではありません。 Json形式で、バケットポリシーを記載し有効にします。

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

Resourceの中のxxxxxxxxにはバケット名を記入します。

実際に記載するとこうなります。

うまく設定が反映されますと静的ウェブサイトホスティングが有効になります。

index.htmlのアップロード

オブジェクトタブを開きます。

アップロードボタンを押すとローカルからファイル追加できます。 なんでも良いですが、表示したい画面が書かれたHTMLをアップロードします。

サイトの確認

静的ウェブサイトホスティングのページからアドレスが確認し、接続してみます。

静的ウェブホスティングのところに、バケットウェブサイトエンドポイントとしてリンクが書いてあります。 このリンクをWebブラウザでアクセスすると繋がります。お手軽。

※HTMLのページを消しましたが、バケット自体削除したので無駄なことをしてしまったなと思っています。

Cloud9

ローカルでファイルアップロードなどを行えば良いですが、 折角なのでCloudでLinuxマシンを使えるような環境を立ち上げます。

勉強会とか、共通の環境を使ってなにかするのに便利そうですね。 (使用する時間によってはちょっとお金かかりますが…)

料金は大体このような感じです。参考までに置いておきます。 (2021/07/10時点)

https://aws.amazon.com/jp/cloud9/pricing/ なお、正規の値段は公式から確認してください。

環境の立ち上げ

Cloud9をコンソールから選択肢作っていきます。

※リージョンが大阪だと作れないので、TOKYOに魂を売ります。

設定は何でも良いですが、初期値でやります。

起動

ちょっと時間がかかります。 (2分ぐらい)。

立ち上がりました。

index.htmlのアップロード

先程は、S3バケットに直接アップロードしましたがCloud9からS3バケットにアップロードしてみます。

適当にフォルダを作ります。

$ mkdir my-webpage
$ cd my-webpage/

Local ファイルをCloud9にアップロードします。 Fileー>Upload Local Filesを選択します。

先程上げたindex.htmlをアップロードします。

上がったファイルをダブルクリックするとWEBブラウザ上で編集ができます。

<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>AWSの勉強のために</title>
</head>
<body>
  <div>
    <div class="msg">
      AWSについて勉強しはじめました。よろしく
    </div>
  </div>
</body>
</html>

アップロードしたHTMLはこのようにしました。

Previewボタンを押すとこんな風に編集しているHTMLファイルを確認できます。 この状態ではタイトルは確認できないですが、タブから開けばタイトルも見られます。

CLIコマンドから単一のファイルアップロード

s3バケットにCloud9上のファイルをアップロードしておきます。 今回はCloud9経由でアップロードしていますが、ローカルにコマンドセットを入れれば同様のことができるはずです。

安価でブログを運用したいってのが目的なのでCloud9を使う構成はやりすぎな気がしますね。 勉強になりましたってことでワイの血と肉になったことにしましょう。

aws s3 cp index.html s3://xxxxxx.xx

xxxxx.xxには例えば,kenpos.devのようなドメインが入ります。

成功するとこんな感じに表示されます。

ec2-user:~/environment/my-webpage $ aws s3 cp index.html s3://xxxxxx.xx
upload: ./index.html to s3://xxxxxx.xx/index.html

参考までに、awsコマンドの使い方をコピーしておきます。

usage: aws s3 cp <LocalPath> <S3Uri> or <S3Uri> <LocalPath> or <S3Uri> <S3Uri>

更新されていることの確認

Cloud9から更新されたファイルを確認してみましょう。 ブラウザから先程設定したS3バケットで公開されているアドレスを叩きましょう。

更新されてるっぽいですね。

CLIコマンドから複数ファイルアップロード

mkdir img
mkdir css
touch css/styles.css

favicon.icoとimg/lamda.webpをアップロードします。 Localファイルからあげれば良いですね。

<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>AWSの勉強のために</title>
  <link rel="icon" href="favicon.ico">
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>
  <div>
    <div class="icon">
      <img src="img/lambda.webp">
    </div>
    <div class="msg">
       AWSについて勉強しはじめました。よろしく
    </div>
  </div>
</body>
</html>

style.css

あんまり本筋ではないですが見た目を整えるためにCSSを書きます。

body {
  width: 300px;
  margin-left: auto;
  margin-right: auto;
}

.icon img {
  padding-top: 16px;
  padding-bottom: 16px;
}

Previewで確認する

こんな表示になりました。

S3バケットにアップロード

皆さんが保有しているS3バケットを指定します。

aws s3 cp . s3://xxxxxx.xx --recursive

実行に成功するとこうなります。

upload: ./index.html to s3://xxxxxx.xx/index.html            
upload: ./favicon.ico to s3://xxxxxx.xx/favicon.ico          
upload: css/styles.css to s3://xxxxxx.xx/css/styles.css    
upload: img/lambda.webp to s3://xxxxxx.xx/img/lambda.webp    

S3サーバからファイルを確認します。

CloudFront

S3バケットに直アクセスするのではなく、CloudFrontというサービスを挟んでコンテンツをキャッシュして そのキャッシュを表示してもらうような構成を取ります。

(気が向いたら図をこの辺に貼ります。)

S3バケットアクセスにCloudFrontを噛ませる

S3バケットが選択肢に出ますが、先程までアクセスしてたサイトアドレスから http:// 部分を削除したものを入れておきます。

Nameのところにはhttp://込みでパスを設定します。

CloudFrontコンソールを立ち上げるとこんな画面になります。

キャッシュの確認

X-Cacheを確認していきます。

CloudFront側で実行した場合

Ctrl + Shift + RでForuce Reloadします。 Hit From cloudFrontとして、キャッシュ結果を取得できたことが確認できました。

S3バケット側で実行した場合

間にCloud Frontが挟まっていないので、X-cacheが無いことを確認できます。

まとめ

本日はここまで。 CloudFront単体だとHttpsでアクセスできないので更にRroute53を噛ませる必要があるようです。 またまとめます。