X-Ray
マイクロサービスは、
- 各サービスで独立した開発・デプロイが行える
- 各サービスで独立したスケーリングが行える
- 障害範囲が各サービス内
という利点があるが、
- ログ集約・フォーマットの違い
- 依存し合う多数・多様なサービス
- ボトルネックが見つけづらい
- 異論関係が変化し続ける
という点が課題となっている。
X-Rayを利用することで、アプリの実行状況や問題の検出、パフォーマンスの計測が可能になる。
X-Rayは大きく3つの区分がある
-
トレース
- 1リクエスト全体
-
セグメント
- Lambdaなどの、リソース名、リクエストの詳細、行った作業の詳細が記録される
-
サブセグメント
- DynamoDBなどの、AWSのサービス、外部HTTP APIの実行状況が記録される
-
トレースIDとセグメントIDで実行を記録していく
-
トレースヘッダーにX-Amazn-Trace-Idという値にトレースID;親セグメントID;サンプルデシジョンが記録される
-
注釈はフィルタ式(検索)で使うキーバリュー形式の値
-
メタデータは注釈と違って検索では使えないが、オブジェクトやリストなどが入れられる
-
グループはフィルタ式で定義されるトレースのコレクション
-
アナリティクスはフィルタリングされたトレースセット(時間帯や所要時間など)
-
メトリクステーブルは200, 500のカウントや%など
サンプリングルールについて、
課金額やパフォーマンスのため、デフォルトでは毎秒最初のリクエストは必ず記録、+以降は5%のみ。
リザーバーサイズ: 1秒間で必ず記録するトレース
固定レート: リザーバーサイズを超えたリクエストのうち何%記録するか
使い方について、
アプリ (SDK) -> X-Rayデーモン(ECSの場合はサイドカー、Lambda, Beankstalkはコンソール) -> API
Lambda: コンソールで有効化。ただし起動だけしかトレースされないので他のイベントはSDKを使って手動で記録する
ECS: サイドカーでX-Rayデーモンを動かす。ブリッジ接続(デフォルト)の場合は、環境変数のAWS_XRAY_DAEMON_ADDRESSが必要。awsvpcの場合は不要
App Mesh: 環境変数ENABLE_ENVOY_XRAY_TRACE = 1の定義が必要
SQS, SNS: パッシブ計測がデフォルトで有効化済み(何もする必要はない)
CloudWatch Lens: CloudWatchとX-RAYが統合
CloudWatch Synthetics: Canaryを作成してエンドポイントを監視。定期的にロード時間やUIスクリーンショットを取得
注意するべきこと
過去30日しか保持されない。
→ X-Ray使ったことないからあまり知らなかった…実際に使ってみたい。またCloudWatch Syntheticsとかも
Cognito
APIベースで実装されるモバイルアプリやWebアプリにユーザー認証機能を作成
-
ユーザープール: アプリへのアクセスに利用できるトークンを提供
-
IDプール: ユーザープール+外部IDプロバイダのログインに基づき、AWSクレデンシャルを提供
-
グループ: IAMロールやAppSyncの権限設定ができる
-
Cognito Identity Provider API
- パスワードの再発行など
- カスタム認証などができる
-
Cognito Auth API / Hosted UI
- カスタム認証は設定できない
- ビルドインのUIが存在するが、日本語対応なし
- OAuth2.0のフロー
- Authorization Code Grant or Implicit Grant(非推奨)がある
- 認可コードが返ってくるので、APIに投げるとトークンが帰ってくる
ALB, API Gateway, サーバー, App Syncが利用
InitiateAuth -> GetId -> GetCredentialsForIdentityでAWSの一時クレデンシャルが手に入る
アダプティブ認証: リスクに応じてMFAを必須にしたりできる
PinpointやCloudTrail(Cognito Auth API)とも連携している
-> Cognioもぜひ使ってみたい。1から作るより断然容易だけど個人開発にしては重いかも?
API Gateway
WebAPIのサービス
- インフラの監理
- APIの監理
- 認証と認可
- 流量制御と保護
RESTとWebSocketに対応している。
RESTの場合はエッジ最適化(CloudFront), リージョン(リージョンに直接アクセス、CFも可), プライベート(PrivateLinkのみ)が選べる。
ステージごとにデプロイが必要。
リソースを入れ子にしてURLを表現。各リソースごとにHTTPメソッドを指定し、フロー処理の定義を行う。
またSwaggerのインポート・エクスポートが可能。API Gateway固有定義の場合はx-amazon-apigateway-*で指定する
WebSocketの場合はルート選択式を使って各イベントの処理を定義する
メソッドリクエスト(REST), ルートリクエスト(WebSocket)のフローでは認証設定が行える。認証設定は下記の3種類
- IAMアクセス制限
- Lambdaオーソライザー
- Cognitoオーソライザー
統合タイプのフローでは処理を実際に行う先を指定できる。最長29秒の制限がある。
- Lambda
- HTTP
- Mock
- AWS サービス
- VPCリンク
Lambda, HTTP, VPCリンクの場合はプロキシ統合の設定が可能。設定が簡単になるがフォーマットが固定になる。
統合レスポンスのフローではマッピングテンプレートを使って処理結果を返すフォーマットを設定できる。
Json Schemaを使ってモデルにすることもできる。
使用量プラン
ステージに関連付けることでスロットリングができる。
キャッシュ
ステージごとにキャッシュを設定できる
カナリアリリースとクライアント証明書も可能。
リソースポリシー
アクセス元の制限など、S3バケットポリシー的な制限ができる。
クライアントSDK
APIステージ単位でREST API呼び出しクライアントをSDKとして生成可能
-> X-Rayと同様こちらも実際に使ってみたい…
Key Management Service (KMS)
- 鍵をどこに保管
- 鍵をどこで使うか
- 鍵を誰が使うか
- 確かなセキュリティ
KMI (Key Management Infrastructure)
- 鍵の管理・保管
AWS KMS
暗号化鍵の作成、管理、運用のためのサービス
-
CMK
- 最上位
- KMSのHMS上のみ平文
- 最大4KB
-
CDK
- 実際の暗号化・復号化に使用
-
Envelope Encryption
- マスターキーをデータ暗号化に利用するのではなく、マスターキーで暗号化した暗号キーで対象オブジェクトを暗号化・復号化する
- 暗号化したデータとCMKで暗号化されたデータキーを一緒に保管
-
Key Policy
- 暗号化キーに対してリソースレベルのポリシー
- IAMユーザーとポリシーの両方評価
-
許可
- CMKの使用をクライアントによって他のAWSプリンシパルに委任できる
-
Encryption Context
- 暗号化を利用する際にKMSにわたすことのできるKey/Valueペア
- 暗号化の時に指定すると復号化の時に同じペアが必要
- CloudTrailに平分で乗るので注意
-
暗号化・復号化のAPI
- Encrypt API
- 暗号化のAPI
- ヘッダが付与される
- Decrypt API
- 復号化のAPI
- ヘッダからCMKが自動で特定される
- GenerateDataKey API
- 暗号化に使うCDKを生成
- 平文の鍵とEncrypt APIで暗号化された鍵を返す
- Encrypt API
暗号化の手順
- データキーを生成 (平文と暗号化されたデータキーが返る)
- 平文のデータキーを使って暗号化
- 平文のデータキーの削除&暗号化済みデータキーと共にデータを保存
復号化の手順
- 暗号化されたデータキーをKMSに送信
- 返ってきた平文のデータキーでデータを復号化
- 平文のデータキーを削除
最小権限・権限分離
発見的統制
パフォーマンスとサービス制限
鍵をどの単位で分離するか(データクラス、インシデントなど)
インシデント対応の明確化と自動化(不正なアクセスが有ればLambdaで自動的にDisableにするなど)
-> KMS今までよく知らなかったけど概要が理解できた!
CloudFormation
テンプレート → スタック → AWSリソース
- Parameters
- ユーザーに指定させる
- Resources
- 必須
- Outputs
- 他スタックとの連携
former2(非公式)でyamlの作成ができる
開発
- cnf-lint
- 入力した値の整合性チェックできるコマンドラインツール
- CloudFormation template schema
- 自動補完をしてくれるプラグイン (VSCode, Pycharm)
テスト
- cnf-lint
- 使われていなかったり型が違うなどの警告を出してくれる
- taskcat
- マルチリージョン・マルチアカウントのテスト
- cnf-nag
- 潜在的なセキュリティ問題の警告(CIDRが0.0.0.0/0になっているなど)
- CloduFormation Guard
- テンプレート検証
- ルールを記述してそれにそぐわない項目をリスト
デプロイ
- CodePipelineでデプロイ
- 自動化
- 安全
- 繰り返し可
- デプロイ先に手動アクセス阻止
- ChangeSetsで確認してからデプロイ
- 変更箇所が事前に確認できる
- StackSetsでデプロイ(マルチリージョン・マルチアカウント向け)
- 1回の操作で複数のアカウントやリージョンへスタックを作成、更新、削除できるCloudFormationの機能
スタックとリソースの保護
- IAMポリシー
- スタックのスタック保護
- スタックポリシー(Ex. RDSの変更を禁止など)
- リソースのDeletation Policy
ライフサイクルごとのスタック
- スタックをレイヤとライフサイクルで分割
- スタックを環境ごとに再利用
設計観点
以下でスタックを分けてそれぞれをCross Stack Referenceで参照し合う
- 依存関係
- ライフサイクル
- 更新頻度と寿命
- 所有権
- 管理するチームごと
依存度が小さく、またライフサイクルが短い順に、次のようにスタックを分割するといい
- Application Layer
- Application
- ECS, ELB, AutoScalingなど
- Data
- S3, RDS, SQSなど
- Shared Service
- Route53, EC2(共通)、Directory Serviceなど
- Application
- Security Layer
- Network Layer
この時、各Roleはそれぞれのスタックで定義して、セキュリティグループはまとめるといい。かつセキュリティグループのスタックはVPCやサブネットなどのスタックとも別にしたほうがいい。
スタックのリファクタリングにはResource Importを使うといい。
ヘルパースクリプト
- cnf-init
- Systems ManagerのState Managerを推奨
- cfn-get-metadata
- メタデータ取得(Ex. EC2起動サービスなど)
- cnf-signal
- EC2リソースが正常にできたか
- cfn-hup
- EC2の再起動をせずにCloudFormationの変更時にアプリケーションに設定を適用
- 作成されたリソースのメタデータを検知し、カスタムフックを実行するためのデーモン
Dynamic Reference
Systems Managerのパラメータストアに格納されたデータを動的に取得
→スタックポリシーを使えばIAMやdeletation policyとは違った方向でリソースを保護できる。
また開発やテスト時に使える便利なツールやプラグインがあることが分かった。
スタックの分割基準も分かってよかった。
様々なヘルパースクリプトも利用できることが分かったし、Dynamic Referenceも知れてよかった。
Terraformから移行する日も近い?