Systems Manager State Manager(以下ステートマネージャー)はSSM管理下のインスタンスのあるべき状態を定義できる機能です。
インスタンスが起動したタイミングで、必ず設定しておきたい状態をステートマネージャーで定義することでアカウント内の統制をとることが可能です。
今回はこのステートマネージャーを使うことで、CloudWatch AgentのインストールとCloudWatch Logsへのログ出力設定を自動化してみました。
作成するもの
こんな感じのイメージです。Systems Mmanagerのリソースを展開したあと、EC2インスタンス(Linux/Windows)を作成してCloudWatch Logsにログが出力されるか確認します。
SSMドキュメント
自作のInstallAndManageCloudWatchDocument
を作成してます。AWS提供のドキュメントを組み合わせてCloudWatch Agentのインストールとログ出力設定を行います。
また、Amazon Linux 2023ではrsyslog
がインストールされておらず、これまでの/var/log/messages
などのログが出力されなくなっているので、Linuxの場合はインストールする処理も入れています。
Amazon Linux 2023の詳細については以下をご参照ください。
Amazon Linux 2023とAmazon Linux2のデフォルトで起動しているサービスやインストールされているパッケージを比較してみた | DevelopersIO
- AWS-ConfigureAWSPackage
- CloudWatch Agentをインストール
- AmazonCloudWatch-ManageAgent
- CloudWatch Agentのログ出力設定
- 設定値はパラメータストアから取得
- Windows/Linuxのプラットフォームで処理を分岐
- CloudWatch Agentのログ出力設定
- AWS-RunShellScript(Linuxの場合のみ)
- rsyslogをインストール・起動
ステートマネージャー
以下の設定で行います。 - 実行対象 - 全てのインスタンス - スケジュール - 1回のみ(インスタンス起動時のみ)
パラメータストア
ログ出力の定義値を登録します。今回はLunixとWindowsで以下2つです。
- AmazonCloudWatch-Linux-syslog
- /var/log/messagesを出力
- AmazonCloudWatch-Windows-syslog
- Systemを出力
やってみる
CloudFormationスタックの作成
Systems ManagerのリソースはCloudFormationテンプレートで作成しました。
以下のテンプレートを使ってスタックを作成してください。
ちょっと長いので折りたたみます。(↓クリックして開いてね)
CloudFormationテンプレート
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
LogGroupPrefix:
Type: "String"
Default: "oslog-linux-syslog"
AllowedValues: ["oslog-linux-syslog"]
LogGroupPrefixWindows:
Type: "String"
Default: "oslog-windows-syslog"
AllowedValues: ["oslog-windows-syslog"]
RetentionDays:
Description: The number of days to retain the log events in the specified log group.
Type: Number
Default: 30
AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365]
Resources:
# 取得する syslog を定義する SSM Parameter
## Linux
SSMParameterLinuxLogs:
Type: "AWS::SSM::Parameter"
Properties:
Name: !Sub "AmazonCloudWatch-Linux-syslog"
Description: "SSM Parameter for Linux to export syslog."
DataType: "text"
Tier: "Standard"
Type: "String"
Value: !Sub |-
{
"agent": {
"run_as_user": "root"
},
"logs":
{
"logs_collected":
{
"files":
{
"collect_list":
[
{
"file_path": "/var/log/messages",
"log_group_name": "${LogGroupPrefix}-${AWS::Region}/var/log/messages",
"log_stream_name": "{instance_id}",
"retention_in_days": ${RetentionDays}
}
]
}
}
}
}
## Windows
SSMParameterWindowsLogs:
Type: "AWS::SSM::Parameter"
Properties:
Name: !Sub "AmazonCloudWatch-Windows-syslog"
Description: "SSM Parameter for Windows to export syslog."
DataType: "text"
Tier: "Standard"
Type: "String"
Value: !Sub |-
{
"agent": {
"run_as_user": "root"
},
"logs":
{
"logs_collected":
{
"windows_events":
{
"collect_list":
[
{
"event_format": "xml",
"event_levels": [
"WARNING",
"ERROR",
"CRITICAL"
],
"event_name": "System",
"log_group_name": "${LogGroupPrefixWindows}-${AWS::Region}/System",
"log_stream_name": "{instance_id}",
"retention_in_days": ${RetentionDays}
}
]
}
}
}
}
InstallAndManageCloudWatchDocument:
Type: "AWS::SSM::Document"
Properties:
DocumentType: Command
Name: InstallAndManageCloudWatchDocument
UpdateMethod: NewVersion
Content:
schemaVersion: "2.2"
description: "The AWS-InstallAndManageCloudWatch command document installs the Amazon CloudWatch agent and manages the configuration of the agent for Amazon EC2 instances."
mainSteps:
- name: installCWAgent
action: "aws:runDocument"
inputs:
documentType: SSMDocument
documentPath: AWS-ConfigureAWSPackage
documentParameters:
action: Install
name: AmazonCloudWatchAgent
# Amazon Linux 2023では rsyslog が未インストール
- name: installRsyslogLinux
action: "aws:runDocument"
precondition:
StringEquals:
- platformType
- Linux
inputs:
documentType: SSMDocument
documentPath: AWS-RunShellScript
documentParameters:
commands:
- yum install rsyslog -y
- sudo systemctl enable rsyslog
- sudo systemctl restart rsyslog
- name: manageCWAgentLinux
action: "aws:runDocument"
precondition:
StringEquals:
- platformType
- Linux
inputs:
documentType: SSMDocument
documentPath: AmazonCloudWatch-ManageAgent
documentParameters:
action: configure
mode: ec2
optionalConfigurationSource: ssm
optionalConfigurationLocation: !Ref SSMParameterLinuxLogs
optionalRestart: "yes"
- name: manageCWAgentWindows
action: "aws:runDocument"
precondition:
StringEquals:
- platformType
- Windows
inputs:
documentType: SSMDocument
documentPath: AmazonCloudWatch-ManageAgent
documentParameters:
action: configure
mode: ec2
optionalConfigurationSource: ssm
optionalConfigurationLocation: !Ref SSMParameterWindowsLogs
optionalRestart: "yes"
SystemAssociationForInstallAndConfigureCloudWatchAgent:
Type: "AWS::SSM::Association"
Properties:
Name:
Ref: InstallAndManageCloudWatchDocument
AssociationName: ManageCloudWatchAgent
ScheduleExpression:
Ref: "AWS::NoValue"
Targets:
- Key: InstanceIds
Values:
- "*"
パラメータとしてロググループのプレフィクスと保持期間が設定できます。今回はすべてデフォルトのまま進めます。
スタックの作成が完了したらOKです。
EC2の起動
起動するEC2は以下が前提です。
- SSM管理下であること (参考:AWS Systems Manager のセットアップ - AWS Systems Manager)
- CloudWatch Logsへのログ出力する権限があること(CloudWatchAgentServerPolicy相当)
今回は以下のAMIを使います。
- Amazon linux 2
- Amazon linux 2023
- Windows Server 2022 Base
IAMロールの権限が不足しないよう注意してください。最小権限であれば、以下2つのポリシーをアタッチします。
- CloudWatchAgentServerPolicy
- AmazonSSMManagedInstanceCore
以下3つのインスタンスを起動して、すべてにIAMロールをアタッチしました。
CloudWatch Logsの確認
少し時間をおいてCloudWatch Logsを見ると、CloudWatch Logsのロググループが作成されているのを確認できました。
Linux側は2つのインスタンスを起動したので、ログストリームに2つのインスタンスIDが作成されています。
Amazon Lunux 2023のインスタンスもログが出力できたので、rsyslog
のインストールと起動も問題ないようです。
無事ステートマネージャーを使って、EC2のCloudWatch Agentのインストールとログ出力設定を自動化できました。
まとめ
ステートマネージャーを使ってCloudWatch Agentのインストールとログ出力設定を自動化してみました。
この仕組みはEC2がSSM管理になっていることが前提なので、以下のようなConfigルールで非管理状態のものを検知できる仕組みがあるとよさそうです。
ec2-instance-managed-by-systems-manager - AWS Config
SSMドキュメントをうまく書ければ他にも色々できるので、管理方法に合わせたものを作れると運用が楽になります!EC2管理に統制をかけたい場合は是非試してみてください。