この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
一つのプロジェクトでAWSアカウントが複数あることは珍しくありません。
本番、開発、検証のほかにセキュリティの観点から、アカウント管理、監査、アカウント踏み台用などでAWSアカウントを複数運用しているケースがあります。
アカウントが複数ある場合、ログ監視のためにログ収集場所を一本化したいですよね。
CloudWatchログは設定ファイルやIAMポリシーを変更するだけで、別のアカウントにログを送信することができます。
今回紹介するのはCloudWatchログで収集しているログを別アカウントに送信する方法です。
CloudWatchログで収集しているログを別アカウントに送信してみる
今回紹介するCloudWatchログで収集しているログを別アカウントに送信する方法は、2つのアカウントを使用します。各手順の最初に【ログ受信側】・【ログ送信側】と記載し、今どちらの作業を行っているか書いてありますが、わかりづらかったら申し訳ないです。
■前提条件
今回の構築の前提条件は以下の通りです。ハンズオンとして行いたい場合は、事前にインスタンスからログを収集してみてください。⇒CloudWatchログでログを収集する方法はこちら
- AWSアカウントが2つ以上ある
- すでにCloudWatchログでログを収集している
■IAMロール作成
【ログ受信側】
まずは、受信側で別アカウントからのログ送信を許可するIAMロールを作成します。
IAMのダッシュボード画面に行き、左のナビゲーションペインから[ロール]をクリックします。
↓[ロールを作成]をクリックします。
↓[信頼されたエンティティタイプ]で[カスタム信頼ポリシー]を選択します。
↓以下のJSONドキュメントを環境に合わせて編集し、貼り付けてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::#送信側AWSアカウントID#:role/#送信側収集対象インスタンスにあたタッチしているIAMロール名#"
]
}
]
}
↓貼り付けが完了しましたら、[次へ]をクリックします。
↓[許可を追加]で[CloudWatchAgentServerPolicy]を追加し、[次へ]をクリックします。
CloudWatchAgentServerPolicy
↓任意でロール名を入力し、内容に問題なければ[ロールを作成]をクリックします。
↓
■IAMポリシー作成
【ログ送信側】
つぎにログ送信側で受信側にログを送信できる許可を与えるポリシーを作成し、収集対象インスタンスにアタッチしているIAMロールに作成したポリシーを付与します。
↓IAMのダッシュボード画面のナビゲーションペインから、[ロール]をクリックし、インスタンスにアタッチしているIAMロールをクリックします。
↓[許可ポリシー]から[許可を追加]の[インラインポリシーを作成]をクリックします。
↓[ポリシーの作成]で[JSON]タブをクリックします。
↓以下のJSONドキュメントを貼り付け、[ポリシーの確認]をクリックしてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::#受信側AWSアカウントID#:role/#受信側で作成したIAMロール名#"
]
}
]
}
↓任意の名前を入力し、[ポリシーの作成]をクリックします。
↓
インラインポリシーが付与出来たら、完了です。
■エージェント設定ファイル編集
【ログ送信側】
CloudWatchログを利用してインスタンスログを収集する際、CloudWatchエージェント設定ファイルを作成したかと思います。
作成した設定ファイルの[Logsセクション]の部分で、別のAWSアカウントにログを送信する際に使用するIAMロール(受信側で作成したIAMロール)を指定するため、設定ファイルを編集する必要があります。
作成した設定ファイルはパラメータストアへの保存されていますので、AWSマネージメントコンソールで編集してしましましょう。
↓まずは[Systems Manager]のダッシュボード画面にいきます。
↓左のナビゲーションペインから、[パラメータストア]をクリックします。
↓対象インスタンスの設定ファイル選択し、[編集]をクリックします。
↓[パラメータの詳細]の[値]を編集します。念のため今の値をメモ帳などに貼り付けておきましょう。
【編集前】
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/secure",
"log_group_name": "secure",
"log_stream_name": "{instance_id}",
"retention_in_days": -1
}
]
}
}
},
"metrics": {
"aggregation_dimensions": [
[
"InstanceId"
]
],
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"collectd": {
"metrics_aggregation_interval": 60
},
"disk": {
"measurement": [
"used_percent"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
},
"statsd": {
"metrics_aggregation_interval": 60,
"metrics_collection_interval": 10,
"service_address": ":8125"
}
}
}
}
上の設定ファイルの"logs"セクションに"credentials"フィールドを追加します。
"credentials": {
"role_arn": "arn:aws:iam::#受信側AWSアカウントID#:role/#受信側で作成したIAMロール名#"
【編集後】
6,7,8,9行目に挿入しています。
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"logs": {
"credentials": {
"role_arn": "arn:aws:iam::#受信側AWSアカウントID#:role/#受信側で作成したIAMロール名#"
},
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/secure",
"log_group_name": "secure",
"log_stream_name": "{instance_id}",
"retention_in_days": -1
}
]
}
}
},
"metrics": {
"aggregation_dimensions": [
[
"InstanceId"
]
],
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"collectd": {
"metrics_aggregation_interval": 60
},
"disk": {
"measurement": [
"used_percent"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
},
"statsd": {
"metrics_aggregation_interval": 60,
"metrics_collection_interval": 10,
"service_address": ":8125"
}
}
}
}
↓編集したドキュメントを[値]に貼り付け、[変更を保存]を押します。
↓
設定ファイルの編集は以上です。
■CloudWatchエージェント再実行
【ログ送信側】
設定ファイルを編集したので、CloudWatchエージェントに設定ファイルを再度参照してもらいましょう。CloudWatchエージェント再実行も[Systems Manager]を利用して行います。
↓[Systems Manager]ダッシュボード画面のナビゲーションペインから[Run command]をクリックします。
↓[Run command]ボタンをクリックします。
↓[コマンドドキュメント]で[AmazonCloudWatch-ManageAgent]を検索し、ラジオボタンをクリックします。
AmazonCloudWatch-ManageAgent
↓[コマンドのパラメータ]の[Optional Configuration Location]で、パラメータストアで編集した設定ファイル名を入力します。
↓[ターゲット]で[インスタンスを手動で選択する]を選択し、対象インスタンスのチェックボックスにチェックを入れます。
↓[実行]をクリックします。
↓[ステータス]が"進行中"から"成功"に変われば、無事に再収集が始まります。
↓
[ステータス]が失敗しましたら、編集した設定ファイルの見直しや、IAMポリシーのアカウントID、ロール名を再確認してみてください。
■動作確認
【ログ受信側】
さいごに別アカウントからログが収集されているか確認しましょう。
CloudWatchダッシュボード画面のナビゲーションペインから[ロググループ]をクリックします。
↓今回は対象インスタンスの[/var/log/secure]を収集していますので、"secure"というロググループが確認できますね。
↓念のため中身も見てみます。インスタンスIDは合っています。
↓直近のログが取れているのが確認できます。
ちなみに、送信側のCloudWatchログを見てみると、
[Run command]を実行したタイミングで、元アカウントへの送信を止めるみたいですね。
今回の構築は以上です。
まとめ:CloudWatchログで収集しているログを別アカウントに送信する方法
ログ収集一本化のために今回の構築を行いました。構築自体は複雑な設定がなくシンプルなのですがCloudWatchだけではなくIAMの知識も必要になります。
ログ収集は奥が深いですね。
参考リンク:AWS公式ドキュメント
↓ほかの協栄情報メンバーもAmazon CloudWatchに関する記事を公開しています。ぜひ参考にしてみてください。
■CloudWatchでサーバーを監視し、メトリクスの閾値を超えた時にメールで通知を受けとる。(nakaniwa)
https://cloud5.jp/cloudwatch-agent-nakaniwa/
■特定IAMユーザに特定のタグが付与されたCloudWatch Logsのみ参照を許可する IAM ポリシー(小林 剛)
https://cloud5.jp/log-access-control-with-tag/
■RDSイベントを取得してCloudWatchLogsに出力するハンズオン(INAMURA)
https://cloud5.jp/rds-events-send-to-cloudwatchlogs/
■CloudWatch Logs の利用量が急増の場合、問題ロググループを特定する方法(dapeng)
https://cloud5.jp/cloudwatch-logs-incomingbytes/