[AWS]CloudWatchエージェントの設定をある程度Ansibleからやってみる

2019/8/14追記: [AWS Systems Manager Quick Setup](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-quick-setup.html)で手軽にセットアップできるようになったようなので、この記事は不要かも知れない。

参考

- [AWS Systems Manager Quick Setup - AWS Systems Manager](https://dev.classmethod.jp/cloud/systems-manager-quick-setup/)
- [[新機能] Systems Manager Quick Setup ですばやく設定可能になりました！ ｜ DevelopersIO](https://dev.classmethod.jp/cloud/systems-manager-quick-setup/)

めんどっちいEC2インスタンスへのCloudWatchエージェントのメトリクス設定をAnsibleである程度頑張る。
ある程度は手動。

# 前提条件

- [SSM エージェントがインストール済み](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ssm-agent.html)
- Amazon Linux

# 環境

- Ansible 2.7.10

# EC2ロールへの権限設定

IAMでEC2にアタッチしているロールに `CloudWatchAgentServerPolicy` `AmazonEC2RoleforSSM` の2つを付与する。

- AWSマネジメント コンソールのIAMを開く
- IAMの左メニューから「ロール」をクリック
- 対象のロールをクリック
- 「アクセス権」タブ「Permissions Policies」の「ポリシーをアタッチします」をクリック
- 対象のポリシーを検索して左側のチェックボックスにチェックを入れる
- 「ポリシーのアタッチ」をクリック

反映されるまでには若干の時間差がある模様。

# インターフェイスとゲートウェイの作成

- AWSマネジメント コンソールのVPCを開く
- 左メニューから「エンドポイント」を選択
- 「エンドポイントの作成」をクリック
- 以下の内容でInterfaceなエンドポイントを作成する
    - サービスカテゴリ: AWSサービス
    - サービス名: 下記4種分を個別に作成
        - com.amazonaws.(リージョン名).ssm
        - com.amazonaws.(リージョン名).ec2messages
        - com.amazonaws.(リージョン名).ec2
        - com.amazonaws.(リージョン名).ssmmessages
    - VPC: CloudWatchエージェントで管理したいEC2のあるVPC
    - サブネット: IPアドレスに余裕がありそうなとこ
    - このエンドポイントで有効にする: チェック入れとく
    - セキュリティグループ: HTTPS接続が許可されているものを選択
    - ポリシー: 必要に応じて
- 以下の内容でGatewayなエンドポイントを作成する
    - サービスカテゴリ: AWSサービス
    - サービス名: 下記1種分を作成
        - com.amazonaws.(リージョン名).s3
    - VPC: CloudWatchエージェントで管理したいEC2のあるVPC
    - ルートテーブル: 適当に必要なとこ。必要なAZに作る
    - ポリシー: 必要に応じて

# AWS Systems Managerでのパラメータ設定

- AWSマネジメント コンソールのAWS Systems Managerを開く
- 左欄から「共有リソース」→「パラメータストア」
- 「パラメータの作成」
- 以下の内容でパラメータを作成
    - 名前: AmazonCloudWatch-linux
    - 説明: 適当に
    - 利用枠: 標準
    - タイプ: 文字列
    - 値: 以下参照
- 「パラメータを作成」をクリック

## AWS Systems Managerのパラメータの内容

```json
{
	"metrics": {
		"append_dimensions": {
			"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
			"ImageId": "${aws:ImageId}",
			"InstanceId": "${aws:InstanceId}",
			"InstanceType": "${aws:InstanceType}"
		},
		"metrics_collected": {
			"collectd": {
				"metrics_aggregation_interval": 60
			},
			"cpu": {
				"measurement": [
					"cpu_usage_idle",
					"cpu_usage_iowait",
					"cpu_usage_user",
					"cpu_usage_system"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				],
				"totalcpu": false
			},
			"disk": {
				"measurement": [
					"used_percent",
					"inodes_free"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"diskio": {
				"measurement": [
					"io_time",
					"write_bytes",
					"read_bytes",
					"writes",
					"reads"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"netstat": {
				"measurement": [
					"tcp_established",
					"tcp_time_wait"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 10,
				"service_address": ":8125"
			},
			"swap": {
				"measurement": [
					"swap_used_percent"
				],
				"metrics_collection_interval": 60
			}
		}
	}
}
```

パラメータは[amazon-cloudwatch-agent-config-wizard](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html)を使用して生成する事もできる。

この辺はTerraformで自動化できるかも知れない。

# Ansible Playbook を書く

```yaml:cloudwatch-agent/tasks/main.yml
---
- name: enable epel repo
  yum: name=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm state=present
  become: yes

- name: install python-lxml
  yum:
    name: python-lxml
  become: yes

- name: copy ssm agent profile template
  copy:
    src: /etc/amazon/ssm/seelog.xml.template
    dest: /etc/amazon/ssm/seelog.xml
    remote_src: yes
  become: yes

- name: edit ssm agent profile
  xml:
    path: /etc/amazon/ssm/seelog.xml
    xpath: /seelog/outputs/custom
    attribute: name
    value: cloudwatch_receiver
  become: yes

- name: edit ssm agent profile 2
  xml:
    path: /etc/amazon/ssm/seelog.xml
    xpath: /seelog/outputs/custom
    attribute: formatid
    value: fmtdebug
  become: yes

- name: edit ssm agent profile 3
  xml:
    path: /etc/amazon/ssm/seelog.xml
    xpath: /seelog/outputs/custom
    attribute: data-log-group
    value: ssm-metrics
  become: yes

- name: restart ssm agent
  service:
    name: amazon-ssm-agent
    state: restarted
  become: yes

- name: add collectd
  command: yum provides /usr/share/collectd/types.db
  args:
    warn: no
  become: yes

- name: install collectd
  yum:
    name: collectd
  become: yes

- name: download cloudwatch agent package
  get_url:
    url: https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
    dest: /tmp

- name: install cloudwatch agent
  command: rpm -U /tmp/amazon-cloudwatch-agent.rpm
  args:
    warn: no
  ignore_errors: yes
  become: yes

- name: unlink cloudwatch agent package
  file:
    path: /tmp/amazon-cloudwatch-agent.rpm
    state: absent

- name: apply cloudwatch agent setting
  command: /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux -s
  become: yes
```

XMLとRPMの処理がどうにも微妙だなぁ…
署名の確認はやっていない。

# 参考

- [【EC2】 CloudWatch エージェントで Auto Scaling グループ配下にあるインスタンス内のログを CloudWatch Logs へ転送 (前編) | ハックノート](https://hacknote.jp/archives/46459/)
- [コマンドラインを使用して CloudWatch エージェントをダウンロードおよび設定する - Amazon CloudWatch](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/download-cloudwatch-agent-commandline.html)
- [CloudWatch エージェントパッケージの署名を確認する - Amazon CloudWatch](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/verify-CloudWatch-Agent-Package-Signature.html)
- [CloudWatch エージェントで使用する IAM ロールおよびユーザーを作成する - Amazon CloudWatch](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html)
- [CloudWatch エージェントにより収集されるメトリクス - Amazon CloudWatch](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/metrics-collected-by-CloudWatch-agent.html)
- [Systems Manager の VPC エンドポイントの設定 - AWS Systems Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-setting-up-vpc.html)
- [ウィザードを使用して CloudWatch エージェント設定ファイルを作成する - Amazon CloudWatch](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html)