Raspberry Pi(Debian)でRoute53を更新する

# 概要
諸般の事情により、自宅に置いたRaspberry Pi(Debian)で直接PPPoE接続することになった。
そのため、外からアクセスするためのDNSレコード更新を、自分でやらねばならない。
DNSは別件でRoute53を使っており、aws CLIで簡単に更新できるので、Route53をDDNS的に使うことにした。

# ポイント/狙い
- 技術的に難しい/新しいことは何もなく、有りものの組み合わせで実現しているが、有りもの全体をまとめた記事がなかったので残しておく。
- 昔はDDNS関係の記事がいっぱいあった気がするが、今は自宅にサーバを置くような時代じゃないようで、近年の記事がない。なので近況更新のような位置づけで記事を残す。

# 作戦
- 前述の通り、Route53はaws CLIで更新できる。なのでPPPoE接続時にaws CLIを実行する。
- 具体的には、PPPoE接続時に実行される/etc/ppp/ip-up.local(シェルスクリプト)でaws CLIを実行する。

# 手順
### aws CLIを入れる
(記事の主旨と直接関係ない話だが....)
pipでawscliをinstallしている古い記事は多いが、pipでOS全体の環境を荒らされることが多くて好きじゃない。
[aws公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html)で紹介されているv2だと、OSに入っているPythonに依存しないバイナリのようなので、これがよさそう。しかもARM用も用意されているし。
しかしいざやってみると、ARMで64bitOSが動いている前提のバイナリのようで動いてくれない。おそらくEC2 A1インスタンスとかで動かして欲しいのだろう。(⇒[参考](https://github.com/aws/aws-cli/issues/4943))
なので残念ながらRaspberry Pi(Debian 32bit)においては、従来のPythonに依存したaws CLI v1を動かすしかない。せめてvirtualenvのpipで動いてくれる以下のzipファイルから入れることとする。

```
curl -s "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
cd ./awscli-bundle
./install -i /usr/local/aws -b /usr/local/bin/aws
```
aws CLIの設定は後ほどやる。

### IAMユーザ(ポリシー)を作成する(任意)
上記のaws CLI実行に際し、目的のレコードのみを更新出来るIAMユーザ(とそのポリシー)を作成する。
(別に既存ユーザや、FullAccessのユーザで実行しても技術的には問題ないが、さすがにそれは怖いので避ける)
作業としては、awsコンソール(IAM)で以下のポリシーを追加して、このポリシーを持つユーザを追加する。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "route53:ChangeResourceRecordSets",
            "Resource": [
                "arn:aws:route53:::hostedzone/xxxxxxxxxx"
            ]
        }
    ]
}
```
ゾーンIDは、同じくawsコンソールのRoute53で確認出来る。
このようにして作ったユーザーについて、aws CLIでプロフィールを設定しておく。

```
aws configure --profile xxxxx
```

### PPPoE接続時にaws CLIを実行するスクリプトを作成する
唐突ではあるが、`/etc/ppp/ip-up`というファイルの中を見ると、以下のように書かれている。
>```/etc/ppp/ip-up
#!/bin/sh
#
# This script is run by the pppd after the link is established.
# It uses run-parts to run scripts in /etc/ppp/ip-up.d, so to add routes,
# set IP address, run the mailq etc. you should create script(s) there.
#
# Be aware that other packages may include /etc/ppp/ip-up.d scripts (named
# after that package), so choose local script names with that in mind.
```

またこのファイルの途中で
>```/etc/ppp/ip-up
# This script can be used to override the .d files supplied by other packages.
if [ -x /etc/ppp/ip-up.local ]; then
exec /etc/ppp/ip-up.local "$@"
fi
```

となっているので、`/etc/ppp/ip-up.local`というシェルスクリプトを作ってやる。
中身は以下のようにした。

```/etc/ppp/ip-up.local
#! /bin/bash

DIR="/etc/ppp"
JSON="$DIR/ip-up.json"
NEW_IP=$PPP_LOCAL
 
update_route53 () {
cat <<EOF > $JSON
{
  "Comment": "Updated by /etc/ppp/ip-up.local",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "$1",
        "Type": "A",
        "TTL": 3600,
        "ResourceRecords": [
          {
            "Value": "$NEW_IP"
          }
        ]
      }
    }
  ]
}
EOF
/usr/local/bin/aws route53 change-resource-record-sets --hosted-zone-id $2 --change-batch file://$JSON  --profile xxxxx
}

NAME="xxx.xxxxx.com"
HOSTZONE_ID="xxxxxxxxxx"
update_route53 $NAME $HOSTZONE_ID
```
まずPPPoEで取得したIPアドレスを含むjsonを作成し、それ使ってaws CLIでRoute53のレコードを更新している。
jsonファイルの場所が決め打ちっぽくて美しくないが、とりあえず問題ないのでこれで行く。

以上

# あとがき
後々書こうと思っている記事の下準備のために書いているので、驚くほど中身が薄い。