AWS Cloud Mapを使って内部通信で扱うEC2の名前解決をする

# はじめに
2020/7/29に、AWS Cloud Mapがアップデートされ、EC2のインスタンスをインスタンスIDで登録できるようになったようだ。
え、これってもしかして、これまではEC2単独で済むような低SLAの内部通信のサーバでも、わざわざ前段にNLB立ててRoute53のプライベートホストゾーンを設定しなければいけなかったのが不要になるということ？神アップデートじゃん！

ということで、さっそく試してみた。

# 前提条件
- AWS Cloud Mapって何？が分かっていること

まあ、概要は[クラスメソッド先生の記事](https://dev.classmethod.jp/articles/cloud-map-perfect/)がたいへん分かりやすいので、これを見ておけば充分かと思う。

# API取得編
基本は通常のサービスディスカバリの登録手順と同じである。
まずは名前空間を作成する。

![キャプチャ1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/6e4fddc0-9ae7-e3ba-17f1-e0e46753cf21.png)

適当な名前空間名と説明を入れて、今回は「API呼び出し」を選択する。

![キャプチャ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/0d4e4c65-7d41-5f5b-8d80-cc99453fe2e1.png)

ちょっと待てば名前空間の作成は完了。

![キャプチャ3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/9620d7bd-0039-c6be-d038-ae26c18deacb.png)

ここで、作ったドメイン名のリンクを踏み、サービスの作成を行う。

![キャプチャ12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/494cf451-dd91-b40e-6716-0173f702b216.png)


サービス名と説明とヘルスチェックはテキトーに設定する。

![キャプチャ4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/2dcda597-2718-6f6e-25e2-611c51aeea10.png)

サービスが作れたら、今度はインスタンスを紐づける。

![キャプチャ5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/81a575c8-39d3-3f9f-8c92-f958ed391f30.png)

インスタンスタイプで「EC２インスタンス」を選択し、適当なサービスインスタンスIDを設定し、対象のEC2インスタンスIDをプルダウンから選択し、カスタム属性をテキトーに設定する。

![キャプチャ6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/db39a66e-b94d-b172-20da-3651a56078a3.png)

完成！

![キャプチャ7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/bb133461-0b91-4f15-075d-83b9f090109c.png)

サービス名からIPアドレスを参照できるかCLIで試してみる。

```
$ aws servicediscovery discover-instances --namespace-name cloudmaptest-for-api --service-name web-service
```

```JSON
{
    "Instances": [
        {
            "InstanceId": "web-server-instance", 
            "NamespaceName": "cloudmaptest-for-api", 
            "ServiceName": "web-service", 
            "HealthStatus": "UNKNOWN", 
            "Attributes": {
                "AWS_EC2_INSTANCE_ID": "[インスタンス]", 
                "AWS_INSTANCE_IPV4": "172.64.0.252", 
                "Name": "[設定したタグ]"
            }
        }
    ]
}
```

あとはもうお分かりだろう。jqコマンドを使えばIPアドレスを抜き出すことができる。

```
$ jq -r '.Instances[].Attributes.AWS_INSTANCE_IPV4'
```

# DNS参照編
残念ながら、「API 呼び出しと VPC の DNS クエリ」の名前空間では、インスタンスIDでのEC2インスタンス指定はまだできないようであった。

名前空間を「API呼び出しとVPCのDNSクエリ」で作成して進めいくと…

![キャプチャ8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/c7657b2d-1bd3-4a53-286f-2a04aa2907dd.png)

EC2のインスタンスIDを選択することができない！

![キャプチャ11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/4c08b0ca-390a-341f-2f9a-fb457f246151.png)


[AWS Cloud MapのAPI仕様書](https://docs.aws.amazon.com/ja_jp/cloud-map/latest/api/API_RegisterInstance.html)にも、以下のような文章があったので、CLIからなら設定できるとかそういう話でもなさそう。

> **AWS_EC2_INSTANCE_ID**
> 
> HTTP namespaces only. The Amazon EC2 instance ID for the instance. If the AWS_EC2_INSTANCE_ID attribute is specified, then the only other attribute that can be specified is AWS_INIT_HEALTH_STATUS. When the AWS_EC2_INSTANCE_ID attribute is specified, then the AWS_INSTANCE_IPV4 attribute will be filled out with the primary private IPv4 address.

本当はこっちをやりたかったのだけど……。

# 結論
DNSを引くことができれば、現状でELBを経由している部分について、ELBを削除してAWS Cloud Mapを設定してあげさえすればアプリケーションの修正が不要になって最高だったので一歩見劣り。それでも、リソースを減らせるというのは嬉しいのである。