ElasticIPを当てずにパブリックIPでドメインを半固定する

# ElasticIPを当てずにパブリックIPでドメインを半固定する

## はじめに

ElasticIPを当てるとお金かかるなぁ～。でもこの環境は起動時に名前当ててアクセスしたいなぁ～。って思っている節約家のための記事

やっていることとしては、インスタンス起動時スクリプトでroute53に自身のPublic IPを登録しにいくだけ。

対象読者はaws-cli少し読めてsystemdが少し分かる人だと良いと思う。
書いたコードまるっと載せてるので、同じ環境でそのままやったらできると思う。

## 環境

AWSのAmazon Linux 2のt2.nano

|ソフトウェア|バージョン等|
|:--:|:--:|
|AWS CLI|1.14.8|
|Amazon Linux2|Amazon Linux 2 LTS Candidate AMI 2017.12.0.20171212.2 x86_64 HVM GP2|

## 動作に必要なパッケージ

+ aws-cli
  - 当然ながらRoute53にリクエストするために必要。Amazon Linux2ならデフォで入ってるはず
  - awsコマンド実行に必要EC2Roleが当たっている or `aws configure`は既に終わっている前提
+ jq
  - jsonをパースするために利用。

## 準備するファイル3つ

### Hosted Zone IDを確認するためのスクリプト

1回使い切りのファイル。HostedZoneのIDが分かる場合は使わなくてOK。

`check_hosted_zone_id.sh`って名前でも付けて任意の場所に配置しておいてください。

`sh check_hosted_zone_id.sh`で実行するとドメイン名入力を要求するので、Route53に登録しているドメインを入力してください。存在する場合はIDが出ます。

```shell
#! /bin/sh
echo "Enter your domain(e.x. uji52.com)"
read DOMAIN
aws route53 list-hosted-zones|jq '.HostedZones[]|select(.Name=="'${DOMAIN}'.")|.Id'
```

### AWS CLIを使ってRoute53に値を登録しにいくスクリプト

このスクリプトを起動時に呼び出してRoute53の値を更新に向かいます

2行目のIDは上のスクリプトで出力されたIDを貼り付けておいてください。

`/usr/local/etc/route53/dns_update.sh`という名前で配置して`chmod +x`で実行可能にしておいてください。

.oO(もっと良い置き場所ある気がしている)

```shell
#! /bin/sh
HOSTED_ZONE_ID="/hostedzone/ZXXXXXX525252"
IP_ADDR=`curl 169.254.169.254/latest/meta-data/public-ipv4 2> /dev/null`
DATE=`date`
sed "s/<%DATE%>/${DATE}/" < /usr/local/etc/route53/route53.json.template | sed "s/<%IP_ADDR%>/${IP_ADDR}/" > /usr/local/etc/route53/route53.json
aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} --change-batch file:///usr/local/etc/route53/route53.json
```

### Route53にリクエストする為のjsonファイルのテンプレート

Route53は古くからのサービス故、CLIでもjsonファイルを送りこまなきゃ設定ができない子なので、送り込むためのjsonファイルをこんな感じで`/usr/local/etc/route53/route53.json.template`という名前で配置。

Nameのところに、このインスタンスに付けたい名前を付けておきましょう。
UPSERTなので、なかったら作ってくれるし、あったら更新してくれるよ

```json
{
  "Comment": "<%DATE%>",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "test.uji52.com.",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "<%IP_ADDR%>"
          }
        ]
      }
    }
  ]
}
```

## 実際に更新してみる

```shell
$ /usr/local/etc/route53/dns_update.sh
{
    "ChangeInfo": {
        "Status": "PENDING", 
        "Comment": "Sun Dec 24 06:45:45 UTC 2017", 
        "SubmittedAt": "2017-12-24T06:45:46.115Z", 
        "Id": "/change/ZXXXXXX525252"
    }
}
```

上記のようなログが出力されれば更新が完了しているので、実際にAWSマネジメントコンソールから確認してみると変更が確認できます。

## 自動起動にしてみる

正直systemdに詳しくないので自信は無いけどこんな感じで記述

ファイル名は`/etc/systemd/system/route53.service`

```
[Unit]
Description=DNS Update
After=network.target

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/local/etc/route53/dns_update.sh

[Install]
WantedBy=multi-user.target
```

設定作ったらデーモンをリロードせあかんらしいから再起動してサービス起動して確認。

```shell
$ systemctl daemon-reload
$ systemctl start route53
$ systemctl status route53
● route53.service - DNS Update
   Loaded: loaded (/etc/systemd/system/route53.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sun 2017-12-24 06:10:24 UTC; 4s ago
  Process: 3534 ExecStart=/usr/local/etc/route53/dns_update.sh (code=exited, status=0/SUCCESS)
 Main PID: 3534 (code=exited, status=0/SUCCESS)

Dec 24 06:10:24 xxx systemd[1]: Started DNS Update.
Dec 24 06:10:24 xxx systemd[1]: Starting DNS Update...
Dec 24 06:10:26 xxx dns_update.sh[3534]: {
Dec 24 06:10:26 xxx dns_update.sh[3534]: "ChangeInfo": {
Dec 24 06:10:26 xxx dns_update.sh[3534]: "Status": "PENDING",
Dec 24 06:10:26 xxx dns_update.sh[3534]: "Comment": "Sun Dec 24 06:10:24...,
Dec 24 06:10:26 xxx dns_update.sh[3534]: "SubmittedAt": "2017-12-24T06:1...,
Dec 24 06:10:26 xxx dns_update.sh[3534]: "Id": "/change/ZXXXXXX525252"
Dec 24 06:10:26 xxx dns_update.sh[3534]: }
Dec 24 06:10:26 xxx dns_update.sh[3534]: }
Hint: Some lines were ellipsized, use -l to show in full.
```

更新ログが良い感じに出てるから、systemdで呼び出しはしっかりできてるっぽい。

ので、自動起動として登録して完了

```shell
$ systemctl enable route53
```

## まとめ
すぐできるし作ろうと思うも、めんどくさくて結局やらんかったんです。
まぁ節約意識大事やと思うんで、日曜大工感覚で作成。

ざっくりしたメモとして残しているだけなので、手順に不足等あったらお教えくださいませ。