AWS Organizations(1)Organizationsの概要

AWS Organizations

AWS Organizationsは、 複数のAWSアカウントを統合 するためのアカウント管理サービス。アカウント管理1や 一括請求 機能をはじめとした、以下の機能が備わっている。

  • アカウントの一元管理
  • 一括請求
  • アカウントのグループ( OU )化
  • アカウント毎の アクセスコントロール
  • タグの標準化
  • IAMの統合

これらの機能を実現するために、AWS Organizationsは以下のAWSサービスと連携している。

サービス名 有効化 実現できること
AWS IAM 不要 サービスアクティビティ による 最終アクセス時間の確認
AWS Artifact 必要 組織契約 による 契約の受諾
AWS CloudTrail 必要 組織の証跡 による 証跡の組織への適用
AWS CloudWatch Events 不要
AWS Config 必要 アグリゲータ による 集約ビュー の表示
AWS Control Tower 不要
AWS Directory Service 必要
AWS Firewall Manager 必要 AWS Firewall Manager による WAFルールの管理
AWS ライセンスマネージャー 必要
AWS RAM 必要
AWS Service catalog 必要
Service Quotas 不要
AWS シングルサインオン 必要
AWS System Manager 必要 Systems Manager Explorer によるデータの同期
タグポリシー 必要

AWS Organizationsを有効化すると、複数のAWSアカウントを一括管理することができる。それぞれのアカウントは、ルートを親として 組織単位 (OU)ごとに分類することができる。アカウントは、 マスターアカウント (=ルート)と メンバーアカウント に分かれ、マスターアカウントにはメンバーアカウントを管理するための様々な権限が付与される。AWS Organizationsの全ての機能を有効化することも、 一括請求機能のみを有効化 することもできる。各OUもしくはアカウント単位に、 サービスコントロールポリシー と呼ばれる各アカウントが持つ権限を明示したポリシーを適用することができる。 サービスコントロールポリシーとタグポリシーは、デフォルトでは無効化されている ので、利用する場合は有効化する。

組織とアカウント

AWS Organizationsが持つことのできるマスターアカウントは1つのみである。マスターアカウントでOrganizationsを有効化し、その後参加するアカウントを招待することで、メンバーアカウントを追加することができる。 マスターアカウントはサービスコントロールポリシーの影響を受けない 。Organizationsを削除すると復元できず、またポリシーも削除される。削除する際には、 全てのメンバーアカウントを消去する必要 がある。

Organizationsに参加したメンバーアカウントでは、サービスコントロールポリシーやタグポリシーが即座に適用され、またサービスの信頼を有効化している場合は、そのサービスからメンバーアカウントに対してアクションを実行することが許可される。また、Organizations内で新規のメンバーアカウントを作成することもできる。

ポリシー

サービスポリシー

サービスポリシーは、 最大で使用できるアクセスの権限を各アカウントに対して指定できる機能アカウントのルートユーザにも適用され、アカウントに与える影響が非常に大きいため適用する際には詳細のテストが必要である。IAMのサービスアクティビティに表示される、各アカウントの最終アクセス時刻を参考にポリシーの内容を決定することが望ましい。

サービスポリシーは以下のタスクには影響しない。

  • マスターアカウント
  • Service-linked Role
  • ルートユーザの認証
  • サポートプランの変更
  • CloudFrontの一部機能

サービスポリシーは、IAMポリシーとほぼ同じ構文を使用する。複数のポリシーが適用されている場合は、明示的なDenyがAllowよりも優先される。ポリシーの例は、 サービスコントロールポリシーの例 を参照のこと。

タグポリシー

タグポリシーを用いることで、タグキーおよびタグ値の大文字と小文字の処理方法の設定などを規定することができる。デフォルトでは、タグポリシーへのコンプライアンスの強制はされない。強制をサポートするAWSサービスは 強制をサポートするサービスとリソースタイプ を参照のこと。

AWS認定(4)ソリューションアーキテクト(プロフェッショナル)に合格するまで

AWS認定ソリューションアーキテクトプロフェッショナル試験合格に向けての資料集。以下の資料を何度も読み込んで、手を動かしながら実践を繰り返すことが合格の近道となる。

カテゴリ サービス名
コンピューティング EC2, ECS, Lambda, Batch, Elastic Beanstalk
ストレージ S3, EFS, Storage Gateway
データベース RDS, DynamoDB, ElastiCache, Redshift
移行と転送 Database Migration Service, Application Discovery Service, Migration Hub, Server Migration Service, Snowball
ネットワーク VPC, CloudFront, Route53, API Gateway, Direct Connect
開発者用ツール CodeCommit, CodeBuild, CodeDeploy, CodePipeline
管理とガバナンス Organizations, Config, CloudWatch, Auto Scaling, CloudFormation, CloudTrail, Config, OpsWorks, Systems Manager
分析 Athena, EMR, CloudSearch, Elasticsearch, Kinesis, QuickSight
セキュリティとコンプライアンス IAM, RAM, Cognito, GuardDuty, Inspector, CloudHSM, AD&SSO, WAF&Shield
モバイル Amplify, Mobile Hub
アプリケーション統合 SNS, SQS

AWS Shield(1)Shieldの概要

AWS Shield

AWS Shieldは、 DDoS攻撃 に対する保護を行う。 AWS Shield Standardは、追加料金なしで全てのユーザが使用できるサービスで、ウェブサイトやアプリケーションを標的とする、一般的かつ頻繁に発生するネットワークおよび転送レイヤーの DDoS 攻撃を防御する。

AWS Shield Advancedは、Amazon Elastic Compute Cloud、Elastic Load Balancing (ELB)、Amazon CloudFront、Amazon Route 53、AWS Global Acceleratorなどに対して行われる 高度な攻撃に対応する拡張保護を提供するAWS Shield Advanced を利用中にDDoS攻撃を受けた際には、 DDoS response team (DRT) にサポートを依頼できる。また、AWS Shield Advancedには、 AWS WAFが無償で付帯 されている。なお、DRTのサポートを受けるためには、 ビジネスサポートプラン以上の契約 が必要である。

多くの場合は、 AWS Shield Standard のみで対処可能である。

AWS Shield Advancedが対応可能なDDoS攻撃の例

DDoS攻撃は、一般的に以下のようなタイプに分類される。 AWS Shield Advanced は、これらのDDoS攻撃にも対応可能である。

名称 内容
UDP反射型攻撃 リクエストの発生元を偽装し、UDP を使用してサーバーから大量のレスポンスを引き出す
SYN フラッド 接続を半開状態にして、システムの利用可能なリソースを枯渇させる
DNS クエリフラッド DNS クエリを使用して DNS サーバーのリソースを枯渇させる
レイヤー 7攻撃 ウェブアプリケーションの実際のユーザーからのように見せかけて多数の HTTP リクエストを送信する

AWS WAF(1)WAFの概要

AWS WAF

AWS WAFは、Amazon API GatewayAmazon CloudFrontApplication Load Balancer に転送される HTTP および HTTPS リクエストをモニタリングできるWAF。

  • 指定したリクエスト 以外の全てのリクエストを許可する
  • 指定したリクエスト 以外の全てのリクエストをブロックする
  • 指定したプロパティに一致するリクエストを カウントする

ことができる。これらを設定する際には、

  • リクエストの発生元の IP アドレス
  • リクエスト送信元の
  • リクエストヘッダーの値
  • リクエストに含まれる 文字列
  • リクエストの 長さ
  • 悪意のある 可能性がある SQLコード の有無
  • 悪意のある 可能性があるスクリプトの有無

などを条件として指定できる。また、 DDoS攻撃の影響を最小限に抑えることが可能な AWS Shield と組み合わせて使用することもでき、これらのサービスを簡単に管理可能な AWS Firewall Manager が用意されている。WAFは、ルールの複雑性が加味された Web ACl Capacity Unit 単位で課金される。

CloudFrontと併用する際には、WAFが返却したレスポンスに応じてカスタムエラーページを表示 したり、 CloudFrontの地理的ブロッキング機能と同時に使用する ことができる。

ACLとルール

Web ACLは、表示された リスト順に評価 され、ルールに一致するリクエストを 許可 , ブロック , カウント することができる。また、どのルールにも一致しないリクエストをどのように処理するかを定める デフォルトアクション を指定することができる。

WEB ACLに追加可能なルールセットである、ルールグループ を規定することができ、あらかじめAWSやベンダーが作成した、マネージドルールグループ を使用/購入することもできる。ルールグループにはデフォルトアクションが設定されておらず複数のWEB ACLに同一のルールグループを適用することができる。

グループ名 WCU 内容 利用シーンと効果
Admin protection 100 公開されている管理ページへの外部アクセスをブロックするためのルール サードパーティーのソフトウェアを実行している場合や、悪意のあるアクターがアプリケーションへの管理アクセスを得るリスクを軽減したい場合
Amazon IP reputation list 25 ボットやその他の脅威に関連付けられている IP アドレスをブロック ボットを軽減したい場合
Core rule set 700 ウェブアプリケーションに一般的に適用可能なルール
Known bad inputs 200 脆弱性の悪用または発見に関連するリクエストパターンをブロックするルール 悪意のあるアクターが脆弱なアプリケーションを発見するリスクを軽減
Linux operating system 200 Linux 固有の脆弱性の悪用に関連するリクエストパターンをブロック 攻撃者がアクセスしてはならないファイルの内容を公開したり、コードを実行したりする攻撃を防ぐ
PHP application 100 安全でない PHP 関数のインジェクションなど、PHP プログラミング言語の使用に固有の脆弱性の悪用に関連するリクエストパターンをブロックするルール 攻撃者が許可されていないコードまたはコマンドをリモートで実行できる脆弱性の悪用を防ぐ
POSIX operating system 100 POSIX および POSIX と同等のオペレーティングシステムに固有の脆弱性の悪用に関連するリクエストパターンをブロックするルール アクセスしてはならないファイルの内容を公開したり、コードを実行したりする攻撃を防ぐ
SQL database 200 SQL Database ルールグループには、SQL インジェクション攻撃などの SQL データベースの悪用に関連するリクエストパターンをブロックするルール 不正なクエリのリモートインジェクションを防ぐ
Windows operating system 200 PowerShell コマンドのリモート実行など、Windows 固有の脆弱性の悪用に関連するリクエストパターンをブロックするルール 悪意のあるコードを実行したりする脆弱性の悪用を防ぐ
WordPress application 100 WordPress サイト固有の脆弱性の悪用に関連するリクエストパターンをブロックするルール

ロギング

ログ記録を有効化することで、WEB ACLで分析されるトラフィックの詳細情報を取得することができる。ログ記録を有効化すると Kinesis Firehose経由で指定した場所にログが保存される

また、CloudWatchアラームで特定のメトリクスをモニタリング することができるほか、CloudTrailによるアクションレコードの保存にも対応している。

FireWall Manager

FireWall Managerを用いることで、AWS WAF Classic ルール、AWS Shield アドバンスド 保護、 Amazon VPC セキュリティグループ を有効化することができ、これにより組織全体の保護を行ったり、リソースの頻繁な追加に対応し、組織全体のDDoS攻撃を一元的に監視することができる。 FireWall Managerを使用するためには、AWS Organizationのメンバーである必要 がある。

AWS System Manager(1)System Managerの概要

AWS System Manager

AWS System Manager は、統合インタフェースでインフラを可視化し、EC2のみならず オンプレミス上のサーバ を含めたさまざまなリソース( マネージドインスタンス )を管理し表示することができる。これによりモニタリングやトラブルシューティング、リソースとアプリケーションの管理などを迅速に行うことができる。

これらのリソースは、リソースグループ と呼ばれるグループごとに分類でき、状態をダッシュボード上から俯瞰することができるため、アプリケーションに影響を当てる可能性のあるリソースをすばやく特定することができる。また、OSのパッチレベルやソフトウェアのインストール状況なども簡単に確認することができる。

また、インスタンスの停止や再起動などの 運用タスクの自動化 や、リモートからのパッチの適用や設定の変更などができるため、ヒューマンエラーや運用負荷の軽減を図ることが可能である。

なお、System Managerは、過去に Simple Systems Manager と呼ばれていたため、現在も略して SSMと呼称される。

AWS System Managerの機能

System Managerを用いることで、以下を行うことができる。

カテゴリ サービス名 内容
運用管理 Explorer 運用データ(OpsData)を集約して表示するダッシュボード
運用管理 OpsCenter 運用作業項目(OpsItems)の表示と調査
運用管理 CloudWatch Dashboards メトリクス の表示
運用管理 Trusted Advisor & Personal Health Dashboard (PHD) プロビジョニングとヘルスイベントの表示
アプリケーション管理 Resource Groups AWSリソースの グループ化
アプリケーション管理 AWS AppConfig アプリケーション設定 を作成、管理、迅速にデプロイ
アプリケーション管理 Parameter Store 設定データ 管理と 機密管理 のための安全な階層型ストレージ
アクションと変更 Automation メンテナンスとデプロイの自動化
アクションと変更 Maintenance Window タスクのスケジュール を設定
インスタンスとノード 設定コンプライアンス パッチと設定の不一致を確認
インスタンスとノード インベントリ ソフトウェア インベントリの収集
インスタンスとノード マネージドインスタンス インスタンスの セットアップ
インスタンスとノード アクティベーション オンプレミス上のノードの承認
インスタンスとノード Session Manager ブラウザベースの シェルでアクセス
インスタンスとノード Run Command リモートから コマンドを実行
インスタンスとノード State Manager インスタンスを 定義された状態 に保つ
インスタンスとノード Patch Manager パッチ の適用
インスタンスとノード Distributor パッケージの作成
共有リソース ドキュメント Systems Manager が実行する アクションを定義

SSM Agent

SSM Agentは、EC2オンプレミスサーバ にインストールすることのできるソフトウェアで、System Managerはこのソフトウェアを介して、これらのリソースの更新や管理、設定を行うことができる。 EC2上で提供されているWindows ServerやAmazon Linux、 Ubuntu ServerのAMIには、あらかじめSSM AgentがインストールされているSystems Manager エンドポイントとの間でHTTPS通信を確立する必要があり、HTTP Proxy経由で通信する設定にすることもできる。なお、このエージェントの動作ログは以下の場所に格納されている。

  • /var/log/amazon/ssm/amazon-ssm-agent.log
  • /var/log/amazon/ssm/errors.log

SSM Agentの実行にはroot権限が付与 されていることから、このSSM Agentを用いて SendCommand や StartSession コマンドを行うことが可能なAWS上のIAM ユーザ等の管理や権限付与には注意する必要がある。SSM Agentをリリースのたびに更新し最新のバージョンを保持するためには、マネージメントコンソール上のマネージメントインスタンスのページから、Agent auto update (エージェントの自動更新)を選択する。

運用管理

Explorer

Explorerは、AWSリソースの情報を表示するダッシュボード。AWSアカウント全体もしくは当該リージョンの Amazon EC2Systems Manager OpsCenterSystems Manager Patch Manager などから運用データを取得し、これを一覧で確認することができる。

Explorerでは、 タグで情報をフィルタリング したり、 リソースデータの同期 機能を用いて、 複数のアカウントの情報を横断的に閲覧する こともできる。

OpsCenter

OpsCenterは、運用データを表示・調査・解決するための場所である。これを用いることで、各事象に対して迅速な対応が可能。

アプリケーション管理

Parameter Store

パラメータストアは、設定データ 管理と 機密管理 のための安全な階層型ストレージを提供し、パスワードや認証情報などを安全に保存できる。これらの情報には、作成時に定義した一意の名前を用いてアクセスできる。また、以下のAWSサービスと接続し、パラメータストアの情報を提供する。

  • Amazon Elastic Compute Cloud (Amazon EC2)
  • Amazon Elastic Container Service (Amazon ECS)
  • AWS Lambda
  • AWS CloudFormation
  • AWS CodeBuild
  • AWS CodeDeploy

パラメータストアは、 StringString List ,、Secure String をサポートしている。Secure Stringは、KMS-CMK (カスタマーマスターキー)を用いて暗号化される。また、パラメータには、デフォルトパラメータと アドバンストパラメータ が用意されている。前者から後者への移行は可能であるが、 その逆はできない 。アドバンスパラメータは、許可される パラメータ数やデータサイズが緩和 され、かつ パラメータポリシーが規定できる課金 される。

パラメータは 階層状 に管理できる。階層構造にすることで管理がしやすく、また 同一階層のデータを一括して取得することもできる 。パラメータポリシーを付加することで、 有効期限や失効期限 などを定めることができる。

パラメータにはタグを付与できる。また、更新されるたびに バージョン がインクリメントされる。パラメータラベル と呼ばれるエイリアスを指定することもできる。

AWSが提供しているパブリックパラメータを使うことで、AMIやリージョンの最新の情報を取得できる。

インスタンスとノード

コンプライアンス

コンプライアンスは、マネージドインスタンスをスキャンして、パッチコンプライアンスと設定の不一致を確認することができる 。具体的には、Patch Manager によるパッチ適用State Manager による Association に関するコンプライアンスデータ が表示される。また、 設定変更履歴をConfigから取得 したり、コンプライアンスをカスタマイズして 独自のルールを作成 したり、Run Command や State Manager を使って問題を修復 できる。

Resource Data Sync を用いることで、全てのマネージドインスタンスからのコンプライアンスをS3に蓄積/集約することができる。これらのデータは、Amazon Athena および Amazon QuickSight で可視化することもできる。データを蓄積するS3には、System Managerからのデータ書き込みを許可する Bucket Policy の作成が必要

インベントリ

インベントリを使用することで、 マネージドインスタンスからメタデータを収集 することができる。収集できるメタデータは、以下の通り。

カテゴリ 内容
アプリケーション アプリケーション名、発行元、バージョンなど
AWS コンポーネント EC2 ドライバ、エージェント、バージョンなど
ファイル 名前、サイズ、バージョン、インストール日、変更および最新アクセス時間など
ネットワーク設定の詳細 IP アドレス、MAC アドレス、DNS、ゲートウェイ、サブネットマスクなど
Windows 更新 Hotfix ID、インストール者、インストール日など
インスタンスの詳細 システム名、オペレーティングシステム (OS) 名、OS バージョン、最終起動、DNS、ドメイン、ワークグループ、OS アーキテクチャなど
サービス 名前、表示名、ステータス、依存サービス、サービスのタイプ、起動タイプなど
タグ インスタンスに割り当てられるタグ
Windows レジストリ レジストリキーのパス、値の名前、値タイプおよび値
Windows ロール 名前、表示名、パス、機能タイプ、インストール日など
カスタムインベントリ カスタムインベントリの操作 に説明されるようにマネージドインスタンスに割り当てられたメタデータ

これらのデータも、上述の Resource Data Sync でS3に保存することができる。インベントリのセットアップは、SSMドキュメントの AWS-GatherSoftwareInventory を Association で実行することによって実現できる。

Run Command

Run Commandを使用することで、マネージドインスタンスにログインすることなく安全に、管理タスクを実行することができる。Run Commandを実行するためには、コマンドを発行するIAM ユーザに実行権限を付与する必要がある。また、対象のインスタンスに対しても、 IAMインスタンスプロファイルを作成して適用する 必要がある。

State Manager

State Managerは、EC2等を定義された状態に保つプロセスの自動化を行う。例えば、起動時に特定のソフトウェアをインストールする、ネットワークを構成する、ソフトウェアの更新を行うなどのタスクを行う。

Patch Manager

Patch Managerは、セキュリティ関連などのパッチをマネージドインスタンスに対して適用するプロセスの自動化を行う。 ベースライン と呼ばれるパッチの適用ルールには、 リリースから数日以内に自動承認されるルール と、 承認済みおよび拒否済みパッチのリスト が含まれている。サポートされるOSは、 パッチマネージャーの前提条件 を参照のこと。各OSには、パッチ適用用のリポジトリが用意されており、これを指定するか、 代替パッチソースリポジトリ を指定することもできる。

AWSによってあらかじめ用意されている定義済みパッチベースラインの場合、

  • 「セキュリティ」タイプで重要度レベルが「非常事態」または「重要」のすべてのOSパッチを7日後に自動承認する
  • 「Bugfix」タイプのパッチをリリースから7日後に自動承認する

などのルールが事前に定められている。これらのパッチを適用する対象のインスタンスをグループ化するために、 パッチグループ を作成することができる。パッチグループは、 1 つのパッチベースラインにのみ登録できる。また、SSMドキュメントの AWS-RunPatchBaseline を適用する際に、対象のインスタンス等を指定することもできる。 パッチが適用されるとインスタンスは再起動される

SSMドキュメント

SSMドキュメントは、マネージドインスタンスで実行するアクションを定義するスクリプト。SSMドキュメントには、以下のタイプが用意されている。使用可能なスキーマバージョンやフォーマット等が定められているため、利用する際には ドキュメントを参照のこと。AWSが提供する Automation ドキュメントの名称や挙動は、Systems Manager Automation ドキュメントの詳細リファレンスを参照する。また、公式ドキュメントは存在しないが、AWSが提供する Command ドキュメントも多数存在する。

タイプ 内容 Schema Run Command State Manager Automation Maintenance Window Distributor Session Manager Change Calendaer
Command 設定の適用 1.2, 2.0, 2.2
Automation タスクの実行 0.3
Package ソフトウェア
Session セッションの定義
Policy AWS-GatherSoftwareInventory を使用したインベントリデータの取得 2.0-
Change Calendaer カレンダーエントリ

AWS Amplify Framework(4)APIカテゴリ

APIカテゴリ

APIカテゴリは、 REST および、AWS Appsync をはじめとする GraphQL エンドポイントへのHTTPリクエストを行うための機能を、JavascriptライブラリおよびSDKを通じて提供する。AppSyncとの統合を行う場合は、

  1. クライアント側でAPIエンドポイントと認証情報を設定
  2. APIスキーマからJavascriptコードを生成
  3. クエリやミューテーションを実行するアプリコードを生成

という手順で行う。また、 Amplify CLI を用いることでバックエンドとなる AWS Appsync の設定やクライアント側の設定ファイルのダウンロードなどを簡単に行うことができる。

セットアップ

Amplifyプロジェクトのルートディレクトリでamplify add apiコマンドを実行することで、ウィザードに従って自動セットアップを行うことができる。

amplify update api
? Please select from one of the below mentioned services: GraphQL
? Choose the default authorization type for the API Amazon Cognito User Pool
Use a Cognito user pool configured as a part of this project.
? Do you want to configure advanced settings for the GraphQL API No, I am done.

スキーマ

/amplify/backend/api/API_NAME/schema.graphql にあるスキーマファイル(schema.graphql)を編集することで、GraphQLのスキーマを更新することができる。Amplifyプロジェクトをデプロイすると、これらのスキーマがバックエンド側に反映される。

GraphQLトランスフォーマ

Amplifyには、拡張定義された GraphQLディレクティブ が用意されており、これらのディレクティブを用いることで、 データ構造や参照権限などを簡単に記述 することができる。

type User @model @key(fields: ["id", "group"]) {
  id: ID!
  group: String!
  attr: Attr
}

type Attr {
  gender: Int
  age: Int
  areacode: Int
  postcode: Int
}
ディレクティブ 内容
@model @model単位でDynamoDBテーブルが作成される
@key(fields: [KEY, KEY]) DynamoDBに格納する際のプライマリキーとソートキーを定義

スキーマの更新

フロントエンドのコンテンツは、GraphQLデータを操作するためのTypeScriptクラスを経由して、バックエンドと通信を行う。amplify codegen を実行することで、 /arc/graphql/ 以下にGraphQLを操作するためのGraphQLステートメントとタイプを自動生成する。

なお、amplify codegen コマンドは、 team-provider-info.json に格納されている情報を基にAWS上の設定内容を確認し、上記動作を行う。したがって、 team-provider-info.json に正しいリソース情報が格納されていない場合には、 UnhandledPromiseRejectionWarning: AccessDenied: Access Denied エラーが発生する。

AWS SAM(1)Serverless Application Modelの概要

AWS SAMとは

AWS SAMは、サーバレスアプリケーションを構築するための オープンソース フレームワークであり、数行の設定のみで、必要なアプリケーションを定義できる。AWS SAMは、CloudFormation拡張テンプレート仕様 および AWS SAM CLI コンポーネントから構成される。

AWS SAMを使用することで、関連するコンポーネントとリソースの整理、操作が単一のスタックで管理できる。また、メモリやタイムアウト値などの設定値をリソース間で共有することも可能である。また、CloudFormationの拡張機能 であるため、 CloudFormationに対応するリソースと組み合わせてリソースを管理することができる。

AWS SAMには、ローカルの開発環境でLambda実行環境と同等の機能を提供する。これを用いることで、AWS上にデプロイする前に、ローカルの開発環境で動作や問題等を確認することができる。

また、Lambdaを安全にデプロイするために、 一定期間の間に段階的に新しいバージョンをデプロイすることも可能 である。

SAM CLI

sam init

プロジェクト名として指定したディレクトリの下に、sam-app ディレクトリと、SAMプロジェクトおよびサンプルテンプレートを作成する。

sam validate

SAMテンプレートが有効であるかどうか検証する。AWS CLI Configureにてデフォルトリージョンを設定していない場合には、以下のように環境変数を与える必要がある。

env AWS_DEFAULT_REGION=ap-northeast-1 sam validate

sam build

sam-app ディレクトリ直下に .aws-sam を作成し、この下に、指定した実行環境をターゲットとする デプロイメントアーティファクト を作成する。例えば、LambdaをPythonで記述した場合に、 requirements.txt にて依存関係のあるライブラリを指定することができるが、 sam build はこれらの依存関係を適切に処理する。

sam package

デプロイメントアーティファクト を圧縮してS3にアップロードする。また、パッケージ化されたSAMテンプレート(packaged.yaml)を作成する。パッケージ化されたSAMテンプレートには、S3にアップロードした デプロイメントアーティファクト へのリンク先が記述されている。sam deploy コマンドは、 sam package コマンドを暗黙的に実行するため、本来は sam deploy コマンドを実行するだけでよい。

sam deploy

アプリケーションのデプロイを行う。 --guided パラメータを付与することで、インタラクティブモードを起動することができる。

sam logs

Lambdaが生成するログを確認することができる。

SAMテンプレート

SAMテンプレートには、 Globals セクションが設けられており、ランタイムやメモリなどの共通設定をこれに格納することができる。なお、以下のプロパティはサポートされていない。

  Function:
    Role:
    Policies:
    FunctionName:
    Events:

  Api:
    StageName:
    DefinitionBody:

SAMテンプレートでは、以下のリソースタイプがサポートされている。AWS :: Serverless :: LayerVersion のみ DeletionPolicy をサポートしている。また、 AWS :: Serverless :: Api 内で記述するOpenAPIドキュメントは、 一部のAPI Gateway拡張(x-amazon-apigateway-) のみサポートしていることに注意が必要である。

タイプ 作成されるリソース 備考
AWS :: Serverless :: Api API Gateway OpenAPIを使用してAPIを定義する
AWS :: Serverless :: Application SAM Serverless Application Repositoryのリソースをデプロイ可能
AWS :: Serverless :: Function Lambda, IAM Role
AWS :: Serverless :: HttpApi API Gateway Http Api
AWS :: Serverless :: LayerVersion Lambda Layer Version
AWS :: Serverless :: SimpleTable DynamoDB プライマリキーのみのテーブルを作成

ポリシーテンプレート

SAMでは、Lambdaのアクセス許可をポリシーテンプレートという形で指定することができる。ポリシーテンプレートは、あらかじめAWSが用意したポリシーパターンである。

テスト

sam local コマンドを用いることでローカルで、API GatewayやLambdaを実行させることができ、開発環境でアプリケーションの動作を検証することができる。

Amazon Inspector(1)Inspectorの概要

Inspectorとは

Amazon Inspectorは自動化されたセキュリティ評価サービスで、AWS上にデプロイされた アプリケーションに脆弱性やベストプラクティスからの逸脱などがないかを自動的に評価 し、重大性の順に項目を並べた結果リストの作成を行う。このサービスを利用することで、EC2への意図しないネットワークアクセスや脆弱性をチェックすることができ、アプリケーションのセキュリティとコンプライアンスを向上することができる Inspectorを使用することで、システムの脆弱性診断を自動化できる。

エージェント

Inspectorを使用する前に、サポートしているOS, リージョン等を確認する。また、対象のEC2インスタンスにInspectorエージェントをインストールする。インストールの際にはroot権限が必要で、System Managersの AmazonInspector-ManageAWSAgent ドキュメントを実行することで、リモートからエージェントをインストールすることも可能である。また、エージェントをインストールしたインスタンスは、テレメトリデータのやりとりのために、Inspectorのエンドポイントと通信できるようにする必要がある。なお、エージェントプログラムに更新が発生する場合は、自動的に適用されるため、手動による管理は不要

Inspectorが評価を行う対象のインスタンスは、評価ターゲット で規定する。タグベースで指定 することも、 全てのインスタンスを指定 することもできる。

評価とルールパッケージ

Amazon Inspectorは、指定されたターゲット内のリソースから動作や設定データを収集し、これらの情報と指定されたルールパッケージとの比較を行う。ターゲットのEC2にエージェントをインストールすることで、これらの動作を実行することが可能となる。また、ネットワーク到達可能性ルールパッケージに関しては、エージェントレスで評価を実行することができる

指定したルールには重要度が規定されており、重要度の大きな順から、 High , Medium , Low , Informational の4つのレベルが定められている。ルールパッケージは、

  • ネットワーク到達可能性
  • 共通脆弱性識別子
  • Center for Internet Security (CIS) ベンチマーク
  • Amazon Inspector のセキュリティのベストプラクティス

の4つのルールパッケージに分類されており、どのパッケージを適用するか指定することができる。これらのルールは、 CloudWatch Eventsなどから指定した時刻に起動 することも、手動で評価を開始することもできる。

結果とモニタリング

評価後の結果には、奨励される対応策 も記述される。何らかの理由で対処できない問題については、結果から除外することもできる。

Amazon Inspector のセットアップ

CloudRrailはCloudFormationに対応しているため、CloudFormation経由でAmazon Inspectorをセットアップすることができる。

サービスにリンクされたロール と IAMロールの作成

Amazon Inspector で使用する Service-Linked RoleIAM Roleを作成する。

Resources:
  ServiceLinkedRoleForInspector:
    Type: AWS::IAM::ServiceLinkedRole
    DeletionPolicy: Retain
    Properties: 
      AWSServiceName: inspector.amazonaws.com
      Description: A service-linked role required for Amazon Inspector to access your resources.   
  IAMRoleForInspectorEvents:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: 'sts:AssumeRole'
      Description: A role required for CloudWatch Events to access Inspector.
      Policies:
        - PolicyName: !Sub 'DefaultSecuritySettings-AWSEventsInspectorPolicy-${AWS::Region}'
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'inspector:StartAssessmentRun'
                Resource: '*'
      RoleName: !Sub 'DefaultSecuritySettings-InspectorEvents-${AWS::Region}'

Amazon Inspectorの有効化

Amazon InspectorAssessment TargetAssessment Template を作成する。

本テンプレートは、上記の4つのルールパッケージに対応する。なお、AWSが公開しているルールパッケージのURLがリージョンごとに異なることから、本テンプレートは、Amazon Inspector に対応しているリージョンのうち、一部のリージョンのみに対応していることに留意する。

Resources:
  InspectorAssessmentTarget:
    DependsOn:
      - ServiceLinkedRoleForInspector
    Type: AWS::Inspector::AssessmentTarget
    Properties:
      AssessmentTargetName: DefaultSecuritySettings-Assessment-Target-All-Instances-All-Rules
  InspectorAssessmentTemplate:
    Type: AWS::Inspector::AssessmentTemplate
    Properties:
      AssessmentTargetArn: !GetAtt InspectorAssessmentTarget.Arn
      DurationInSeconds: 3600
      AssessmentTemplateName: DefaultSecuritySettings-Assessment-Template-Default-All-Rules
      RulesPackageArns:
        # Asia Pacific (Tokyo)リージョンの場合
        - arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-gHP9oWNT
        - arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-7WNjqgGu
        - arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-YI95DVd7
        - arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-bBUQnxMq

CloudWatch Events を設定

Amazon Inspector は、CloudWatch Eventsを用いてAssessment Templateを定期実行することができる。本テンプレートでは毎週月曜日午前9時になると、CloudWatch EventsAmazon Inspectorを定期実行する。

Resources:
  CloudWatchEventsForInspector:
    Type: AWS::Events::Rule
    Properties: 
      Description: !Join
        - ''
        - - Scheduled Inspector Assessment for 
          - !GetAtt InspectorAssessmentTemplate.Arn
          - running every 7 day(s)
      Name: Amazon_Inspector_Assessment
      # Every Monday 9AM
      ScheduleExpression: cron(0 9 ? * 1 *)
      State: ENABLED
      Targets:
        - Arn: !GetAtt InspectorAssessmentTemplate.Arn
          Id: CloudWatchEventsForInspector
          RoleArn: !GetAtt IAMRoleForInspectorEvents.Arn

CloudFormation Launch Stack URL

以下のボタンから上のCloudFormationテンプレートを実行することが可能である。ソースコードは、aws-cloudformation-templates/security – GitHub にて公開。

作成されるAWSサービス CloudFormationテンプレート
セキュリティサービス全般 cloudformation-launch-stack
Inspector のみ cloudformation-launch-stack

AWS CloudTrail(2)CIS AWS Foundations Benchmarkに準拠するための通知設定

IAMパスワードポリシーの自動修復

CIS AWS Foundations Benchmark というセキュリティガイドラインが公開されており、このガイドラインは、AWSアカウントをセキュアに保つために必要なAWSのセキュリティ設定を集めたベストプラクティス集として活用できる。

この CIS AWS Foundations Benchmarkでは、CloudTrailによって検知された特定のイベントに対して以下のような対応を求めている。

  • 3.1 不正な API 呼び出しに対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.2 MFA なしの AWS マネジメントコンソール サインインに対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.3 「ルート」アカウントに対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.4 MFA なしの IAM ポリシーの変更に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.5 MFA なしの CloudTrail 設定の変更に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.6 AWS マネジメントコンソール 認証の失敗に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.7 カスタマー作成の CMK の無効化またはスケジュールされた削除に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.8 S3 バケットの変更に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.9 AWS Config 設定の変更に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.10 セキュリティグループの変更に対するメトリクスフィルタとアラームが存在することを確認します
  • 3.11 ネットワークアクセスコントロールリスト (NACL) への変更に対するログメトリクスとアラームが存在することを確認します
  • 3.12 ネットワークゲートウェイへの変更に対するログメトリクスとアラームが存在することを確認します
  • 3.13 ルートテーブルの変更に対してログメトリクスフィルタとアラームが存在することを確認します
  • 3.14 VPC の変更に対してログメトリクスフィルタとアラームが存在することを確認します

上述のログメトリクスフィルタとアラームを設定し、CIS AWS Foundations Benchmark準拠するために以下の設定を行う。

  1. CloudWatch Logs の MetricFilter を作成する
  2. 上のメトリクスに対する CloudWatch Alarm を作成する
  3. 閾値を超えた場合にAmazon SNSに通知を送る
Resources:
  # CIS 3.1 a log metric filter and alarm exist for unauthorized API calls 
  CloudWatchLogsMetricFilterCloudTrailUnauthorizedAPICalls:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.errorCode="*UnauthorizedOperation") || ($.errorCode="AccessDenied*")}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: UnauthorizedAPICalls 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailUnauthorizedAPICalls:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *不正なAPIコールを検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-Unauthorized-API-Calls'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      DatapointsToAlarm: 6
      EvaluationPeriods: 60
      MetricName: UnauthorizedAPICalls
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.2 a log metric filter and alarm exist for AWS Management Console sign-in without MFA
  CloudWatchLogsMetricFilterCloudTrailLoginWithoutMFA:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.eventName="ConsoleLogin") && ($.additionalEventData.MFAUsed !="Yes")}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: LoginWithoutMFA 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailLoginWithoutMFA:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *MFAなしのログインを検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-Login-Without-MFA'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: LoginWithoutMFA
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.3 a log metric filter and alarm exist for usage of "root" account 
  CloudWatchLogsMetricFilterCloudTrailForRootAcount:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{$.userIdentity.type="Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType !="AwsServiceEvent"}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: ForRootAcount 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailForRootAcount:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *ルートアカウントに対する変更を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-For-RootAcount'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: ForRootAcount
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.4 a log metric filter and alarm exist for IAM policy changes 
  CloudWatchLogsMetricFilterCloudTrailIamPolicyChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.eventName=DeleteGroupPolicy) || ($.eventName=DeleteRolePolicy) || ($.eventName=DeleteUserPolicy) || ($.eventName=PutGroupPolicy) || ($.eventName=PutRolePolicy) || ($.eventName=PutUserPolicy) || ($.eventName=CreatePolicy) || ($.eventName=DeletePolicy) || ($.eventName=CreatePolicyVersion) || ($.eventName=DeletePolicyVersion) || ($.eventName=AttachRolePolicy) || ($.eventName=DetachRolePolicy) || ($.eventName=AttachUserPolicy) || ($.eventName=DetachUserPolicy) || ($.eventName=AttachGroupPolicy) || ($.eventName=DetachGroupPolicy)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: IamPolicyChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailIamPolicyChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *IAMポリシーの変更を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-IamPolicy-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: IamPolicyChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.5 a log metric filter and alarm exist for CloudTrail configuration changes 
  CloudWatchLogsMetricFilterCloudTrailCloudTrailConfigurationChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.eventName=CreateTrail) || ($.eventName=UpdateTrail) || ($.eventName=DeleteTrail) || ($.eventName=StartLogging) || ($.eventName=StopLogging)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: CloudTrailConfigurationChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailCloudTrailConfigurationChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *CloudTrailの設定変更を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-CloudTrailConfiguration-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: CloudTrailConfigurationChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.6 a log metric filter and alarm exist for AWS Management Console authentication failures
  CloudWatchLogsMetricFilterCloudTrailAuthenticationFailuresDetected:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.eventName=ConsoleLogin) && ($.errorMessage="Failed authentication")}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: AuthenticationFailuresDetected 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailAuthenticationFailuresDetected:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *ログイン認証失敗を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-AuthenticationFailures-Detected'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: AuthenticationFailuresDetected
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.7 a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs 
  CloudWatchLogsMetricFilterCloudTrailCustomerCreatedCMKsChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.eventSource=kms.amazonaws.com) && (($.eventName=DisableKey) || ($.eventName=ScheduleKeyDeletion))}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: CustomerCreatedCMKsChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailCustomerCreatedCMKsChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *カスタマー作成CMKの無効化もしくは削除を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-CustomerCreatedCMKs-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: CustomerCreatedCMKsChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.8 a log metric filter and alarm exist for S3 bucket policy changes 
  CloudWatchLogsMetricFilterCloudTrailS3BucketPolicyChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties:
      FilterPattern: '{($.eventSource=s3.amazonaws.com) && (($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication))}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: S3BucketPolicyChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailS3BucketPolicyChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *S3のバケットポリシーの変更を検知* しました。'
      AlarmName: !Sub 'Notice-${AWS::StackName}-CloudTrail-S3BucketPolicy-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: S3BucketPolicyChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.9 a log metric filter and alarm exist for AWS Config configuration changes 
  CloudWatchLogsMetricFilterCloudTrailConfigConfigurationChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties: 
      FilterPattern: '{($.eventSource=config.amazonaws.com) && (($.eventName=StopConfigurationRecorder) || ($.eventName=DeleteDeliveryChannel) || ($.eventName=PutDeliveryChannel) || ($.eventName=PutConfigurationRecorder))}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: ConfigConfigurationChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailConfigConfigurationChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *Configの設定変更を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-ConfigConfiguration-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: ConfigConfigurationChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.10 a log metric filter and alarm exist for changes to Security Group 
  CloudWatchLogsMetricFilterCloudTrailSecurityGroupChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties: 
      FilterPattern: '{($.eventName=AuthorizeSecurityGroupIngress) || ($.eventName=AuthorizeSecurityGroupEgress) || ($.eventName=RevokeSecurityGroupIngress) || ($.eventName=RevokeSecurityGroupEgress) || ($.eventName=CreateSecurityGroup) || ($.eventName=DeleteSecurityGroup)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: SecurityGroupChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailSecurityGroupChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *セキュリティグループの変更を検知* しました。'
      AlarmName: !Sub 'Warning-${AWS::StackName}-CloudTrail-SecurityGroup-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: SecurityGroupChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.11 a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) 
  CloudWatchLogsMetricFilterCloudTrailNACLChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties: 
      FilterPattern: '{($.eventName=CreateNetworkAcl) || ($.eventName=CreateNetworkAclEntry) || ($.eventName=DeleteNetworkAcl) || ($.eventName=DeleteNetworkAclEntry) || ($.eventName=ReplaceNetworkAclEntry) || ($.eventName=ReplaceNetworkAclAssociation)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: NACLChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailNACLChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *NACLの変更を検知* しました。'
      AlarmName: !Sub 'Notice-${AWS::StackName}-CloudTrail-NACL-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: NACLChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.12 a log metric filter and alarm exist for changes to network gateways
  CloudWatchLogsMetricFilterCloudTrailNetworkGatewayChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties: 
      FilterPattern: '{($.eventName=CreateCustomerGateway) || ($.eventName=DeleteCustomerGateway) || ($.eventName=AttachInternetGateway) || ($.eventName=CreateInternetGateway) || ($.eventName=DeleteInternetGateway) || ($.eventName=DetachInternetGateway)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: NetworkGatewayChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailNetworkGatewayChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *ネットワークゲートウェイの変更を検知* しました。'
      AlarmName: !Sub 'Notice-${AWS::StackName}-CloudTrail-NetworkGateway-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: NetworkGatewayChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.13 a log metric filter and alarm exist for route table changes
  CloudWatchLogsMetricFilterCloudTrailRouteTableChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties: 
      FilterPattern: '{($.eventName=CreateRoute) || ($.eventName=CreateRouteTable) || ($.eventName=ReplaceRoute) || ($.eventName=ReplaceRouteTableAssociation) || ($.eventName=DeleteRouteTable) || ($.eventName=DeleteRoute) || ($.eventName=DisassociateRouteTable)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: RouteTableChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailRouteTableChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *ルートテーブルの変更を検知* しました。'
      AlarmName: !Sub 'Notice-${AWS::StackName}-CloudTrail-RouteTable-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: RouteTableChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching
  # CIS 3.14 a log metric filter and alarm exist for VPC changes 
  CloudWatchLogsMetricFilterCloudTrailVpcChanges:
    Type: 'AWS::Logs::MetricFilter'
    Properties: 
      FilterPattern: '{($.eventName=CreateVpc) || ($.eventName=DeleteVpc) || ($.eventName=ModifyVpcAttribute) || ($.eventName=AcceptVpcPeeringConnection) || ($.eventName=CreateVpcPeeringConnection) || ($.eventName=DeleteVpcPeeringConnection) || ($.eventName=RejectVpcPeeringConnection) || ($.eventName=AttachClassicLinkVpc) || ($.eventName=DetachClassicLinkVpc) || ($.eventName=DisableVpcClassicLink) || ($.eventName=EnableVpcClassicLink)}'
      LogGroupName: !Ref CloudWatchLogsGroupForCloudTrail
      MetricTransformations:
        - MetricName: VpcChanges 
          MetricNamespace: LogMetrics
          MetricValue: '1'
  CloudWatchAlarmMetricFilterCloudTrailVpcChanges:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      ActionsEnabled: true
      AlarmActions:
        - !Ref SnsTopicARN
      AlarmDescription: '*CloudTrail* が *VPCの変更を検知* しました。'
      AlarmName: !Sub 'Notice-${AWS::StackName}-CloudTrail-Vpc-Changes'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      MetricName: VpcChanges
      Namespace: LogMetrics
      OKActions:
        - !Ref SnsTopicARN
      Period: 60
      Statistic: Maximum
      Threshold: 1
      TreatMissingData: notBreaching

また、これらのメトリクスのアラーム通知先となる、Amazon SNSTopic Policy を作成する。

Resources:
  SNSAlert:
    Type: 'AWS::SNS::Topic'
    Properties:
      DisplayName: !Sub 'System Notifications from ${AWS::StackName}'
      TopicName: !Sub '${AWS::StackName}-system-notifications'
  SNSAlertTopicPolicy:
    Type: 'AWS::SNS::TopicPolicy'
    Properties:
      Topics: 
        - !Ref SNSAlert
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            # All AWS Services
            Principal:
              AWS: '*'
            Resource: '*'
            Action: 'SNS:Publish'