AWSのマネージドサービスをZABBIXで監視する

# 背景
AWS内の監視について、EC2の監視についてはZABBIXサーバを使用している。
マネージドサービス（下記の例だとFSX）の監視についてはCloudWatchを使用している。
メール通知の内容を見やすくするためEventBridgeを挟んでいる。（入力トランスフォーマーを使用）

![AWSZABBIX1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/0b22f321-bbcb-21b1-cd03-dcf61d099d9e.png)

しかし、これだとマネージドサービスの状態やグラフ確認の際、CloudWatchの画面を参照する必要がある。
下記の様にZABBIXからCloudWatchのAPIをたたいて情報取得すれば、ZABBIXコンソールから一元管理可能となる。

![AWSZABBIX2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/ff4a156d-5f27-0e86-dccd-fe3ac5291fab.png)

# 環境
* Python 3.6.8
* zabbix_server (Zabbix) 5.0.18

ZABBIXの外部チェックを利用する。外部チェックでシェルスクリプトをキック。
（この際、実行するファイル名に加え、メトリクス名、インスタンスID等を引数として指定する。）
シェルスクリプトからPythonのスクリプトをキックする。
この中でget_metric_statics APIを使用してCloudWatchから値を取得する。

![AWSZABBIX3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/406ed425-4372-d90a-e932-4baa1687c85b.png)

# 参考
[Boto3公式ドキュメント(get_metric_statistics)](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudwatch.html#CloudWatch.Client.get_metric_statistics)

# 手順
## 事前準備
* Pythonのインストール

```bash
yum install python3
pip3 install boto3
```

* IAMロールの設定
手順は割愛します。CloudWatchにアクセス可能なポリシーを付与したIAMロールを作成してEC2に付与します。
ZABBIXがオンプレの場合はAWS Configureでアクセスキーを埋め込み。

## スクリプト用意

* 外部ファイルを置く場所に移動
ZABBIXの設定ファイルの中にパスの記載があります。

```bash
cat /etc/zabbix/zabbix_server.conf | grep ExternalScripts
### Option: ExternalScripts
# ExternalScripts=${datadir}/zabbix/externalscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
cd /usr/lib/zabbix/externalscripts
```

* Pythonスクリプト準備
今回はテストでEC2のCPU利用率を取得するスクリプトを作成しました。
他のマネージサービスについてもパラーメータを変更すれば取得可能です。

```python:cloudwatch.py
import boto3
import datetime
import sys

args = sys.argv
name_space = args[1]
metric_name = args[2]
dimensions = args[3]
dimensions_value = args[4]

def get_metrics(name_space,metric_name,dimensions,dimensions_value):
    client = boto3.client('cloudwatch',
             region_name='ap-northeast-1')

    response = client.get_metric_statistics(
        Namespace = name_space,
        MetricName = metric_name,
        Dimensions = [
             {
            'Name': dimensions,
            'Value': dimensions_value
            },
        ],
        StartTime=datetime.datetime.utcnow() - datetime.timedelta(seconds=600),
        EndTime=datetime.datetime.utcnow(),
        Period = 300,
        Statistics = ['Average']
    )
    response = float(response['Datapoints'][0]['Average'])
    print('{:.3g}'.format(response))

get_metrics(name_space,metric_name,dimensions,dimensions_value)
```
シェルスクリプトから引数を受取りget_metrics関数を実行します。
関数の中で期間などを指定してCloudWatchから値を取得します。
CPU使用率の小数点以下の桁数が多いので丸めています。
※パラメータ等は公式資料を参照下さい。

* シェルスクリプト準備
このシェルをZABBIXの外部チェックで呼び出します。

```bash:cloudwatch.sh
python3 /usr/lib/zabbix/externalscripts/cloudwatch.py $1 $2 $3 $4
```

* 実行権限付与
```bash
chmod 755 cloudwatch.sh
```

## ZABBIX側設定

* マクロ設定
アイテムのキーに直接インスタンスIDなどを指定しても良いですが、汎用的な作りにするためにマクロに値を設定します。

![AWSZABBIX4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/146b6c31-89bd-ac4d-87da-e7d0d17d84e9.png)

|マクロ|値|
|---|---|
|{$NAME_SPACE1}|AWS/EC2|
|{$METRIC_NAME1}|CPUUtilization|
|{$DIMENSIONS1}|InstanceId|
|{$DIMENSIONS_VALUE1}|i-xxxxxxxxxxxxxxxxxxxxxx|

* アイテム設定
![AWSZABBIX5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/82b2d811-6774-3f11-306f-d71aa270f4b9.png)

設定する項目（名前などは何でも良いです。）
![AWSZABBIX7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/34d16159-8201-4e64-b53c-ad1af3b5f91d.png)

## 確認

* データ取得確認
「監視データ」⇒「最新データ」から値が取得されていることを確認します。
![AWSZABBIX8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/33a1b7a1-4211-fb0f-456f-4aca64d01c04.png)