s3 ssl化 https化(CloudFront/ACM/Route53)

S3の静的WEBホスティングで公開中のアプリのURLはデフォルトではhttpになります。Cloud Frontを用いてhttpsにしてセキュリティを向上させます。

基礎知識

静的コンテンツ配信を行うAWSアーキテクチャのベストプラクティス

architecture

  • S3でコンテンツをHostingして、ユーザーとの間にCloud FrontとRoute53を挟むのが基本です
    • それぞれの説明は後述します

SSL

  • SSL(Secure Sockets Layer)とは
    • データ通信を暗号化し、盗聴や改ざんを防ぐプロトコル
    • httpsから始まるWEBサイトはSSLを導入しています
    • 非SSL(http)の場合、Googleがデフォルトで警告マークを出すので、サイトやWEB APの信頼度が大幅に下がります

Cloud Front

  • CDN
    • 配信パフォーマンスの向上
    • コスト削減
  • セキュリティの向上

Route53

手順

  • 想定する状況
    • AWS Consoleで設定
    • CloudFormationやSAMで作るケースもあると思います

Cloud FrontとS3を連携

  • まずは以下の構成を作ります
    CloudFront x s3
  • AWS Console/サービス/CloudFront

  • Create Distributionを押下
    Cloud Front Menu

  • 配信方法はWEBを選択
    Delivery Method

ディストリビューションの作成

  • Origin Settings

    • Origin Domain Name
      • Hosting中のs3バケットを選択
    • Restrict Bucket Access
      • YesにするとCloudFront経由でのみ閲覧可能になる
      • Grant Read Permissions on Bucket
        • これを設定しておくとS3のバケット側の設定を自動でやってくれる
  • Default Cache Behavior Settings

    • そのままでもOK
    • Viewer Protocol Policy
      • Redirect HTTP to HTTPS
        • これにしておくとhttpからhttpsへリダイレクトさせてくれる
  • Distribution Settings

    • Alternate Domain Name(CNAMEs)
      • 証明書を取得したドメイン名を設定
        • 複数のドメイン名を使用する場合は、改行区切り
      • ドメインを取得していなければスルー
    • SSL Certificate
      • Defaultの証明書でOK
      • 独自SSLを使用する場合
        • 事前にIAMに証明書をアップロードしておく
    • Default Root Object
      • S3の静的Hostingの設定で指定した、インデックスドキュメント(Angularであればindex.html)を入力
    • Create Distributionを押下
  • 20分程度でStatusがDeployedになるので、完了後にアクセスしてみる

  • URL

    • XXXX以降はディストリビューションのGeneralタブのDamain Nameに表示されているものを確認
      1
      https://xxxxx.cloudfront.net
      image
  • Route53や独自ドメインを利用しないのであれば以上で完了

CloudFrontの注意点:キャッシュコントロール


独自ドメインを活用する場合

  • 前提
    • 独自ドメインを取得してRoute53に登録済み
    • これから取得する人はお名前.com等を使ってみてください

ACM(AWS Certificate Manager)で証明書を作成

  • AWS Console/AWS Certificate Manager/証明書のリクエスト

  • ドメイン名を入力

    • ”この証明書に別の名前を追加”よりドメインの別名を設定

ACM

requst

  • CloudFrontにACMで作成した証明書を設定
  • Ditribution/Generalタブ/Edit
  • SSL Certificate
    • Custom SSL Certificateを選択
    • プルダウンから先ほどACMに登録した証明書を選択
  • 保存

Route53の独自ドメインのエイリアスの向き先を変更する

  • AWS Console/サービス/Route53

  • ホストゾーンから登録済みのドメインを選択

  • 対象の行を選択

    • タイプ:Aのもの
  • レコードセットの編集

    • エイリアス先を変更
      • [CloudFront ディストリビューション] - 対象のドメイン名 を選択
  • レコードセットを保存

  • 確認
    • 以下にアクセスしてみる
      1
      https://{独自ドメイン}

参考

[AWS S3 x Angular] 静的WEBサイトホスティングでSPAを公開/ng build/公開範囲の限定/CI/CD化

基礎知識

S3の静的WEBサイトホスティング機能

  • 静的WEB Hostingとは

    • 静的コンテンツをWEBに公開するオンラインストレージの機能
    • 静的コンテンツとは
      • HTML/CSS/JavaScriptなどで構成されるWEBページやWEBアプリ
    • サーバーレスアーキテクチャを実現
      • Angularで開発したアプリは静的WEB Hostingを利用することで、WEBサーバー無しで公開できます
      • TypScript(JavaScript)で書いた機能は、アクセスしたユーザーのブラウザ側で動くため、公開する側にコンピューティングパワーが必要無い=WEBサーバーが必要無いわけです
      • こういったサービスを利用して、表向きのサーバー無しで構成するのが、サーバレスアプリケーションと呼ばれるており、最近の流行りです
    • メリット
      • サーバーの運用費がかからないため、インフラのコストを大幅に削減可能
        • 一般的にアクセス数が伸びるまでは無料で公開できるため、スタートアップが新しいサービスを立ち上げる際によく使う手法でもあります
  • 静的WEB Hostingの代表的なサービス

  • S3の料金

    • 料金はHostingする容量+通信料で定まります

    • 無料枠

      • 初めの1年間以下を利用できます
        • Hosting:5GBまで
        • 通信
          • 20,000 GET リクエスト、2,000 PUT、COPY、POST、あるいは LIST リクエスト、データ送信 15 GB
    • 計算方法

      • SPA(Single page Application)は初めにAP全体を読み込んで画面遷移は端末側で行います。つまり、画面遷移によって通信が発生しません。よって、初めにS3のAPにアクセスしたタイミングでAPの容量分の通信が発生します。
        • APアクセス数/1000 x 0.05USD + AP容量 x 0.023USD
      • 料金の目安
        • 最初の 50 TB/月 0.023USD/GB
      • Angularで開発したAPの容量
        • がっつり機能を具備したAPで容量は20MB程度でした
        • 50TBを超えるには相当人気が出ないと無理です
    • Tips: コスト削減方法

      • APの設計により、通信を減らす
        • 前述したように、フロントをMPAではなく、SPAで開発することで画面遷移に伴う通信を削減可能です
      • CloudFrontでキャッシュ
        • アクセスの多いリージョンからS3へのアクセスを軽減できます
        • S3を使う場合はこれを利用するのが一般的です

APをS3で公開するまでの流れ

以下の流れで解説します

  1. Build
  2. S3バケットを生成
  3. デプロイ

APを更新する度に手動でデプロイするのはイケてないので、その後の自動化方法も別記事で解説しています。

Angular APをBuild

まずはアプリを本番環境で動く状態にします

  • ng buildコマンド

    • プロジェクト配下に/distフォルダを生成
    • コンパイルされたアプリ一式が格納される
      1
      ng build --prod
  • 生成されたフォルダ

    • angular pj直下にdistフォルダができています
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      your-app> ls

      Mode LastWriteTime Length Name
      ---- ------------- ------ ----
      d----- 2020/06/05 17:00 dist
      d----- 2020/02/04 11:15 e2e
      d----- 2020/06/05 15:42 node_modules
      d----- 2020/05/08 9:25 src
      -a---- 2020/02/04 11:15 246 .editorconfig
      -a---- 2020/02/04 11:15 631 .gitignore
      -a---- 2020/04/13 9:53 3905 angular.json
      -a---- 2020/02/04 11:15 429 browserslist
      -a---- 2020/02/04 11:15 1025 karma.conf.js
      -a---- 2020/04/07 13:58 482680 package-lock.json
      -a---- 2020/04/07 13:58 1480 package.json
      -a---- 2020/02/04 11:15 1029 README.md
      -a---- 2020/02/27 21:35 276 tsconfig.app.json
      -a---- 2020/02/27 21:35 575 tsconfig.json
      -a---- 2020/02/04 11:15 270 tsconfig.spec.json
      -a---- 2020/02/04 11:15 1953 tslint.json
  • 中身

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    your-app\dist\your-app> ls


    Mode LastWriteTime Length Name
    ---- ------------- ------ ----
    -a---- 2020/06/16 18:52 445686 3rdpartylicenses.txt
    -a---- 2020/06/16 18:52 948 favicon.ico
    -a---- 2020/06/16 18:53 1001 index.html
    -a---- 2020/06/16 18:53 3344584 main-es2015.c5b9e425026ef7fc731a.js
    -a---- 2020/06/16 18:53 3478180 main-es5.c5b9e425026ef7fc731a.js
    -a---- 2020/06/05 17:01 37074 polyfills-es2015.b94e8feb7a16d6790318.js
    -a---- 2020/06/05 17:01 129383 polyfills-es5.b220e907c509a1aa6f0d.js
    -a---- 2020/06/05 17:00 1485 runtime-es2015.c5fa8325f89fc516600b.js
    -a---- 2020/06/05 17:00 1485 runtime-es5.c5fa8325f89fc516600b.js
    -a---- 2020/06/16 18:52 64154 styles.5a9f2f959a54b18f5f2f.css

S3バケットの作成

Buildしたソースコードを置くバケットを作ります

  • AWS Consoleにログイン

  • サービスよりS3を選択

  • バケットを作成するを選択
    S3画面

  • 一意なバケット名とリージョンを指定
    バケット作成/名前とリージョン
  • バージョニング

    • Git等でソースを管理しているのであれば、無効でOK

    • Tags

      • AWS運用の基本的原則として、最低限以下は付けましょう。AWSのリソースのコストはTagをつけておくことで追跡しやすくなります。
        • PJ: PJ名
        • Own: リソースの管理者

      バケット作成/バージョニング

  • アクセス許可の設定

    • 一先ずデフォルトでOK

      バケット作成/アクセス許可の設定

  • バケットを作成

アクセス権限を変更する際には適宜このバケットの設定を弄ってください

S3にHosting(アプリを公開)

S3にソースをアップロード

先ほど作成したS3バケットにBuildしたAngularのソース(/dist/your-app配下)を置きます

  • AWS Console/サービス/S3より任意のバケットのページを開く

  • アップロードを押下
    Bucket

  • ファイルを追加

    • /dist/your-app配下のファイル群をドラック&ドロップ or ファイルを追加で選択

upload

  • アップロードを押下
    • 以上でアップロードが始まります

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

S3にアップしたソースを公開します

  • AWS Console/サービス/S3より任意のバケットを選択
  • 右に表示されるバケット情報欄の”アクセス権限”を選択

ブロックパブリックアクセス

  • ブロックパブリックアクセスタブの”編集”を押下
    Blockpublic access

  • 全てのブロックのチェックを外す

    • 保存

バケットポリシーを変更

  • バケットポリシータブを選択
    policy

  • 画面のエディターにポリシーを記載して保存

    • 特に絞らず公開する場合の例
    • “Resource”のarnは自分のbucketのものに変更してください
1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::angular-sample-bucket/*"
}
]
}

プロパティの変更/Static website hosting

  • バケット内のプロパティタブ ⇒ Static website hostingを選択
    property

  • ”このバケットを使用してウェブサイトをホストする”

    • インデックスドキュメントに”index.html”を入力して保存

Static website hosting

  • URLの確認方法
    • Static website hostingより確認
  • URL
    • 以下のように一意に定まります
      1
      http://<bucket-name>.s3-website-<select-region>.amazonaws.com

S3で公開したAPのアクセス制限

 開発したAPを社内公開する際、イントラからのアクセスに絞るケースが多いと思うので解説しておきます。

  • バケットポリシーにIPアドレスの制限をかけることで絞れます

    • Conditionで許可するIPを書き足すだけ
      1
      2
      3
      4
      "Condition" : {
      "IpAddress" : {
      "aws:SourceIp": "xxx.xxx.xxx.xxx/xx"
      }
  • 記載例

    • アクセスを許可するIPをSourceIpとして定義
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      {
      "Version": "2012-10-17",
      "Statement": [
      {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket/*",
      "Condition" : {
      "IpAddress" : {
      "aws:SourceIp": "xxx.xxx.xxx.xxx/xx"
      }
      }
      ]
      }

デプロイの自動化(CI/CD)の検討

APを改修する度に手動でS3へデプロイするのは面倒なので自動化しましょう。やり方は沢山あり、ぱっと思いつくだけでも以下があります。

  • 実現方法

    • Github Actionsを使用
    • Code PipelineとCode Buildを使用
    • ng deployに設定
    • JenkinsやCircleCIを使用
  • 色々試した結果、最も使い勝手が良いのはGithub Actionsだと思います。詳細は以下の記事にまとめてあります。

  • 何故Github Actionsが優れているか?

    • Githubで完結
      • 他のツールと組み合わせる手間が無いのは大きいです
    • 費用面
      • 基本無料で使える
    • 再利用性
      • ymlファイルで自動化するワークフローを定義するのですが、これをgitでソースと一緒に管理できます。つまり、同じようなケースでファイルをコピーするだけで使いまわすことができます。
    • 学習コストの低さ
    • サードパーティーの公開Action
      • よくあるパターンのテンプレートは大体既に用意されています
      • まさに今回やりたいS3へのデプロイの自動化を実現するActionも既にありました

Tourble Shooting: 404でAPにアクセスできない

404

  • 以下を確認してください
    • bucket直下にindex.htmlが入っているか?
    • /dist配下のフォルダ毎まるまるupしてしまうと読み込めません
    • /dist/your-app配下のファイル群をUpしましょう

参考

関連記事

S3

@EventEmitter @Input @Output @ViewChild ACM AMP API Gateway AR AR.js AR.js Studio AWS AWS Amplify AWS Budgets AWS Cost Explorer AWS SDK for JavaScript AddThis Adobe XD Alexa Amazon CloudWatch Amazon Honycode Amazon SNS Android Angular Angular Material AngularFire AppSync Augury C CDN CI/CD Cloud Craft Cloud9 CloudFormation CloudFront CloudTrail Cognito Cost Anomaly Detection Cubase ai Cubasis LE DTM Disqus DynamoDB Elgato HD 60S Firebase Firebase Hosting Former2 Github Github Actions Github.com GithubEnterprise GithubPages Google Chrome Google Cloud Shell GraphQL Hexo Hosting IAM Ionic JSON JavaScript LadioCast Logging LowCode MFA MS Authentication MacBook Pro 16 Mind Node NETDUETTO Netflix Party Netlify Network NoCode Observable PO PdM Promise RPA ReactiveForm Recognition Route53 S3 SAM(Serverless Application Model) SAR SSL SYNCROOM Schematics ScrumInc Serverless Service Siri Sitemap Spark AR Steinberg UR44C Teams Touch Cast Studio Treetable TypeScript UI UI Bakery WAF WAFv2 WEB Page Dev WEB会議 WebAR WebSocketAPI Webhook Windows Power Automate Wireshark aot async/await aws config cloud9 display.land draw.io e2e test filter() forkJoin() google search console hexo-generator-amp iOS iPad Pro iPhone icarus map() mat input mat tree mat-checkbox mat-input mat-selection-list mmhmm ngFor plantUML popIn Aladdin2 then() vscode ”global is not defined” らくがきAR アジャイル アジャイル開発 クロスプラットフォーム ショートカット スクラム スクラム開発 テレワーク ファイル操作 ブラウザ型IDE プロダクトオーナー プロダクトマネージャー プロトタイピング リモートセッション 共同開発 双方向データバインディング 待ち合わせ処理 認定スクラムマスター 静的WEB Hosting 静的WEBサイトHosting
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×