Ruby on Rails アプリをAWSにアップするまで

Webアプリ初心者がはじめてrailsアプリをAWSへアップするまでの作成日記
作成中のサイト
https://www.drink-app.club/

  • ID:admin
  • pass:test0108

https://github.com/katsun0921/drink-app-rb

参考サイト

@iwaseasahi さんのページを参照すればだいたいAWSへのアップはいける

はまったところ

ruby2.5.0でやったらDeviseでSyntaxErrorとなった。

バグらしいので修正が必要だった

SyntaxError: /.../devise-3.5.5/app/controllers/devise/sessions_controller.rb:5: syntax error, unexpected '{', expecting keyword_end
...ter only: [:create, :destroy] { request.env["devise.skip_tim...

ここをコードを修正

prepend_before_filter only: [:create, :destroy] { request.env["devise.skip_timeout"] = true }
prepend_before_filter(only: [:create, :destroy]) { request.env["devise.skip_timeout"] = true }

nginxでrestartが反映されない?

修正ファイルをgit hubからpull したら、反映されずというかDNSが切れた
なぜ?
どうやらnginxだとrestartではなくreloadだとうまくいく
http://abyssluke.hatenablog.com/entry/2015/12/11/203707

sudo nginx service reload

でうまくいかなかったらreload

sudo nginx -s reload

develop環境だと画像が表示されるのに、producton環境だと画像が表示されなくなった?

ローカル環境でのvagrantだと画像は、表示されるのにAWSにアップしたら表示されない?
assets/images 配下に画像をおいていた

background: url(/assets/images/hoge.jpg)

この書き方だとパスの書き方が間違っていたっぽい

https://qiita.com/wadako111/items/03bc00d914e62243a511

このページを参考にして画像をpublicへ変更したら解決

/public/images/

に画像をおいて画像パスを変更

background: url(/images/images/hoge.jpg)

assetsにあるcssは変更したらプリコンパイルを忘れず

bundle exec rake assets:precompile RAILS_ENV=production

続きを読む

S3の暗号化

S3でのデータ保護は2パターン

  • 転送時(S3との間での送受信)

    • SSLを使用
    • クライアント側で暗号化

      • AWS KMSで管理されたCMK(カスタマーマスターキー)を使用

        • KMS CMK IDを使用
      • クライアント側のマスターキーを使用
  • 保管時(S3データセンター内のディスクに格納されている時)
    • S3で管理されたキーによるサーバー側の暗号化SSE-S3

      • キーが定期的に更新されるマスターキーで暗号化
      • AES-256を使用して暗号化
      • オブジェクトデータのみが暗号化。オブジェクトメタデータは暗号化されない
      • x-amz-server-side-encryptionというリクエストヘッダーを使用
    • KMSで管理されたキーによるサーバー側の暗号化SSE-KMS
      • SSE-S3と同様だが下記の利点がある

        • エンベロープキーを使用するための個別アクセス制限がある。
          エンベロープキー: データの暗号化キーを保護するキー
        • いつ、誰によってキーが使用されたか監査証跡も提供されている
        • 暗号化キーを自分で作成し管理したり、ユーザー、サービス、リージョンごとに一意のデフォルトキーを使用できる
    • 自前で用意した暗号化キーによるサーバー側の暗号化SSE-C
      • S3側でAES-256を使用し暗号化される
      • S3側で暗号化キーを保存しない。代わりにランダムなSALT値を付加したHMAC値を保存する。
      • httpsを使用する必要がある
      • レスポンスのETagはオブジェクトデータのMD5ではない
        • ETag(エンティティタグ): レスポンスヘッダの1つ。キャッシュの有効性確認の手段の1つ
      • 使用した暗号化キーと暗号化したオブジェクトのマッピングはクライアント側で行う
        • バージョニングが有効時、各バージョンに独自の暗号化キーを使用出来る。
      • コンソールでオブジェクトをアップロードした場合は使えない。またSSE-Cで保存したオブジェクトの更新をコンソールですることは出来ない。

SSE = Server Side Encryption
バケット内オブジェクトを一覧表示するときに、リストAPIは暗号化されていても表示する

続きを読む

SSL encryption and Security Settings for AWS Jupyterhub

さらに表示: security settings prevent access to this property or method, need a developer to instal ssl onto my website aws, need expert setting up server security compliance, iis7 security settings, change security settings, security settings service require windows authentication enabled iis, vbulletin … 続きを読む

Setup AWS server with SSL + other related setting

さらに表示: aws server setup, setup email server aws, aws setup smtp server, smtp server setup aws, setup proxy server aws, aws setup mail server, setup web server amazon aws, setup aws server, setup php server verification email, webmin setup sendmail server, dedicated server ssl installation, … 続きを読む

AWS DMSを使ってRDS for PostgresからDynamoDBにデータ移行

はじめに

Postgresqlに保存してあったデータをDynamoDBに移行させるために、AWSのDMS(Database Migration Service)を使ってみた時の、メモをまとめた記事である。

背景

クローリングしたデータをRDS for Postgresqlに保存していて、そのデータの利用してAPI GatewayとLambdaを使ってAPIサーバを作成しようと思っていたのだが、RDSとLambdaは相性が良くないということが判明した(接続数の問題などで)。
しかも、DynamoDBを使えば、エンドポイントがつくられるので、わざわざLambdaで関数作る必要無いことに気がついたので、RDS to DynamoDBへの移行計画を立てることにした。

調べているとAWS DMSという、いかにもなサービスがあったので使ってみることにしたというのが、事の顛末である。

AWS DMSについて

AWS DMS(Database Migration Service)は、Databaseの移行を簡単に行えるサービスである。
Mysql to Mysqlのような同種DB間のデータ移行にも当然対応しているが、Postgresql to DynamoDBのような異種DB間のデータ移行にも対応している。
利用シーンとしては、オンプレのMySQLサーバをRDS for MySQLに移行する際や、RDS for PostgresqlをAurora for Postgresqlに移行する際に使用する。
また、一度だけのデータ移行にも使えるが、継続的なレプリケーションにも対応しているので、開発/テスト環境の同期などにも使うことができる。
ちなみに、Aurora、Redshift、DynamoDBに移行する場合はDMSを6ヶ月間無料で使うことができる。今回はDynamoDBに移行させるので、試すにはピッタリだった。

移行手順

1. レプリケーションインスタンスの作成

DMSでデータ移行するためにはレプリケーション用のインスタンスを作成する必要がある。
これは、DMSの設定画面から簡単に設定できる。

AWSコンソールから
「Database Migration Service >> レプリケーションインスタンス >> レプリケーションインスタンスの作成」
を選択。

すると以下のような画面が出てくる。
image.png

  • 名前:

    • レプリケーションインスタンスの名前
  • 説明:
    • レプリケーションインスタンスの説明
  • インスタンスクラス:
    • EC2でいうインスタンスタイプ
    • 2018年1月現在ではt2とc4インスタンスが選べる
    • 料金はこちら
  • レプリケーションエンジンのバージョン:
    • バージョン2.4.0を選択するとデータの検証ができるらしい
    • 古いものを選ぶ理由は今のところ無いので新しいバージョンを選ぶ
  • vpc:
    • レプリケーションインスタンスを置くvpc
    • 移行元か移行先どちらかのvpcに置くと色々と楽
      • ちなみに、移行元か移行先のどちらかがAWSサービスでないとDMSは使用できない
  • マルチAZ:
    • レプリケーションインスタンスをマルチAZ配置にする場合有効にする
  • パブリックアクセス可能:
    • レプリケーションインスタンスをインターネットアクセス可能にする場合有効にする
    • VPCでサブネットやインターネットゲートウェイをしっかりと設定しているのであれば有効にする必要がない(はず)

2. ソースエンドポイントの作成

ソースエンドポイントでは移行元のDBへのアクセス方法を設定する。
今回はRDS for Postgresqlが移行元DBになる。

AWSコンソールから
「Database Migration Service >> エンドポイント >> エンドポイントの作成」
を選択。

すると以下のような画面が出てくる
image.png

  • エンドポイントタイプ:

    • ソースかターゲットを選択
    • 移行元がソースなので、ここではソースを選択
  • エンドポイント識別子:
    • 作成するエンドポイントの名前
    • 同じ名前のエンドポイントは作成できない
    • 名前が同じでなければなんでも良い
  • ソースエンジン:
    • 移行元のデータベースエンジン
    • 今回はPostgresqlなので、postgesを選択
  • サーバ名:
    • 移行元のサーバ名
    • オンプレの場合であれば、そのサーバのアドレス
    • RDSであれば、インスタンスのエンドポイントを入力すれば良い
  • ポート:
    • 移行元DBのポート番号
    • 今回はPostgresのデフォルトポートの5432を入力
  • SSLモード:
    • 移行時の通信を暗号化するかを選択する
    • SSLを有効にした場合には、安全にはなるがオーバーヘッドが増えるので必要化判断して有効化すること
    • 選択した項目によりサーバ証明書が必要になる
    • 選択項目は以下の4つ
      • none: 暗号化しない
      • require: 暗号化される。証明書は不要。
      • verify-ca: 暗号化される。証明書が必要。
      • verify-full: 暗号化される。証明書とサーバのホスト名が一致するか確認される
  • ユーザ名
    • 移行元DBのユーザー名
    • ここでマスターユーザを選択しないと色々と面倒なので、マスターユーザを選択すること
  • パスワード
    • 先程選択したユーザのパスワード
    • 「&」や「+」のような記号はエスケープしないと使えない
    • 「&」や「+」が入る場合は全てを波括弧「{}」で括ること
  • データベース名
    • 移行したいデータベース名

一通りの設定をした後、接続テストができる。
ここで接続する元は、先程作成したレプリケーションインスタンスになるため、セキュリティーグループやファイアーウォールでアクセス制限をしている場合は、レプリケーションインスタンスがアクセスできるようにする必要がある。

3. ターゲットエンドポイントの作成

こちらでは移行先のDBのアクセス方法を設定する。
今回の移行先はDynamoDBになる。

設定方法は基本的にソースエンドポイントと同じだが、ターゲットエンドポイントにDynamoDBを設定した場合には、サービスのアクセスロールだけ指定すれば簡単に設定することができる。

AWSコンソールから
「Database Migration Service >> エンドポイント >> エンドポイントの作成」
を選択。

エンドポイントタイプをターゲットを選択し、ターゲットエンジンをDynamoDBにすると、以下のような画面が出てくる。
image.png

  • エンドポイント識別子:

    • エンドポイントの名前
    • 既に作成済みのエンドポイントと重複しなければ良い
  • ターゲットエンジン:
    • 移行先のデータベース
    • 今回はdynamodbを選択
  • サービスへのアクセスロールのARN
    • DynamoDBのアクセス権限があるIAM RoleのARN
    • ポリシーは細かく設定できるけど、めんどくさかったので以下のポリシーをアタッチ
      • AmazonDynamoDBFullAccess
      • AmazonDMSVPCManagementRole(いらないかも…?)

これも、必ず接続テストを行うこと。
DynamoDBに関しては、設定したロールが正しいアクセス権限を持っていれば問題なく接続できる(はず)

4. タスクの作成

移行するための最後の設定としてタスクを作成する。

AWSコンソールから
「Database Migration Service >> タスク >> タスクの作成」
を選択。

すると以下のような画面が出てくる。タスクの設定だけはちょっと長いので分割して説明する。
image.png

  • タスク名:

    • タスクの名前
    • これはなんでも良い
  • レプリケーションインスタンス:
    • このタスクで使用するレプリケーションインスタンス
    • 今回は 1. で作成したものを使用する
  • ソースエンドポイント:
    • このタスクの移行元となるエンドポイント
    • 今回は 2. で作成したものを使用する
  • ターゲットエンドポイント:
    • このタスクの移行先となるエンドポイント
    • 今回は 3. で作成したものを使用する
  • 移行タイプ:
    • このタスクで継続的にデータのレプリケーションを行うか設定する
    • 項目は以下の3つ
      • 既存のデータを移行する

        • 初回の移行のみ実行する
      • 既存のデータを移行し、継続的な変更をレプリケートする
        • 初回の移行を実行し、その後も継続的にレプリケートされる
      • データ変更のみをレプリケートする
        • データ変更のみをレプリケートされる
        • 通常、同種DB間の移行にのみ適用されるらしい
        • どういう時に使うかはよくわからなかった
    • 今回は、一度だけ移行ができれば良いので、「既存のデータを移行する」を選択
  • 作成時にタスクを実行
    • タスクの作成と同時にタスクを実行したければチェックをつける

次はタスク設定の画面
image.png

  • ターゲットテーブル作成モード:

    • タスク実行時に移行先のテーブルをどうするかを設定する
    • 設定項目は以下の3つ
      • 何もしない

        • 移行先にテーブルがない場合作られる
      • ターゲット上のテーブルをDROP
        • 移行先のテーブルを全部DROPする
      • TRUNCATE
        • メタデータに影響を与えないよう、TRUNCATEされる
  • レプリケーションにLOB列を含める:
    • データ移行の際にLOB(Large Object)を含めるか設定する
    • 画像をバイナリで保存している際などに、そのデータを移行するか設定する
    • 以下の設定項目がある
      • LOB列を含めない

        • LOB列を移行対象から外す
      • 完全LOBモード
        • サイズに関係なくLOB列を移行対象に含める
        • チャンク単位で送信するため、低速
      • 制限付きLOBモード
        • 次で設定する最大LOBサイズ以上のデータを削除して送信する
        • 完全LOBモードに比べると高速
  • 最大LOBサイズ(KB):
    • レプリケーションにLOB列を含めるに制限付きLOBモードを選択した時の最大LOBサイズ
  • 検証の有効化:
    • 移行元と移行先でデータを比較し検証するかどうかを選択する
  • ロギングの有効化:
    • 移行時のログをCloudWatch Logsに吐くかを選択する

最後にテーブルマッピングの設定
image.png

  • 選択ルールを設定する。
  • このルールに基いて、除外するテーブルやカラムを決定する。
  • ワイルドカードを使用できるので、まぁまぁ柔軟に設定できそう。
  • 最低一つは設定しなければいけないっぽい。
  • 一旦、デフォルトの状態のまま選択ルールの追加する。
  • 選択ルールを一つでも追加すると、変換ルールも追加できるようになる。
    • 名前の変更とか、テーブルや列の削除しかできないので、結構限定的。

以上が全て設定できたら、タスクの作成ボタンを押下。
「作成時にタスクを開始」にチェックが入っている場合にはすぐにタスクが実行される。

所感

実際にAWS DMSを使ってみて、かなり簡単に異種DB間のデータ移行を実現することができた。
データ量もあまり多くなかったため、10分程度で全てのデータ移行が完了していた。
コストも今回は無料だったし、実際に課金されても低コストで使用することができそう。

実際にDynamoDBを見てみるとPostgresqlにあったテーブルが作成されていた。
しかし、いくつかカラムが消えていたので、まだ調査が必要そうだ(LOB列と判断された…?)。

参考

続きを読む

【完結編】AWS Amazon SageMaker つかってみた4 〜GPU利用でサンプルの実行〜

はじめに

Amazon SageMaker を利用する上で自分が気になったところ、詰まったところを中心にまとめていきます。
この記事では前回の記事で失敗したサンプルの実行について再度まとめます。
前回の記事はこちら
次回の記事は作成中

サンプルの場所

Jupyterの導入については前回の記事を参照

  1. Jupyterのホーム画面を開きます。
  2. sample-notebooks ディレクトリを開きます。
  3. sagemaker-python-sdk ディレクトリを開きます。
  4. mxnet_gluon_cifar10 ディレクトリを開きます。
  5. cifar10.ipynb ファイルを開きます。

サンプルの実行

Jupyter NotebookにはPythonのコードと説明が含まれます。
右に In [ ]: と書かれているのがコードで、それ以外は説明です。

サンプルについて

  • 用いるデータセット: CIFAR-10という6万枚の画像データのデータセット
  • 学習内容: 34層の深層学習により画像を10種類にクラスタリングする。

セットアップ

scikit-image のライブラリが必要なのでcondaのページから入れてください。

  1. conda tab のリンクをクリックするか、Jupyterのホームから Conda のタブをクリックします。
  2. Available packages のところのSearchで scikit-image を検索します。
  3. scikit-image を選択します。
  4. 右矢印を押下してインストールします。

はじめのpythonコードを実行してみましょう。
以下のコードを選択して、画面上部の Cell から Run Cells を選択します。

import os
import boto3
import sagemaker
from sagemaker.mxnet import MXNet
from mxnet import gluon
from sagemaker import get_execution_role

sagemaker_session = sagemaker.Session()

role = get_execution_role()

右の表示が In [*]: に変わります。
* は実行中であることを表します。
実行が終わると In [1]: のような表示になります。
数字は実行された順番を表します。

初めて実行すると以下のWarningが表示されます。
こちらの原因と解消方法を知っている人がいれば教えてください。

/home/ec2-user/anaconda3/envs/mxnet_p27/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py:46: DeprecationWarning: OpenSSL.rand is deprecated - you should use os.urandom instead
  import OpenSSL.SSL

もう一度実行するとWarningが消えます。

データのダウンロード

CIFAR10をダウンロードします。

from cifar10_utils import download_training_data
download_training_data()

少し時間がかかります。

データのアップロード

Amazon SageMakerで学習させるにはまずS3に学習データをアップロードする必要があります。
S3へデータをアップロードするには sagemaker.Session.upload_data の関数を使います。
戻り値の inputs にはアップロード先のIDが入っており、後ほど学習の際に利用します。

inputs = sagemaker_session.upload_data(path='data', key_prefix='data/gluon-cifar10')
print('input spec (in this case, just an S3 path): {}'.format(inputs))

train 関数の確認

SageMakerで利用可能な学習スクリプトを用意する必要があります。
学習スクリプトは train 関数として実装されている必要があります。
学習環境の情報が train 関数の引数として渡されます。

!cat 'cifar10.py'

学習スクリプトの実行

MXNet クラスを用いると分散環境での学習が可能です。
以下の設定をします。

  • 学習スクリプト
  • IAMロール
  • インスタンス数
  • インスタンスタイプ

デフォルトでは2個の ml.p2.xlarge インスタンスで学習ができるように設定されています。
3行目の train_instance_count の値を 1 に変更して1個のインスタンスで学習するように変更してください。(理由は考察の項目を参照)
※GPUインスタンスはデフォルトで使用制限があります。制限解除方法についてはこちらの記事にまとめています。

m = MXNet("cifar10.py", 
          role=role, 
          train_instance_count=1, 
          train_instance_type="ml.p2.xlarge",
          hyperparameters={'batch_size': 128, 
                           'epochs': 50, 
                           'learning_rate': 0.1, 
                           'momentum': 0.9})

MXNet クラスができましたので、アップロードしたデータを使って学習を開始します。

m.fit(inputs)

学習がスタートしました。
現在実行中の学習はAmazon SageMakerのジョブの画面で確認できます。
学習時間は44分でした。 ml.p2.xlarge が1時間\$1.26ですので学習にかかった費用は\$1ほどです。

予測

学習が終わりましたので学習結果を使ってエンドポイントを作成します。
学習ではGPUインスタンスを利用しましたが、エンドポイントではCPUのインスタンスも利用できます。

deployの戻り値のpredictorオブジェクトでエンドポイントを呼び出してサンプル画像の予測ができます。

predictor = m.deploy(initial_instance_count=1, instance_type='ml.m4.xlarge')

CIFAR10のサンプル画像

サンプル画像でCIFAR10のテストをします。

# load the CIFAR10 samples, and convert them into format we can use with the prediction endpoint
from cifar10_utils import read_images

filenames = ['images/airplane1.png',
             'images/automobile1.png',
             'images/bird1.png',
             'images/cat1.png',
             'images/deer1.png',
             'images/dog1.png',
             'images/frog1.png',
             'images/horse1.png',
             'images/ship1.png',
             'images/truck1.png']

image_data = read_images(filenames)

predictorは入力された画像を予測して結果のラベルを返します。
ラベルはfloat値で返ってくるのでintに変換してから表示しています。

for i, img in enumerate(image_data):
    response = predictor.predict(img)
    print('image {}: class: {}'.format(i, int(response)))

リソースの開放

このサンプルの実行が終わったらインスタンスを開放してエンドポイントを削除するのをお忘れなく。

sagemaker.Session().delete_endpoint(predictor.endpoint)

結果

正解率80%

image 0: class: 0
image 1: class: 9
image 2: class: 2
image 3: class: 3
image 4: class: 4
image 5: class: 5
image 6: class: 2
image 7: class: 7
image 8: class: 8
image 9: class: 9

考察

GPUの圧倒的な処理速度

GPUが得意な画像処理ということもあり60倍程度の処理速度が出ていた。

インスタンスタイプ 1秒間に処理できるサンプル数
ml.m4.xlarge 約 22 サンプル/秒
ml.p2.xlarge 約 1400 サンプル/秒

単位時間あたりはCPUよりGPUの方が高いが、処理速度が段違いなので結果的にGPUを使うほうが安上がりになる。

並列処理の同期のオーバヘッドが大きい

MXNetでは1回の学習ごとに各インスタンス間で同期を取っているようです。
単体のインスタンスで学習をさせたところ1秒間に11回の学習ができたのに対し、2並列で学習させた場合は毎秒各インスタンス1回ずつの合計2回しか学習ができませんでした。
分散学習をさせると性能が1/5に低下してしまいます。

インスタンスタイプ 1秒間に学習できる回数
単体(同期なし) 約 11 回/秒
2並列(毎回同期) 約 2 回/秒

今回の学習では1回の学習に要する時間が0.1秒以下の学習であったために毎回同期を取らないといけない並列処理のほうが遅くなる結果となってしまった。

SageMakerのいいと感じたところ

ワンストップで実行可能

ノートブックの作成、リソースの確保、学習、エンドポイントの作成までワンストップで行える。

リソースの最適化

ノートブック、学習、エンドポイントでそれぞれでインスタンスを選択できる。
学習は学習している間だけ料金が発生する。

続きを読む

Expected response code 220 but got code "", with message ""

Mailerがエラーしてる

Laravelのメーラーを使おうとするとエラーでる。

基本的には、smtpなどの設定見直せばいける

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=your_address@gmail.com
MAIL_FROM_NAME=your_name
MAIL_USERNAME=your_address@gmail.com
MAIL_PASSWORD=your_password
MAIL_PRETEND=false

このアドレスとパスワードを自分のものに書き換えれば大丈夫。

AWSの場合は少し面倒

僕の環境下は、AWSでの送信を試みていたので、ちょっと面倒な感じに。
まずは、AWSからメールが送信できるように、設定しないといけない。

多分だけど、AWS→他サービスのサーバー→メール
みたいな感じで、経由するのは厳しそう。多分。

↓を参考にして欲しい。
独自ドメインのメール送受信をAWSで。メールサーバーレスアーキテクチャーを構成

続きを読む

AWS CloudFrontとLambda勉強まとめ

CloudFront

CDN
– Contents Delivery Network
– エッジのキャパシティを利用して効率的かつ高速にコンテンツ配信
→ユーザに最も近いサーバに誘導して、配信を高速化
→エッジサーバではコンテンツのキャッシングを行い、オリジンに負荷をかけない

・最適なエッジへの誘導方法
①ドメイン名問い合わせ(クライアント→DNS)
②IPアドレス問い合わせ(DNS→CloudFrontDNS)
③最適なEdgeアドレス応答(CloudFrontDNS→DNS)
④最適なEdgeへアクセス(クライアントからEdge)
⑤キャッシュがある場合:コンテンツ配信
キャッシュがない場合:オリジンサーバから取得

・CloudFront特徴
– 84拠点のエッジサーバ
– 予測不可能なスパイクアクセスへの対応
– ビルトインのセキュリティ機能(WAF連携、DDoS対策)
– 充実したレポート

・動的コンテンツ:ELBでEC2に負荷分散。HTML
静的コンテンツ:S3などで保存

・84エッジロケーション→11リージョナルキャッシュ→オリジン
→オリジンに対するコンテンツ取得を削減

CloudFront Distribution
– ドメインごとに割り当てられるCloudFrontの設定
– 40Gbpsもしくは100,000RPSを超える場合上限申請必要
– HTTP/2対応
– IPv6対応
– CNAMEエイリアスを利用して独自ドメイン名の指定可能
→Route53と合わせたZone Apex(wwwがないもの)も利用可能

Gzip圧縮機能
エッジでコンテンツをGzip圧縮することでより高速にコンテンツ配信
※S3はGzip圧縮をサポートしていないので有効

キャッシュコントロール
– キャッシュヒット率の向上がCDNのポイント
→URLおよび有効化したパラメータ値の完全一致でキャッシュが再利用

キャッシュの無効化
コンテンツごとの無効化パス指定

ダイナミックコンテンツ機能
オリジンサーバに対して下記情報をフォワードすることで、動的なページの配信にも対応
– ヘッダー(必要最小限)
– Cookie(Cookie名と値をセットでCloudFrontがキャッシュ)
– クエリ文字列パラメータの値

ダイナミックキャッシング
リクエストパターンをもとにオリジンへのアクセスルールを個別指定可能

カスタムエラーページ
4xx系:クライアントエラー。オリジン側で対処
5xx系:サーバエラー。CloudFrontで対処
参考URL:https://goo.gl/NcUQiY

読み取りタイムアウト
CloudFrontがオリジンからの応答を待つ時間を指定
デフォルトは30秒

キープアライブタイムアウト
接続を閉じる前に、CloudFrontがオリジンとの接続を維持する最大時間
デフォルトは5秒

・セキュリティ
– HTTPS対応
– SSL証明書
→専用IPアドレスSSL証明書には申請必要
ビューワーSSLセキュリティポリシー
→クライアントとCloudFront間のSSL/TLSプロトコルとCipherの組み合わせを指定可能
– オリジン暗号化通信
– オリジンカスタムヘッダー
GEOリストリクション
→地域情報でアクセス判定。制御されたアクセスには403を応答
署名付きURL
→プライベートコンテンツ配信。
→署名付きURLを生成する認証サイトにクライアントから認証リクエスト
→認証サイトからEdgeにアクセス※署名付き出ない場合は、403を返す
-オリジンサーバーの保護
→Origin Access Identitiy(OAI)を利用
S3のバケットへのアクセスをCloudFrontからのみに制限
– AWS WAF連携
AWS ShieldによるDDoS攻撃対策
ブロック時は403応答
– AWS ShieldによるDDoS攻撃対策
デフォルトで有効

・CloudFrontレポート・アクセスログ機能
任意のS3バケットに出力可能

・CloudWatchアラームの活用
リアルタイム障害・異常検知

・S3オリジン自動キャッシュの無効化(Invalidation)
S3にアップロード→Lambdaファンクション呼び出し→CloudFront Invalidation APIの呼び出し→CloudFront上でキャッシュの無効化

Lambda

高度にパーソナライズされたウェブサイト
ビューワーリクエストに応じたレスポンス生成
URLの書き換え
エッジでのアクセスコントロール
リモートネットワークの呼び出し

参考URL:https://www.slideshare.net/AmazonWebServicesJapan/aws-blackbelt-online-seminar-2017-amazon-cloudfront-aws-lambdaedge

続きを読む

CloudWatch カスタムメトリクスの料金計算

CloudWatchのカスタムメトリクスについて、料金計算が分かりづらかったので確認した

AWSで特にEC2を使用している場合、なにかとCloudWatchを使うことはあるのではないでしょうか?
そして、少し前に新しいCloudWatch Agentもリリースされ、今まで以上にカスタムメトリクスを使用する機会も増えました。

そこで、様々なカスタムメトリクスの使い方を考慮して、その見積りをするべく料金を確認したところ、分かりにくい点があったため、調査をしました。

まずは結論から

CloudWatch へのメトリクスの送信 (PutMetricData API) が行われていた時間の割合で計算され、1時間の間に1度以上の送信があった時間が課金対象となります。

例えば、1つのカスタムメトリクスを 1週間 (168 時間)、1時間毎に送信した後に送信を止めた場合、1か月は 720時間(30日の場合)となりますので、$0.3 * 168/720 = 0.069999 と、約 $0.07 が課金の対象となります。

調査の背景

カスタムメトリクスについての料金ですが、料金のページに下記のような記載があります。

Amazon CloudWatch のカスタムメトリクス
$0.30 メトリクスあたり/月 (最初の 10,000 メトリクス)
$0.10 メトリクスあたり/月 (次の 240,000 メトリクス)
$0.05 メトリクスあたり/月 (次の 750,000 メトリクス)
$0.02 メトリクスあたり/月 (1,000,000 メトリクス以上)

こちらの記事によると、10,000メトリクスまではメトリクスあたり月$0.3とのことです。

一見とても分かりやすい料金体系です。

本当にそうでしょうか?

私のAWS環境の12月度の請求書(既に1ヶ月丸々使用済みの環境)の 「$0.30 per metric-month for the first 10,000 metrics – Asia Pacific (Tokyo)」の項目のメトリクス数は、小数点以下が3桁まで表示されていました。
仮に、保有メトリクスの数が対象となるのであれば、このメトリクス数は整数値になるはずです。

AWSサポートに確認しました。

本件、たまたま担当された方が知識不足だったのか分かりませんが、最初の回答として、「保有メトリクス数x$0.3」であり、月の途中から使用した場合、時間数により按分されるため、保有メトリクス数が小数点以下になることがあるという説明でした。

しかしこの説明が正しい場合、メトリクスを削除できない ことから、一度でもメトリクスデータを送信したらその後ずっと$0.3が課金されることになります。

その点について、指摘し再度確認を行ったところ、冒頭の結論に記載したとおりの料金である旨、訂正した説明が送られてきました。

CloudWatch カスタムメトリクスのコストパフォーマンスのよい使い分け

これらの調査結果から、カスタムメトリクスは3600秒毎に課金が発生することが分かりましたので、
1分に1回データを送信するのも1時間に1回送信するのもカスタムメトリクスの料金としては同じです。 1
メモリ使用率などのメトリクスデータを監視する目的で使う場合は、数時間単位で確認するよりも数分単位で確認するほうが現実的だと思いますので、質の高いデータにするためには60秒間隔などで送るのがよいでしょう。

SSL証明書の監視 を行うような場合、1日1回確認することでよいため、1ドメインの料金は、30 / 720 * 0.3 ≒ $0.013 となります。
つまり、1カスタムメトリクスの月額料金分で24ドメインが監視対象として監視できます。
CloudWatchメトリクスにSSL証明書の残日数を送るとこんな感じでダッシュボードに並べられてとても管理しやすいです。
これが、とても安価に使えるのは良いと思います。
image.png

同様に、少し応用的な使い方として、1日毎のデータでよいメトリクス情報(売上データ、アクセス数、会員登録数のようなもの)は、使い方を考えて時間毎ではなく日毎にデータを送るようにするととても安く効果的に使用できます。


  1. 別途Amazon CloudWatch API リクエストを行うための料金(1000件のリクエストあたり$0.01)は発生します。 

続きを読む