NewRelicのalert policyを自動で適用する


NewRelicの監視対象サーバーを追加するのは簡単ですが、通常default policyが適用されてしまいます。

それを毎回GUIからごにょごにょするのも面倒だったので、ちゃんと自動化しました。

## 方法

実現方法としては３つ。

1. default policyをproductionにしちゃう
2. 別OrganizationにしてTokenわける
3. newrelic server monitoringのAPIを使ってpolicyを更新する
  - 参考：https://discuss.newrelic.com/t/aws-auto-scaling-and-server-notification-groups/3482


１と２は、ラフに行う行えるものの、

1の場合

- stagingとかdevelop、monitoring用のサーバー群などのpolicy変更し忘れると痛い。
- serverのrole(app, job, その他)に合わせた細かいpolicy設定が不可能

2の場合

- roleと環境の数だけswitching増えるのでめんどい

という問題点があるので３でやることにしました。


## 方法３を利用した自動適用に向けた準備

require

- curl
- jq

### labelでmonitorするserverを識別する

まず、追加されたサーバーがどのようなものなのか分からないと、どのalert policyを適用して良いか分からないのでnewrelicのlabelを利用します。

/etc/newrelic/nrsysmond.cfg

```
license_key=YOUR_LICENSE_KEY
labels=YOUR_SERVER_LABEL
```

https://docs.newrelic.com/docs/servers/new-relic-servers-linux/installation-configuration/configuring-servers-linux

### APIの有効化

次に、newrelicのAPIを有効化してAPIようのkeyを取得します。

![newrelic.png](https://qiita-image-store.s3.amazonaws.com/0/8250/66ff0aad-f66d-7d5b-f6c0-bc574d121757.png)

どのようなお口があるかは下記URLを参照

https://rpm.newrelic.com/api/explore

### Get policy ids

適用したいserver alert policyのIDを知ります。

Call

```bash
$ curl -X GET 'https://api.newrelic.com/v2/alert_policies.json' \
     -H 'X-Api-Key:YOUR_API_KEY' \
     -d 'filter[type]=server' | jq '.alert_policies[] | {"id": .id, "name": .name}'

```

Result example

```json
{
  "id": 123456,
  "name": "Default server alert policy"
}
{
  "id": 234567,
  "name": "Local server alert policy"
}
{
  "id": 345678,
  "name": "Staging server alert policy"
}
{
  "id": 456789,
  "name": "Production server alert policy"
}
```

### Get servers with label

次に、LabelをベースにサーバーIDを引っ張ります。

Call

```bash
$ curl -X GET 'https://api.newrelic.com/v2/servers.json' \
     -H 'X-Api-Key:YOUR_API_KEY' \
     -d 'filter[labels]=YOUR_LABEL' | jq -c '[.servers[].id]'
```

Result

```json
[1234567]
```

### Update policy's server list

policyをupdateします。

```bash
$ curl -X PUT 'https://api.newrelic.com/v2/alert_policies/YOUR_ALERT_POLICY_ID.json' \
     -H 'X-Api-Key:YOUR_API_KEY' \
     -H 'Content-Type: application/json' \
     -d \
'{
  "alert_policy": {
    "links": {
      "servers": [
        YOUR_TARGET_SERVER_ID
      ]
    }
  }
}' | jq '.alert_policy.links.servers'
```

Result

```json
[1234567]
```

追加されたことがわかります。


### 取得から更新までいっぺんにやると

こんな感じ

```bash
curl -X GET 'https://api.newrelic.com/v2/servers.json' \
     -H 'X-Api-Key:YOUR_API_KEY' \
     -d 'filter[labels]=YOUR_LABEL' | \
     jq -c '[.servers[].id]' | \
xargs -n 1 -t -I{} \
curl -X PUT 'https://api.newrelic.com/v2/alert_policies/YOUR_ALERT_POLICY_ID.json' \
     -H 'X-Api-Key:YOUR_API_KEY' \
     -H 'Content-Type: application/json' \
     -d '{ "alert_policy": { "links": { "servers": {} }}}'
```

[newrelic cookbook](https://github.com/reproio/newrelic) (本家がlabel対応していないので、folkして対応させたおきました）とかつかって、cookするとこんな感じです。

```ruby
package 'jq'

include_recipe 'newrelic'

bash 'apply-policy' do
  user 'root'
  code <<-EOH
curl -X GET 'https://api.newrelic.com/v2/servers.json' \
     -H 'X-Api-Key: #{node['newrelic']['api']['license']}' \
     -d 'filter[labels]=#{node['newrelic']['server_monitoring']['labels']}' | \
     jq -c '[.servers[].id]' | \
xargs -n 1 -t -I{} \
curl -X PUT 'https://api.newrelic.com/v2/alert_policies/#{node['newrelic']['server_monitoring']['alert_policy']}.json' \
     -H 'X-Api-Key: #{node['newrelic']['api']['license']}' \
     -H 'Content-Type: application/json' \
     -d '{ "alert_policy": { "links": { "servers": {} }}}'
  EOH
end
```

## その他tips

defaultはdefaultとしてゴミサーバーを放り込めるので残しておいたほうが楽です。

autoscaleもこの方法を用いれば楽になりますね。