ControlTower関連記事まとめ
・ControlTower①マルチアカウント環境をセットアップする
・ControlTower②環境確認
・ControlTower③SSOの確認・アカウントの追加・削除
・ControlTower④ガードレールの設定
・ControlTower⑤Auditアカウントに作成されるリソースについて
・ControlTower⑥LogArchiveアカウントに作成されるリソースについて
・ControlTower⑦SecurityHubの有効化
・ControlTower⑧GuardDutyの有効化
・ControlTower⑨CloudWatchクロスアカウントダッシュボードの設定
・ControlTower⑩LogArchiveアカウント内バケットへのCloudWatchLogs集約←今ここ
現在の構成と設定内容の確認
前回までの記事で、ControlTower配下のSecurityOUに所属するAuditアカウントでSecurityHub・GuardDutyを集約し、CloudWatchのクロスアカウントダッシュボードを有効化する手順を確認しました。各アカウントの役割について、下記図に整理します。
今回は、Sandboxアカウントの存在するEC2インスタンスのログファイルをLogArchiveアカウントのS3バケットに集約する手順を確認します。
EC2インスタンスへCloudWathAgentをインストールする際の手順についてはこちらをご参照ください。EC2にCloudWatchの権限を付与したIAMロールをアタッチする必要がある点、EC2がプライベートサブネットに存在する場合はVPCエンドポイントを作成する必要がある点にご留意ください。
メンバーアカウント・Auditアカウント・LogArchiveアカウント間でのサービス連携は下記の構成図のようになります。AuditアカウントのクロスアカウントダッシュボードからSandboxアカウントのEC2のメトリクス確認やアラーム設定を行います。LogArchiveアカウントのS3バケットにはEC2インスタンスから出力されるログファイルが集約されます。
設定手順の確認・事前準備
設定はAWS公式ブログの手順を参考に行います。ControlTowerにより作成されたS3バケットには設定変更が許可されていません。そのため、CloudWatch Logsの集約を行う場合はLogArchiveアカウントにログ収集用のS3バケットを作成しましょう。S3バケット作成後、LogArchiveアカウント側でKinesisFirehoseの設定を行います。
今回はAWS CLIを使用して、コマンドラインからAWSリソースの作成を行う必要があります。そのための準備作業として、以下二点の設定を行いました。
①IAMユーザーを作成し、アクセスキー・シークレットアクセスキーの取得
②AWSCLIのインストール
また、今回はLogArchiveアカウント、Sandboxアカウント両方のリソースをCLIから操作する必要があります。CLIから複数アカウントを操作する場合は、プロファイルの設定を行っておくと、作業がしやすくなります。
具体的な設定手順の説明に入る前に、設定内容を確認しておきましょう。下記は前のセクションの構成図からCloudWatchLogs→S3の連携部分を抜き出し詳細化した構成図となります。
LogArchiveアカウントのKinesisFirehose・CloudWatchDestinationにはそれぞれIAMロールを紐づけ、リソースへの書き込みを許可しておきます。SandboxアカウントのCloudWatchLogsにサブスクリプションフィルタを設定し、LogArchiveアカウントのCloudWatchLogsDestinationあてにログイベントを連携するように設定します。
LogArchiveアカウント側の作業
まずはKinesisFireHose用のIAMロールの設定から行います。構成図の赤枠で囲った部分です。
IAMロールに設定する信頼ポリシー用Jsonを作成します。
下記内容でjsonファイルを作成し、保存しておきましょう。
【ファイル名:TrustPolicyForFirehose.json】
{
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": "firehose.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
“sts:ExternalId”: “ログアーカイブアカウントのアカウントID"
}
}
}
}
信頼ポリシー用のJsonが作成できたら、KinesisFirehose用のIAMロールの作成を行います。
コマンドプロンプトから下記コマンドを実行します。
「assume-role-policy-document file」で指定した場所は、適宜ファイルを作成した場所を指定するようにしてください。
aws --profile logarchive iam create-role ^
--role-name IAMロール名^
--assume-role-policy-document file://~/TrustPolicyForFirehose.json
今回はLogArchiveアカウントを「logarchie」、Sandboxアカウントを「sandbox」としてプロファイルを登録しています。プロファイルを設定せず手順を行う場合は、コマンドの「 --profile logarchive」部分を抜いて実行ください。IAMロール作成後、出力されるARNを控えておきます。
また、IAMロールに紐づけるためのポリシーの内容もjsonファイルで定義します。構成図の赤枠で囲った部分の設定です。
下記内容でjsonファイルを作成し、保存します。
【ファイル名:PermissionsForFirehose.json】
{
"Statement": [
{
"Effect":
"Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:PutObjectAcl",
"s3:PutObject"
],
"Resource": [
“arn:aws:s3:::S3バケット名",
"arn:aws:s3::: S3バケット名/*" ]
}
]
}
S3バケットへの読み込み・書き込みなどを許可するIAMポリシーです。「S3バケット名」と記載の項目にログを集約したいバケット名を記入してください。
jsonファイルが作成できたら、IAMポリシーの作成・IAMロールへの紐づけを行います。
aws --profile logarchive iam put-role-policy --role-name IAMロール名--policy-name Permissions-Policy-For-Firehose --policy-document file://~/PermissionsForFirehose.json
IAMロールの作成が完了したら、LogArchiveアカウントで使用するKinesisの配信ストリームを作成します。
構成図の赤枠で囲った部分です。
下記コマンドを実行し、配信ストリームを作成しましょう。
aws --profile logarchive firehose create-delivery-stream --delivery-stream-name “配信ストリーム名” --s3-destination-configuration RoleARN=“IAMロールのARN”,Prefix=“プレフィックス名”,CompressionFormat=“ZIP”,BucketARN=“配信先バケットのARN" --region ap-northeast-1
今回は東京リージョンで設定を行っているため、「--region」の引数には「ap-northeast-1」を指定しています。実際に設定を行う場合は、適宜使用しているリージョン名に読み替えてコマンドを実行してください。
コマンドを実行後出力される配信ストリームのARNを控えて置きます。
また、下記コマンドを実行し、「DeliveryStreamStatus」が「ACTIVE」となることを確認します。
aws --profile logarchive firehose describe-delivery-stream --delivery-stream-name “配信先ストリーム名" --region ap-northeast-1
Kinesisの配信ストリーム作成が完了したら、CloudWatchLogsDestinationの設定を行います。まずはCloudWatchLogsDestinationに紐づけるIAMロールを作成しましょう。構成図の赤枠で囲った部分です。
IAMロールに紐づける信頼ポリシー用のjsonファイルを作成します。
下記内容でjsonファイルを作成し、保存します。
【ファイル名:TrustPolicyForCWL.json】
{
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": "logs.ap-northeast-1.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
}
「service」に指定したリージョン名は適宜読み替えてご使用ください。
信頼ポリシー用のJSONが作成できたら、コマンドを実行しIAMロールを作成します。
aws --profile logarchive iam create-role ^
--role-name IAMロール名^
--assume-role-policy-document file://~/TrustPolicyForCWL.json
また、IAMロールへ紐づけるIAMポリシーを作成します。作成するのは、Firehoseへの書き込みを許可するポリシーです。構成図の赤枠で囲った部分の作業となります。
下記内容でJSONを作成し、保存します。
【ファイル名:PermissionsForCWL.json】
{
"Statement":[
{
"Effect":"Allow",
"Action":["firehose:*"],
“Resource”:[“arn:aws:firehose:ap-northeast-1:LogArchiveアカウントのアカウントID:*"]
},
{
"Effect":"Allow",
"Action":["iam:PassRole"],
“Resource”:[“arn:aws:iam::LogArchiveアカウントのアカウントID:role/CWLtoKinesisFirehoseRole"]
}
]
}
リージョン・アカウントIDは適宜読み替えてご利用ください。
ここまで完了したら、IAMロールへIAMポリシーの紐づけを行います。
aws --profile logarchive iam put-role-policy --role-name IAMロール名--policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
これで、CloudWatchDestinationに紐づけるIAMロールの作成が完了しました。
次に、CloudWatchLogsDestinationの作成を行います。構成図の赤枠で囲った部分です。
下記コマンドを実行し、CloudWatchLogsDestinationを作成できます。
aws --profile logarchive logs put-destination --destination-name “CloudWatchLogsDestinationの名前” --target-arn “KinesisFirehoseストリームのARN” --role-arn “作成したCloudWatchLogs用IAMロールの名前" --region ap-northeast-1
また、CloudWatchLogsDestinationに紐づけるアクセスポリシー用のJSONを作成します。
Sandboxアカウントからの書き込みを許可するアクセスポリシーを作成し、CloudWatchLogsDestinationに関連付けることでSandboxアカウントからのログの連携が可能となります。構成図の赤枠で囲った部分の作業です。
アクセスポリシーのJSONは下記内容で作成します。
【ファイル名:AccessPolicy.json】
{
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "",
"Effect" : "Allow",
"Principal" : {
“AWS” : “SandboxアカウントのアカウントID"
},
"Action" : "logs:PutSubscriptionFilter",
“Resource” : “作成したKinesisFirehose配信ストリームのARN"
}
]
}
アカウントIDには、ログ配信元のアカウントIDを指定します。また、Resourceに指定したARNには、KinesisFirehose配信ストリームのARNを指定します。
jsonファイルを作成したら、下記コマンドにてCloudWatchLogsDestinationへのアクセスポリシー紐づけを行います。
aws --profile logarchive logs put-destination-policy --destination-name " CloudWatchLogsDestinationの名前" --access-policy file://~/AccessPolicy.json --region ap-northeast-1
CloudWatchLogsDestinationの状態確認を行います。「AccessPolicy」のPrincipalで書き込み元のAWSアカウントIDが許可されていることをご確認ください。
aws --profile logarchive logs describe-destinations --region ap-northeast-1
これで、LogArchiveアカウント側での作業は完了です。
SandBoxアカウント(ログ配信元)の作業
ここまでの手順が完了したら、Sandboxアカウント側でCloudWatchのサブスクリプションフィルタを作成します。構成図の赤枠で囲った部分です。
下記コマンドにて、CloudWatchLogsのサブスクリプションフィルタの作成を行います。
aws --profile sandbox logs put-subscription-filter --log-group-name “ロググループ名” --filter-name “サブスクリプションフィルタ名" --filter-pattern "" --destination-arn ^
“ ログアーカイブアカウントにて作成したCloudWatchLogsDestinationのARN " --region ap-northeast-1
これで、S3への配信設定が完了しました。
下記コマンドを実行すると、CloudWatchLogsのロググループにログイベントを出力することができます。ログイベントを出力し、S3バケットにログが配信されていることを確認しましょう。
aws logs put-log-events --log-group-name "ロググループ名" --log-events timestamp=1461997171845,message='Hello CloudWatch'
ここまでお読みくださりありがとうございました。次回はControlTower環境での通知の集約について書こうと思います。