Systems Managerを使ってCloudWatchエージェントを導入・設定してみた
背景
以前いた会社ではFluentdとAWS Athenaを使ったログ集約基盤を構築を経験しました。
→詳しい内容はこちらの記事をご覧ください。
今の会社でもログ集約基盤の実装を担当していますが、今回はそこまで複雑なクエリ分析が不要である点、数百台のEC2のログ集約を実装したいという要望を踏まえて、CloudWatchエージェントを導入しCloudWatch Logsにログを集約する実装にしました。
とはいえ一台一台にCloudWatchエージェントをインストールするのは大変ですし、CloudWatchエージェントの設定ファイルを反映するのも面倒なので、AWS Systems Managerを使って複数のEC2に対して一括で設定反映できる実装に取り組んでみました。
AWS Systems Managerについて
EC2インスタンスやオンプレミスのサーバー管理をエージェントソフトによって管理し、面倒な運用タスクを自動化できます。
事前にSSMエージェントをインストールする必要がありますが、Ubuntu、Amazon Linux2の公式AMIには最初からプリインストールされています。
Systems Managerでできることに以下の機能があります。
- SSH接続なしのサーバーログイン
- 事前定義されたコマンドドキュメントからのコマンド実行
- 明示的なバージョン指定でのパッチ適用
- 定常タスクのオートメーション
今回はRun Command
という事前定義されたコマンドドキュメントからのコマンド実行機能を利用して、CloudWatchエージェントのインストールとエージェントの設定反映を行ない、複数WebサーバーのApacheログをCloudWatch Logsに集約できるように実装します。
下準備
EC2とSystems Managerの通信を実現するにはEC2に以下の設定が必要です。
- SSMエージェント導入
- Systems Managerとの通信を許可するIAMロールのアタッチ
今回EC2はBitnamiのWordPressの公式AMIから起動したものを使いました。
OS情報は以下のとおりDebianです。
$ neofetch
_,met$$$$$gg. bitnami@ip-10-0-0-56
,g$$$$$$$$$$$$$$$P. --------------------
,g$$P" """Y$$.". OS: Debian GNU/Linux 10 (buster) x86_64
,$$P' `$$$. Host: HVM domU 4.11.amazon
',$$P ,ggs. `$$b: Kernel: 4.19.0-18-cloud-amd64
`d$$' ,$P"' . $$$ Uptime: 2 hours, 3 mins
$$P d$' , $$P Packages: 435 (dpkg)
$$: $$. - ,d$$' Shell: bash 5.0.3
$$; Y$b._ _,d$P' Terminal: /dev/pts/0
Y$$. `.`"Y$$$$P"' CPU: Intel Xeon E5-2676 v3 (1) @ 2.394GHz
`$$b "-.__ GPU: Cirrus Logic GD 5446
`Y$$ Memory: 276MiB / 983MiB
`Y$$.
`$$b.
`Y$$b.
`"Y$b._
`"""
このAMIから3台のEC2インスタンスを起動させましたので、まずはそれぞれにSSMエージェントを導入していきます。
SSMエージェントインストール
まず始めにSSMエージェントのインストールから始めます。
SSMエージェントのインストール方法は公式ドキュメントに記載がありますが、これを一台一台に実行するのはやはり手間ですので簡単なAnsible Playbookを作成して一括導入します。---
- hosts: all
become: yes
tasks:
- name: install ssm-agent
apt:
deb: "https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb"
とても雑シンプルなPlaybookですがSSMエージェントをインストールするだけでしたら、これで大丈夫です。
インストールができたかどうかはsystemctl
コマンドで確認できます。
$ systemctl status amazon-ssm-agent
● amazon-ssm-agent.service - amazon-ssm-agent
Loaded: loaded (/lib/systemd/system/amazon-ssm-agent.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2021-11-06 10:22:38 UTC; 7min ago
Main PID: 2733 (amazon-ssm-agen)
Tasks: 14 (limit: 1164)
Memory: 30.3M
CGroup: /system.slice/amazon-ssm-agent.service
├─2733 /usr/bin/amazon-ssm-agent
└─2763 /usr/bin/ssm-agent-worker
インストールできましたら各EC2インスタンスに必要なIAMロールをアタッチさせます。
IAMロールアタッチ
必要なIAMポリシーはAmazonSSMManagedInstanceCore
になります。
これを新規に作成したIAMロールにアタッチさせて、このIAMロールもEC2インスタンスにアタッチさせます。
Systems Manager実行
SSMエージェントをインストールし、IAMロールをアタッチさせましたらEC2がSystems Manager管理配下になります。
これでSystems MananerのRun Command
を使い、CloudWatchエージェントをインストールしてみます。
Run Command実行
Run Commandではコマンドドキュメントという事前に定義されたコマンドを実行できます。
コマンドドキュメントはユーザーが自由に作成できますし、AWS側でテンプレートドキュメントも多く用意されています。
今回CloudWatchエージェントをインストールするドキュメントもすでに用意されていますのでそちらを利用します。
ドキュメントAWS-ConfigureAWSPackage
を選択し、インストールするAWSパッケージにCloudWatchエージェントを指定後に、Systems Manager管理下のEC2インスタンスにエージェントインストールが実行されます。
実行が完了しましたらCloudWatchエージェントがインストールされていますので、同じようにsystemctl
コマンドで確かめてみます。
$ systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: enabled)
Active: inactive (dead)
インストールはされていますが、何も設定されていないので起動はされていない状態です。
CloudWatchエージェントにはウィザードで初期セットアップを簡単に済ませる機能がありますが、対象サーバーが多いと若干面倒な手順になります。
そこでここでもSystems Managerを使ってCloudWatchエージェントの設定ファイルを複数台に一括で適用させます。
パラメータ作成
Systems Managerのパラメータストアにはパスワード情報やライセンスコードといった機密情報を格納したり、Systems Manager管理下のサーバーに設定ファイルを配置させることもできます。
パラメータストアにCloudWatchエージェントの設定ファイルを作成し、Run Command
で配置、セットアップを行ないます。
{
"agent": {
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/home/bitnami/stack/apache/logs/access_log",
"log_group_name": "Apache_access.log",
"log_stream_name": "{local_hostname}"
}
]
}
}
}
}
Run Command再実行
ドキュメントはAmazonCloudWatch-ManageAgent
を指定し、コマンドパラメータのOptional Configuration Location
にパラメータストアで作成した設定ファイルを入力します。
コマンド実行が完了しますと、設定ファイルがEC2に格納されCloudWatchエージェントが起動されるようになります。
$ systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2021-11-06 15:10:13 UTC; 14min ago
Main PID: 2030 (amazon-cloudwat)
Tasks: 7 (limit: 1164)
Memory: 35.1M
CGroup: /system.slice/amazon-cloudwatch-agent.service
└─2030 /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml -envconfig /opt/aws/amazon-cloudwatch-agent
Nov 06 15:10:13 Test-WordPress systemd[1]: Started Amazon CloudWatch Agent.
Nov 06 15:10:13 Test-WordPress start-amazon-cloudwatch-agent[2030]: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json does not exist or cannot read. Skipping it.
Nov 06 15:10:13 Test-WordPress start-amazon-cloudwatch-agent[2030]: Valid Json input schema.
Nov 06 15:10:13 Test-WordPress start-amazon-cloudwatch-agent[2030]: I! Detecting run_as_user...
$ cat /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_AmazonCloudWatch-linux
{
"agent": {
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/home/bitnami/stack/apache/logs/access_log",
"log_group_name": "Apache_access.log",
"log_stream_name": "{local_hostname}"
}
]
}
}
}
}
これでCloudWatch Logsにログが転送されるようになりました。
所感
Systems Managerを使ってCloudWatchエージェントの導入・設定をしてみました。
CloudWatchエージェントの設定は面倒な手順も多く、Ansibleで一括反映するにしてもPlaybookの作りこみが面倒だと思いましたが、Systems Managerを使うことで当初想定していたよりもスムーズにログ集約基盤の構築が完了できました。
Systems Managerにはまだまだ色々な機能が備わっており、運用作業の自動化推進に向けて積極的に使っていこうと思います。
参考文献
Discussion