AWS API Gateway(3)カスタムログの出力


API Gatewayは、詳細のアクセスログをCloudWatch Logsに吐き出すことができる。CloudWatch Logsへのログ書き込みを行うためには、書き込み権限の取得とログを書き込むロググループの指定が必要となる。

IAMロールの指定

IAM上でAPI GatewayからCloudWatch Logsへの書き込み許可を持つIAMロールを作成する。IAMでは、あらかじめAmazonAPIGatewayPushToCloudWatchLogsと呼ばれるポリシーが用意されているため、このポリシーがアタッチされたIAMロールを作成する。この作成したIAMロールをAPI Gatewayの設定画面上で指定することで、API GatewayはCloudWatch Logsへの書き込み権限を取得する。

ログの指定

次にAPI Gateway上の各APIのログ/トレース設定画面にて、カスタムアクセスのログ記録を有効化する。入力項目は、CloudWatchロググループのARNと、ログ形式の2種類。ログ形式は、JSONやCLFなどの中から選ぶと自動的に入力される。

AWS API Gateway(2)Kinesisへのデータ投入

API Gatewayから大量のデータを投入し、これらのデータを解析および蓄積する場合には、API GatewayからLambdaに直接データを渡すのではなく、大規模データストリームサービスのKinesisを介した方が、バックエンドのシステムが高負荷に晒されずに安定的に稼働させられる場合がある。

API Gatewayとバックエンドのエンドポイントとの接続は、API Gateway内の統合リクエスト機能を用いて行い、統合リクエストは下の5つの統合タイプを用意している。

  • Lambda関数
  • HTTP
  • Mock
  • AWSサービス
  • VPCリンク

Mockは、バックエンドと接続せずにレスポンスを返す統合タイプで、テストを行う際や、CROSのプリフライトリクエストの返答などに用いる。

統合リクエスト

Kinesisと接続する場合は、POSTメソッドを作成し、上記のうちの「AWSサービス」を選択して以下のように各欄に必要事項を入力する。Kinesisへデータ投入する際には、Kinesis側で用意されているputRecordメソッドを使用する。

データ入力項目

項目 入力内容 備考
統合タイプ AWSサービス
AWS リージョン 当該Kinesisのリージョン
AWS サービス Kinesis
AWS サブドメイン 空欄
HTTP メソッド POST
アクション PutRecord
実行ロール KinesisへのputRecordをAPI Gatewayに許可するIAMロール arn:aws:iam::account-id:role/iam-role-name

IAMロールについては、KinesisへのputRecordをAPI Gatewayに許可する記述が必要で、IAM上で以下の内容を含んだIAMロールを作成する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kinesis:PutRecord",
                "kinesis:PutRecords"
            ],
            "Resource": "arn:aws:kinesis:*:*:stream/*"
        }
    ]
}

データマッピング

API GatewayからKinesisにデータを投入する場合は、クライアントから受信したデータをKinesisが規定するデータフォマットに変換する必要がある。これに対応するのがデータマッピング機能で、Velocity Template Languageを用いて記述することができる。

よく使われる関数および使用例を以下に挙げる。

記述 内容
#set($param = ”) 変数の定義
#if(評価式) #end if文
$context.requestTimeEpoch データの受信時刻
$input.path(‘$.param’) 入力データ内の指定タグの値
$input.path(‘$.param’).size 入力データ内の指定タグの数
$input.params().header.get(”) ヘッダ内の指定タグの値
$input.json(‘$.param’) 入力データ内の指定タグJSONデータ
$util.urlDecode($input.path(‘$’)) 入力データをURLデコード
$util.escapeJavaScript(data) 文字をエスケープ
$util.base64Encode(data) 文字をBASE64エンコード

また、これらを使用してデータマッピングを記述すると以下となる。

#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}

AWS API Gateway(1)API Gatewayの概要

API Gatewayとは

API Gatewayは、完全マネージドのAPI作成サービス。受信したAPIコールと送出したデータ量に対して課金される。スロットリングによるトラフィック管理ができるため、DDoSやトラフィックの激増にも対応することが可能であり、リミットを超えたリクエストにはHTTPステータス 429が返却される。また、レスポンスはキャッシュ可能であり、レイテンシやトラフィック等を低減することができる。

API Gatewayは、IAMやCognitoを用いたアクセス認証署名付きAPIコールなどを使用することができるために柔軟にセキュリティ管理ができる。また、CloudWatchやCloudWatch Logsを用いた監視が可能で効率的なデバッグとモニタリングを実現している。

![API Gateway]https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/images/BackplaneArch.png

エンドポイント

API Gatewayは、特定のリージョンにデプロイされる。エンドポイントは以下の3種類がサポートされている。エンドポイントは、HTTPSのみサポートされている。

種類 内容
エッジ最適化 CloudFrontネットワークにデプロイ
リージョン リージョンにデプロイ。EC2 インスタンスまたは API と同じリージョン内のサービスから送られる場合に使用すると良い。
プライベート VPCからのみアクセス可能

リソースとメソッド

APIは階層構造となっており、リソースやメソッドをネストすることも可能。指定可能なメソッドは以下の通り。

種類 実行内容
POST 子リリースの作成
PUT 既存リソースの更新
DELETE リソースの削除
PATCH リソースの更新
HEAD テストシナリオに使用
OPTIONS 通信オプションに関する情報を取得する度に使用できる

CROSを有効にするためには、OPTIONSメソッドのプリフライトリクエストに対してAPIが応答することが必要であり、このリクエストに対して、HTTPステータス 200Access-Control-Allow-Method, Access-Control-Allow-Headers, Access-Control-Max-Ageヘッダを含んだレスポンスを返す。これらの挙動には、統合リクエスト/レスポンスのMockタイプを使用する。

リクエストに対して、 URLクエリ文字列パラメータHTTPヘッダHTTPボディを検証し、必須の項目が含まれているかやキャッシュを行うかなどを指定することができる。HTTPボディがapplication/json形式である場合は、JSON Schemaを用いてJSON形式を指定することもできる。

統合リクエスト/レスポンスとマッピングテンプレート

API Gatewayとバックエンドとを接続する内部インタフェース。マッピングテンプレートを用いることで、フロントエンド(API Gateway)とバックエンドのデータ形式を変換することができる。

  • Lambda関数の呼び出し
  • 他のAWSサービスの呼び出し
  • HTTPウェブサイトのアクセス

の3つのバックエンドへのアクセスに対応している。Lambdaプロキシ統合を用いることで、API GatewayとLambdaがより協力に結合され、リクエストヘッダやパス変数などがLambdaに渡される。また、HTTPプロキシとして使用することも可能である。

デプロイ

APIを利用可能とするためには、APIのリソースおよびメソッドのスナップショットであるAPIのデプロイを実施する必要がある。APIをバージョン管理できるために、新しいバージョンを簡単にテストしリリースすることが可能である。

1アカウント1リージョンあたりのAPIの上限は、10000RPSである。これ以上のアクセス負荷にも耐えうる値とする場合は上限緩和申請が必要となる。

AWS(4)Well-Architectedフレームワーク

フレームの柱

運用上の優秀性

設計の原則

  • 運用のコード化を行う
  • ドキュメントに注釈を付ける
  • 頻繁に小さく可逆的な変更を行う
    • システムを小さく設計
    • 失敗した場合に戻せるように
  • 運用手順を頻繁に見直す
  • 発生しうる障害を予想する
  • 運用の失敗を改善に役立てる

ベストプラクティス

  • 準備(本番環境への移行)
    • チェックリストによる検証
    • イベントと障害に対するテスト
    • CloudFormationの利用
    • CloudWatch等を利用した解析
  1. 運用の優先順位を決定する要因は明確か
  2. 運用性を向上させるワークロード設計をしているか
  3. ワークロードが運用可能であるか確認しているか
  • 運用
    • 期待されている成果、およびその測定方法を決定し、システムと運用に関するメトリクスを特定する。システムとそのシステムに対する運用の正常性の双方を考慮する。イベント対応の優先度を定めて、影響の度合いに応じて追加の担当者を巻き込むエスカレーショントリガーも含める。計画外のイベントが発生した原因と影響範囲を確認し、今後の運用に反映させるとともに、計画外のイベントであっても自動的に処理されるようにシステムの設計を行う。デプロイやリリース管理、変更ロールバックなどはマニュアルで行なってはならない。
  1. 運用状態をどのように確認しているか
  2. 運用上のイベントをどのように管理しているか
  • 進化
    システムを継続的に少しずつ改善していくことが必要。システムと運用の両方に関して改善できる部分を洗い出し、優先順位を付ける。また、チームを超えて、運用から学んだ知見を共有する。
  1. 運用をどのように進化させているか

AWSのサービス

AWS CloudFormationを用いてシステム構築を行う。またそれぞれのフェーズで以下のサービスを活用する。

フェーズ AWSサービス 目的
準備 AWS Config システム標準を作成しそれに準拠しているか確認する
運用 Amazon CloudWatch システムの運用状態をモニタリング
進化 Amazon Elasticsearch Service ログデータを分析

セキュリティ

設計の原則

  • 強固な認証基盤を整備する
  • 追跡可能性を実現する
  • 全てのレイヤーにセキュリティを適用する
  • セキュリティのベストプラクティスを自動化する
  • 転送中および保管中のデータを保護する
  • データへの直接的なアクセスや手動処理を減らす
  • セキュリティイベントに対して準備を行う

ベストプラクティス

  • アイデンティティとアクセス管理
    +

信頼性

パフォーマンス効率

コスト最適化

設計の原則

  • 必要なキャパシティを勘に頼らない
  • 本番規模でシステムをテスト
  • 自動化
  • 発展的なアーキテクチャを受け入れる
    • クラウドは自動化とテストが容易で設計変更のリスクを低減できる
    • システムを継続して進化させる
  • データ計測に基づいてアーキテクチャを決定する
  • 本番で想定されるトラブルをあらかじめテストする

AWS RDS(1)Relational Database Serviceの概要

RDSとは

RDSは、AWS内でRDBSを簡単に設定、運用、スケールできるサービスで、データベースのセットアップやパッチ適用、バックアップなどの管理タスクを自動化している。対応しているRDBSは、Amazon AuroraMySQLMariaDBOracleMicrosoft SQL ServerPostgreSQLの6種類である。一部制限事項も存在するため、この制限事項とのトレードオフが許容できない場合は、EC2上でRDBSを稼働させることも検討する。

管理負荷を軽減

RDBSにわずか数分でアクセス可能で、CloudWatchによる監視にも対応しているため、パフォーマンスの問題を簡単に検出することが可能である。また、ソフトウェアのパッチが自動的に適用されるために、常に最新の状態が維持されている。

パフォーマンス

汎用(SSD)ストレージプロビジョンドIOPS(SSD)ストレージから選択することが可能である。

スケーラビリティ

最大32vCPUおよびRAM244GiBまで拡張することが可能で、数分以内にスケーリングすることができる。また、ストレージサイズも柔軟に拡大が可能で、稼働中にダウンタイムなしに最大16TBまでストレージの拡張を行うことができる。また、リードレプリカを使用(=Amazon AuroraMySQLMariaDBPostgreSQLのみ対応)することで、読み込み負荷の高い処理をスケールアウトすることができる。

可用性と耐久性

自動バックアップ機能によって自動的(=1日に1回)に、もしくは任意の時点のスナップショットを保存することもでき最大35日(デフォルトは7日間保持)まで保存可能。また、RDは、5分に1回トランザクションログを保存しているため、これを用いて新たなインスタンスを起動(ポイントインタイムディカバリ)が可能。マルチAZ配置オプションを使用することで、異なるAZのスタンバイインスタンスにデータを複製し、可用性を向上させることができ、ハードウェア障害が発生した場合には、自動でフェールオーバされる。DNSでCNAMEが書き換えられ切り替えには数分要する。なお、スナップショット実行時は、短時間I/Oが停止することに注意が必要

セキュリティ

KMSを使用してデータベースを暗号化することが可能。また、VPC上で稼働させることで独自のネットワーク上で外部と隔離された状態で稼働できる。

AWS SNS(2)モバイルプッシュ通知

モバイルプッシュ通知

AWS SNSは、モバイルデバイスのアプリケーションにプッシュ通知メッセージを直接送信できる。通知可能なサービスは、

  • Amazon Device Messaging (ADM)
  • iOS および Mac OS X 用の Apple Push Notification Service (APNS)
  • Baidu Cloud Push (Baidu)
  • Android 用 Google クラウドメッセージング (GCM)
  • Windows Phone 用 Microsoft プッシュ通知サービス (MPNS)
  • Windows プッシュ通知サービス (WNS)

である。

プッシュ通知サービスは、登録時にデバイストークンを返すため、SNSはこのデバイストークンを元にモバイルエンドポイントを作成しプッシュ通知を行う。モバイルプッシュ通知を行うためには以下の手順が必要となる。

  1. 認証情報を上記サービスに対して要求し認証情報を取得する
  2. トークンを上記サービスに対して要求しトークンを取得する
  3. プラットフォームアプリケーションオブジェクトを作成する
  4. プラットフォームエンドポイントオブジェクトを作成する
  5. メッセージを送信する

AWS SNS(1)Simple Notification Serviceの概要

Amazon SNSについて

Amazon SNSは、マネージド型のメッセージ発行/購読サービス。SNSは、発行者からのメッセージを受信し、LambdaやSQS、Email、SMSなどの購読者に対してこれらを送信することが可能である。SNSを使用するときは、その所有者としてトピックを作成し、発行者と購読者を定義するポリシーを策定する。

SNSの流れ

トピック名は他と識別できるユニークな名称であり、発行者はこのARNを利用してメッセージをこのトピックに送信する。購読者は、送信されたメッセージを購読するかどうか判断し、購読を許可した場合に全てのメッセージが受信可能となる。発行者は、各配信先ごとに異なるメッセージを送信することも可能である。トピックの所有者は、購読情報を全て削除(クリーンアップ)することも可能となっている。

SNSの機能とシナリオ

SNSは以下のようなシナリオで動作させることができる。

ファンアウト

発行者からのメッセージをSNSが複製することで、並列非同期処理が可能となるシナリオ。並行処理を行なったり、本番環境のデータをテスト環境に入力するために使用できる。

アラートの送信

アプリケーションやシステムからの出力に対してあらかじめ閾値を定めておき、それを超えた場合にメッセージが送信される。

EメールおよびSMSの送信

特定の購読者へEメールおよびSMSの送信する。

モバイルプッシュ通知

モバイルアプリケーションへ通知を送信する。

ポリシー

所有者は各トピックに対して、「どの購読者(=プリンシパル)がどの配信先(=リソース)を受信できるか。」「どの発行者(=プリンシパル)がメッセージの発行を行えるか」などのアクションを定めることができる。ポリシーのデフォルトは拒否であるため、許可を与えるためにはポリシーを明示しなくてはならない。また、ポリシーでは、リトライ回数や遅延時間等も指定することができる。

AWS S3(4)使用する上で注意すること

パフォーマンス最適化

S3へのリクエストが100rpsを超える場合は、キー(ディレクトリ名やファイル名等)先頭部分の文字列をランダムにする。プレフィックスごとに3500rpsのPUT/POST/DELETEリクエスト5500rpsのGETリクエストを処理可能である。また、大量のGETリクエストが発生する場合には、CloudFrontを併用する。

データ整合性モデル

S3では、書き込み後の読み込み整合性を提供する。また、単一キーに対する更新はアトミックである。しかし、複数のデータセンタに複製することから、オブジェクトを書き込んだ直後に表示させると、オブジェクトが表示されなかったり、古いデータが表示されることがある。また、あるクライアントが書き込みを完了する前に別のクライアントが書き込みを始めた場合などは、整合性のある書き込み結果とならない場合もある。したがって、データベースのトランザクションログなど短時間に書き込みが連続するデータの保存には適さない

バケットの命名規則

バケット名は3文字以上63文字以内で、大文字やアンダースコア、ピリオドを含むことはできない。ハイフンは使用可能。また、バケット名は既存のバケット名の中で一意でなければならない。

ストレージクラス

S3 Standerd(低頻度アクセス)とS3(1ゾーン/低頻度アクセス)は、少なくても30日間保存する予定があり、サイズが128KB以上あるオブジェクトに最適である。

ライフサイクル

S3 Standerd(低頻度アクセス)とS3(1ゾーン/低頻度アクセス)は、現在のストレージクラスに少なくとも30日間は保存する必要がある。ライフサイクル処理は、UTC時0時に実行される。

AWS S3(3)S3の概要

S3 (Simple Storage Service)とは

S3は、どこからの、どのような量のデータ(通常100バケットまで1ファイル5TBまで)でも保存と取得が可能なオブジェクトストレージ。データは3箇所以上のデータセンタへ自動複製され、
99.999999999% の耐久性を提供している。高い耐久性、可用性、スケーラビリティー、数多くのセキュリテイ機能を持つ。AWS AthenaやS3 Selectを用いることで簡単に、S3内のデータに対してビッグデータ解析を行うことが可能で、さまざまな方法でS3へのデータ転送を行うことができる。

S3には、S3 StanderdS3 Standerd(低頻度アクセス)S3(1ゾーン/低頻度アクセス)Amazon Glacierの4つのストレージが用意されている。S3(1ゾーン/低頻度アクセス)は、地震や洪水といった災害によるアベイラビリティーゾーンの物理的な損失時にデータを失う可能性がある。*S3 Standerd(低頻度アクセス)とS3(1ゾーン/低頻度アクセス)は、他の手法で復元可能なデータや原本のコピーを保存する目的で使用する。VPCエンドポイントを用いることで、同一リージョンのVPC内からセキュアにファイル転送を行うことが可能である。また、複数の暗号化、監査ログ、バージョニングにも対応している。

S3は、キーバリュー型のストアであるので、フラットな構造であり、ディレクトリや階層構造は存在しない。フォルダやファイル名に相当するのがキーであり、スラッシュ文字によってディレクトリ構造のように見せることができる。

タイプ 堅牢性 備考
Standard 99.999999999% 3箇所以上にデータ複製
Standard(低頻度アクセス) 99.999999999% 安価だが読み出しに課金される
1ゾーン(低頻度アクセス) 99.99% 低い堅牢性。オブジェクト毎に指定可能。
Glacier 99.999999999% 取り出しに時間(3-5時間)とコストを要する

S3は、ファイルを複数のチャンクに分割して並列アップロードを行う、Multipart Uploadに対応している。ファイルサイズが100MBを超える場合は、このMultipart Uploadを使用することが奨励されている。AWS CLIでは、ファイルサイズによって自動判別されてこの機能が利用される。Glacierに格納されたデータの復元時には、迅速(Expedited)(=1-5分)、標準(Standard)(=3-5時間)、大容量(Bulk)(=5-12時間)の3種類が用意され、それぞれ実行単価が異なる。

また、静的なファイルをS3のみでホステイング可能なWEBサイトホスティング機能を有している。独自ドメインの指定クロスドメインCloudFrontとの連携なども可能。

セキュリティ

アクセス管理

S3はデフォルトでは全てプライベートアクセス権限となっている。アクセス権限は、バケットやオブジェクト単位で指定可能である。IAMユーザ単位でS3へのアクセス権限を指定できる「ユーザポリシー」(=IPアドレスも指定可能)、バケット毎にアクセス権限を指定できる「バケットポリシー」(=IPアドレスレンジやMFA等も指定可能)、バケットやオブジェクト単位で指定可能な「ACL」などが存在する。バケットポリシーは、バケットの所有者のみが設定でき、またACLは、バケットACLよりもオブジェクトACLが優先される。

暗号化

サーバサイド暗号化、クライアントサイド暗号化の両方に対応している。デフォルト暗号化を指定することも可能である。

Pre-signed Object URL

一定時間のみアクセスを許可するURLを発行できる。

通知

バケットにイベントが発生した際に、SNS、SQS、Lambdaに対して通知を行うことが可能。

モニタリング

CloudWatchとCloudTrailによるモニタリングが可能。

料金

通常ははストレージおよびデータ転送に掛かるコスト全ては、バケットの所有者が負担する。しかし、リクエスタ支払いバケットに指定した場合は、リクエストおよびバケットからのデータダウンロードに掛かるコストは、 所有者ではなくリクエストを実行したリクエスタが支払う

バージョニング

バージョニングが有効となったオブジェクトに対してDELETE処理を行った場合、全てのバージョンはストレージに残り削除マーカーが付加される。当該オブジェクトをGETしようとすると404 Not Foundが返されるが、オブジェクトバージョンを指定すると当該オブジェクトを取得可能である。

ライフサイクル

ライフサイクルと呼ばれる、オブジェクトに対するアクションルールをXMLにより規定できる。ライフサイクルによって、オブジェクトを異なるストレージクラスに移行したり、オブジェクトを削除したりすることができる。Glacierは削除や上書き、アーカイブリクエスト、復元に対して費用が発生する。ただし90日以上アーカイブされているオブジェクトに対する削除および上書きは無料である。

AWS CloudWatch(3)CloudWatch Logsのインストール

EC2インスタンスにCloudWatch Logs Agentをインストールすることで、任意のログをCloudWachに送信することが可能となる。AmazonLinuxを使用する場合には、以下の手順でインストールする。

CloudWatch Logs Agentのインストール

CloudWatch Logs Agentのインストール

CloudWatch Logs Agentはyumから簡単にインストールできる。

yum update -y
yum install -y awslogs

CloudWatch Logs Agentの設定

監視対象のログはconfファイルで設定する。

sudo vi /etc/awslogs/awslogs.conf

標準で/var/log/messagesの情報は送られる設定になるようである。
その下に下記のように設定を追記することで、任意のログを送ることが可能となる。

[/var/log/messages]
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/messages

[test-app-log]
file = /home/ec2-user/test-app/process_log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /home/ec2-user/test-app/process_log

CloudWatch Logsのログデータをエクスポートする

CloudWatch Logsに蓄積したログデータは、S3に一括エクスポートすることができる。詳しくは、「CloudWatch コンソールを使用してログデータを Amazon S3 にエクスポートする」を参照のこと。