Datadog プライベートロケーションで内部アプリケーションを監視する

Datadog Synthetic の Private Location で監視を行う方法について記します。

# 対象読者
- Datadog Syntheticの概要を理解している。
- Dockerの概要を理解している。
- （構築手順のみ）Amazon ECS on Fargateの構築が出来る。

# プライベートロケーションとは？
>内部用アプリケーションの監視や、パブリックインターネットから接続できないプライベート URL の監視が行えます。

例えば、インターネットへ公開されているサービスであれば、Datadogが用意しているマネージドロケーションからSyntheticで特に問題無く監視できます。
![インターネットへ公開されているサービスのDatadogによる監視.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/14d7946c-3da1-7ed8-7ca6-86b6cce79c94.png)

ただ、IP制限のかけられているサービスや......

![IP制限のかかっているサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/83670240-dcc0-8e3a-5171-ce274858e0bf.png)

内部でのみアクセスされるAPIやVPNへ接続してアクセスするサイト等はDatadogから監視ができません。

![非公開のサービス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/bbc6bc51-86d2-06d3-ead3-313870652c99.png)

そこで、内部にDatadogのワーカーコンテナを作成し、内側から監視を行うのがプライベートロケーションです。

![プライベートロケーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/84612385-504d-a4f5-de39-07b095937d93.png)

## 料金
プライベートロケーション機能自体は無料なので、通常のSynthetic使用とDatadogからの請求額は同じです。
※プライベートロケーションを自身で構築して管理するので、インフラ運用維持費は必要です。

>**プライベートロケーションの使用に追加料金はかかりますか？**
>いいえ。プライベートロケーションを設定するための追加費用はありません。 プライベートロケーションへのすべてのテスト実行は、管理ロケーションへの場合と同じように請求されます。

[料金#Synthetic-モニタリング | Datadog](https://www.datadoghq.com/ja/pricing/?product=synthetic-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0)

## SyntheticのIPについて
Datadogの使用している各サービスのIPリストは[API](https://docs.datadoghq.com/ja/api/latest/ip-ranges/)で取得できます。
Syntheticで選択できるDatadogマネージドロケーションの現在のIPリストは以下のURLにて取得できます。

```
https://ip-ranges.datadoghq.com/synthetics.json
```

- すべてのロケーションのIPリストは`prefixes_ipv4`の配列に格納されています。
- 各ロケーション毎のIPリストは`prefixes_ipv4_by_location`ハッシュの中でロケーション別に格納されています。
    - 例えば、Tokyo (AWS)ロケーションの場合は、`aws:ap-northeast-1`配列に格納されています。
- 最終更新日時は`modified`に表示されています。

<details><summary>Datadog Synthetic マネージドロケーション IPリスト※2021/09/16時点</summary><div>

```
{
    "version": 43,
    "modified": "2021-09-15-22-43-00",
    "synthetics": {
        "prefixes_ipv4": [
            "13.114.211.96/32",
            "13.115.46.213/32",
            "13.126.169.175/32",
            "13.209.118.42/32",
            "13.209.230.111/32",
            "13.234.54.8/32",
            "13.238.14.57/32",
            "13.48.150.244/32",
            "13.48.239.118/32",
            "13.48.254.37/32",
            "13.54.169.48/32",
            "15.188.202.64/32",
            "15.188.240.172/32",
            "15.188.243.248/32",
            "18.130.113.168/32",
            "18.139.52.173/32",
            "18.195.155.52/32",
            "18.200.120.237/32",
            "18.229.28.50/32",
            "20.62.248.141/32",
            "20.83.144.189/32",
            "3.1.219.207/32",
            "3.1.36.99/32",
            "3.120.223.25/32",
            "3.121.24.234/32",
            "3.18.172.189/32",
            "3.18.188.104/32",
            "3.18.197.0/32",
            "34.208.32.189/32",
            "35.154.93.182/32",
            "35.176.195.46/32",
            "35.177.43.250/32",
            "40.76.107.170/32",
            "52.192.175.207/32",
            "52.35.61.232/32",
            "52.60.189.53/32",
            "52.67.95.251/32",
            "52.89.221.151/32",
            "52.9.13.199/32",
            "52.9.139.134/32",
            "63.34.100.178/32",
            "63.35.33.198/32",
            "99.79.87.237/32"
        ],
        "prefixes_ipv6": [],
        "prefixes_ipv4_by_location": {
            "aws:ap-northeast-1": [
                "13.114.211.96/32",
                "52.192.175.207/32",
                "13.115.46.213/32"
            ],
            "aws:ap-northeast-2": [
                "13.209.118.42/32",
                "13.209.230.111/32"
            ],
            "aws:ap-south-1": [
                "35.154.93.182/32",
                "13.126.169.175/32",
                "13.234.54.8/32"
            ],
            "aws:ap-southeast-1": [
                "3.1.36.99/32",
                "18.139.52.173/32",
                "3.1.219.207/32"
            ],
            "aws:ap-southeast-2": [
                "13.54.169.48/32",
                "13.238.14.57/32"
            ],
            "aws:ca-central-1": [
                "52.60.189.53/32",
                "99.79.87.237/32"
            ],
            "aws:eu-central-1": [
                "3.120.223.25/32",
                "18.195.155.52/32",
                "3.121.24.234/32"
            ],
            "aws:eu-north-1": [
                "13.48.150.244/32",
                "13.48.254.37/32",
                "13.48.239.118/32"
            ],
            "aws:eu-west-1": [
                "63.35.33.198/32",
                "18.200.120.237/32",
                "63.34.100.178/32"
            ],
            "aws:eu-west-2": [
                "18.130.113.168/32",
                "35.177.43.250/32",
                "35.176.195.46/32"
            ],
            "aws:eu-west-3": [
                "15.188.243.248/32",
                "15.188.202.64/32",
                "15.188.240.172/32"
            ],
            "aws:sa-east-1": [
                "52.67.95.251/32",
                "18.229.28.50/32"
            ],
            "aws:us-east-2": [
                "3.18.188.104/32",
                "3.18.197.0/32",
                "3.18.172.189/32"
            ],
            "aws:us-west-1": [
                "52.9.13.199/32",
                "52.9.139.134/32"
            ],
            "aws:us-west-2": [
                "52.35.61.232/32",
                "34.208.32.189/32",
                "52.89.221.151/32"
            ],
            "azure:eastus": [
                "40.76.107.170/32",
                "20.62.248.141/32",
                "20.83.144.189/32"
            ]
        },
        "prefixes_ipv6_by_location": {}
    }
}
```
</div></details>

### IP制限で使用できる？
アクセス元IPリストが公開されているならIP制限のホワイトリストに追加すれば、プライベートロケーションを作らなくても良いのでは？と思われるかもしれません。
ですが、以下の通りIPリストは突然変更されてしまうので、APIを監視して変更に追従し続ける必要があります。
>IPアドレスのレンジは不定期に予告なく変更される事がございます。
>2020/01/22 Datadogサポート回答より

APIの結果から動的にIPリストを取得し、更新日や内容の差分からIP制限のリストを修正するようなスクリプトを作成しても良いのですが、プライベートロケーションを作成する方が簡単なので個人的にはプライベートロケーションをお勧めします。

# 注意点
## 機能の有効化
プライベートロケーション機能はデフォルトでは使えないので、Datadogに有効化して貰う必要があります。
※Organization毎に申請が必要です。

プライベートロケーション画面にアクセスしても、最初は以下画像のように表示されて機能が使用できません。
![2021-07-27_21h16_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/b3a131f2-a184-48b4-5f99-f7958487abc9.png)

`Datadog 営業担当`宛でsales@datadoghq.comへメールで有効化したいOrganization名と有効化したい旨を連絡すれば、通常３営業日以内には有効化されます。

有効化された後は、プライベートロケーション画面が以下画像のように表示されます。
![2021-07-28_14h01_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/d88efd2e-720e-4743-5cb3-f35f8bc19ea2.png)

### 気になった事

#### 問い合わせ先について
問い合わせ先についてはそれぞれ下記の通り記載されています。

[ドキュメント](https://docs.datadoghq.com/ja/getting_started/synthetics/private_location/)
>この機能へのアクセスは制限されています。アクセス権をお持ちではない場合、[Datadog サポートチーム](https://docs.datadoghq.com/help/)にお問い合わせください。

[Datadogサイト](https://app.datadoghq.com/synthetics/settings/private-locations)
>現在のプランには、プライベートロケーションへのアクセスは含まれていません。
>お問い合わせください sales@datadoghq.com.

[ドキュメント](https://docs.datadoghq.com/ja/getting_started/synthetics/private_location/)では`Datadog サポートチーム`に、メール（support@datadoghq.com）で問い合わせしてね、と記載されておりDatadogサイト上の表示と異なるので問い合わせてみました。
>Q.有効化依頼は「sales@datadoghq.com」へのメールとDatadogサポートチームへのリクエストとどちらの方が早く対応頂けるでしょうか？
>A.正式な手続きとしてはsales@datadoghq.comへのご連絡よりリクエストいただくという形になっており、サポートチケットでリクエストを上げていただいた場合でも、営業側に確認するためのお時間が必要となりますため、直接 sales にご連絡いただく方がスムーズかと存じます。
>2021/08/02 Datadogサポート回答より

#### 既定の有効化可否
機能自体は無料なので、何故機能を制限しているのか謎なのでサポートに問い合わせました。

>Q.Organization作成時にデフォルトで有効化されるようには出来ないでしょうか？
>A.申し訳ございませんが、既定での変更はできません。個別具体的な契約状況により変化いたします。
>2021/08/02 Datadogサポート回答より

残念ながら私が契約しているのProプランでは出来ないようでした。
もしかしたらEnterpriseプランや個別の契約によっては出来るのかもしれないです。

#### 昔に作成したOrganizationは有効化されている？
Datadog 営業担当へリクエストしていないにも関わらず、昔に作成したOrganizationは何故か機能が有効化されていました。
確認してみたら、Organizationの作成時期が2020/08頃を境にデフォルトで機能が無効になっているようでした。
※全てではありません、作成時期が早くても無効なOrganizationもありました。

有効化されていて困ることは無いのでこちらについては詳細には問い合わせていません。

## Docker Only
プライベートロケーションのワーカーはパッケージやバイナリでの配布が無く、Dockerコンテナイメージとしてのみ配布されている為、Dockerコンテナとして起動する必要があります。
逆に言えば、Dockerがホストできる環境であればどこでも良いです。

## インターネットへ通信できる
プライベートロケーションワーカーが①Syntheticテスト設定をDatadogサーバーから取得し、②テストした結果をDatadogサーバーへ送信する為にアウトバウンドの443ポートでインターネットへ出られる環境である必要があります。

もう少し要件が厳しい場合は`intake.synthetics.datadoghq.com`と`intake-v2.synthetics.datadoghq.com`への送信を許可してください。
詳しくは、[前提条件](https://docs.datadoghq.com/ja/synthetics/private_locations/?tab=fargate#datadog-%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%AD%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A8%E3%83%B3%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)を参照してください。

プライベートロケーションワーカーをホストする環境の通信がインターネットには絶対出られない場合、2021/09/28現在本機能を使用できません。
DatadogのVPCエンドポイントがSyntheticに対応すれば、以下のドキュメント等を参考に、AWS us-east-1リージョンにあるDatadogのVPCエンドポイントへデータを送信する事で完全プライベート化できる可能性はあります。
[AWS PrivateLink を介して Datadog に接続する - Datadog Docs](https://docs.datadoghq.com/ja/agent/guide/private-link/)

# プライベートロケーション構築
機能の有効化がまだであれば先に有効化の申請をしておいてください。
## Datadogの設定
[Datadog サイト](https://app.datadoghq.com/)へログインします。
### API Key作成
Datadog API Keyが無い場合は、作成してください。

1. 画面左ナビバーの「Integrations」> 「APIs」をクリック
※ブラウザの種類や拡大率により、ナビバーは画面上部に配置されている場合があります。
1. 「API Keys」 を展開
1. 「API key name」に任意のキー名を入力し、「Create API Key」ボタンをクリック

![2021-03-19_19h21_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/213256cf-e5ea-096d-fe91-b84a1a40c299.png)

### プライベートロケーションの作成
1. 画面左ナビバーの「UX Monitoring」＞「Settings」をクリック
1. 「Add Private Location」ボタンをクリック
![2021-09-17_20h19_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/64d17bea-9dd4-15e2-fb2b-8bab9108f3af.png)
1. Nameに任意のプライベートロケーション名を入力
1. 任意のAPI Keyを選択
1. 「Save Location and Generate Configuration File」ボタンをクリック
![2021-09-17_20h43_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/79dbeb34-caaf-37d1-e4d7-f692cedfe638.png)
1. Configure your private locationの項目はワーカーを構築する環境に応じて必要な場合のみ入力
1. 「JSON」を選択し、表示された設定ファイルを保存**※この画面を閉じると二度と設定ファイルは再表示できないので注意してください！**
![2021-09-17_20h54_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/1e954978-18b9-311e-40eb-cbbbf30ab08a.png)

設定ファイルを保存したら画面は閉じても問題ありません。

プライベートロケーション画面に戻ると、作成したPrivate Locationが追加されている事が確認できます。
![2021-09-17_20h55_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/556996a5-ad2d-f199-229e-6a50d9947658.png)


## ワーカーの作成
本稿ではAWS Fargate（Amazon ECS on Fargate）の手順のみ記します。
ワーカーをホストできればお好きな環境で作成して問題ありません。

### タスク定義設定
以下の設定で新しいタスク定義を作成してください。
#### 起動タイプの互換性の選択
- 起動タイプ：FARGATE

#### タスクとコンテナの定義の設定
- タスク定義名：任意

#### タスクサイズ
タスクサイズはテストタイプとテストの同時実行数によって[ハードウェア要件](https://docs.datadoghq.com/ja/synthetics/private_locations/?tab=fargate#%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E8%A6%81%E4%BB%B6)の推奨値が変化します。
API テストのみを実行するプライベートロケーションの場合は下記のサイズで動作します。

- タスクメモリ (GB)：0.5GB
- タスク CPU (vCPU)：0.25 vCPU

concurrency（同時実行数）がデフォルト設定でブラウザテストが含まれる場合は最低でも下記以上のサイズが推奨されています。

- タスクメモリ (GB)：10GB
- タスク CPU (vCPU)：2 vCPU

#### コンテナの定義
##### スタンダード
- コンテナ名：任意
- イメージ：`datadog/synthetics-private-location-worker:latest`

##### 詳細コンテナ設定（ヘルスチェック）
- コマンド：`CMD-SHELL /bin/sh -c '[ $(expr $(cat /tmp/liveness.date) + 300000) -gt $(date +%s%3N) ]'`
- 間隔：10
- タイムアウト：2
- 開始期間：30
- 再試行：3

###### 詳細コンテナ設定（環境）
- 環境変数：プライベートロケーションの作成時に表示された設定ファイルの各値を下記の通り入力します。※必要に応じてAWS Systems Manager パラメータストアに機密データとして挿入し、参照してください。

|キー|値|
|--|--|
|DATADOG_ACCESS_KEY|[accessKeyの値]|
|DATADOG_API_KEY|[datadogApiKeyの値]|
|DATADOG_PRIVATE_KEY|[privateKeyの値]|
|DATADOG_PUBLIC_KEY_FINGERPRINT|[fingerprintの値]|
|DATADOG_PUBLIC_KEY_PEM|[pemの値]|
|DATADOG_SECRET_ACCESS_KEY|[secretAccessKeyの値]|

![2021-09-22_20h46_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/1e76b129-7a44-fa3f-72ea-c911dab545c9.png)


### サービスの作成
ワーカーをProtected Subnetに作成する場合は「ネットワーキング」タブのパブリックIPを「無効」にしてください。
（因みに下図のような構成にしておけば、外部のIP制限のかけられているサービスへ、NAT-GWへ紐づけたEIPを用いる事でIPを固定した状態でのテストが可能です。）
![protected-subnet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/aa423e19-d6ec-5b25-279c-49cac1c1d880.png)

逆に、Public Subnetに作成する場合は「ネットワーキング」タブのパブリックIPを「有効」にしてください。
![public-subnet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/abb28140-2357-4e7c-15ae-0bda37dfa298.png)

## Datadogで確認
無事ワーカーコンテナが起動し、Datadogサーバーへレポートが送信され始めると、プライベートロケーションのSTATUSが`NOT REPORTING`から`REPORTING`に変わり、このロケーションからのテストが可能になります。
![2021-09-28_19h26_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/02a14892-6e7c-171d-3573-934819b42b5a.png)

### テスト
ワーカーから任意のエンドポイントへリクエストを送信し、構築したワーカーからの監視経路に問題が無いかテストができます。

1. プライベートロケーションにマウスオーバーすると歯車アイコンが表示されるので、クリック
![2021-09-28_19h31_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/91751d18-0b62-2b6a-c84e-2a0c00c988a1.png)
1. 任意のURLと、必要に応じてオプションを指定して「Test URL」ボタンをクリック
![2021-09-28_19h58_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/85c22b6c-6d1d-033b-fadc-c3b8e2b7797e.png)
1. テスト結果が表示されるので、想定通りの結果か確認
![2021-09-28_20h01_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/28ba5b95-dc95-8bea-f287-7a2a67e8dc68.png)

# Syntheticsテストにプライベートロケーションを使用する
プライベートロケーションの構築完了後、テストの作成・編集時に作成したプライベートロケーションが追加で表示されるようになります。
Select locations項目にて作成したプライベートロケーションを選択すればテストに使用されるようになります。
![2021-09-28_20h11_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269716/f19b19c0-e2bd-5929-5246-69f4323d1c84.png)

# おまけ
[ドキュメント](https://docs.datadoghq.com/ja/synthetics/guide/identify_synthetics_bots/?tab=%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%81%8A%E3%82%88%E3%81%B3%E3%83%9E%E3%83%AB%E3%83%81%E3%82%B9%E3%83%86%E3%83%83%E3%83%97api%E3%83%86%E3%82%B9%E3%83%88#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AE%E3%83%98%E3%83%83%E3%83%80%E3%83%BC)には特に記載がありませんが、
Datadogマネージドロケーションとプライベートロケーションのデフォルトのリクエストヘッダーは同じです。

```
# マネージドロケーション
sec-datadog: Request sent by a Datadog Synthetics API Test (https://docs.datadoghq.com/synthetics/) - test_id: 123456|xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
connection: close
x-datadog-sampling-priority: 1
accept: */*
user-agent: Datadog/Synthetics
x-datadog-origin: synthetics
host: example.com
x-datadog-parent-id: 0

# プライベートロケーション
sec-datadog: Request sent by a Datadog Synthetics API Test (https://docs.datadoghq.com/synthetics/) - test_id: 123456|xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
x-datadog-sampling-priority: 1
accept: */*
x-datadog-parent-id: 0
x-datadog-origin: synthetics
connection: close
host: example.com
user-agent: Datadog/Synthetics
```

特にロケーションによってuser-agentが変わることは無いようです。
恐らくDatadogマネージドロケーションも、内部ではプライベートロケーションと同じコンテナをホストしているのだと思われます。

# 参考
[プライベートロケーションの概要 - Datadog Docs](https://docs.datadoghq.com/ja/getting_started/synthetics/private_location/)
[Synthetic テストをプライベートロケーションから実行する - Datadog Docs](https://docs.datadoghq.com/ja/synthetics/private_locations/)

[Synthetic ボットの特定 - Datadog Docs](https://docs.datadoghq.com/ja/synthetics/guide/identify_synthetics_bots/)
[API リファレンス  >  IP 範囲 - Datadog Docs](https://docs.datadoghq.com/ja/api/latest/ip-ranges/)

[AWS PrivateLink を介して Datadog に接続する - Datadog Docs](https://docs.datadoghq.com/ja/agent/guide/private-link/)

[料金#Synthetic-モニタリング | Datadog](https://www.datadoghq.com/ja/pricing/?product=synthetic-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0)