[JAWS-UG CLI] ACM入門 #2 Route53とSESによるドメイン利用環境の構築

これは<A HREF="http://qiita.com/zakky/items/29cf8095f6faa24f216b" target=_blank>AWS Certificate Manager (ACM)入門ハンズオン資料</A>の一部です。

前提条件
========

ドメインを取得済みであること。
無料でドメインを取得可能です。こちらの手順で取得しておいてください。


作業環境
-----------
Amazon Linux EC2インスタンス、AWS CLIがインストールされたUNIX系端末を想定しています。
ウィンドウズ端末の場合、EC2(Amazon Linux)へログインして作業することを推奨します。
CYGWINやPowershellなどはサポート対象外です。自己責任で利用してください。


なるべく新規アカウントを使用してください
-----------
今回利用するサービスを既に利用しているアカウントの場合、想定外の動作をする場合が有ります。
AWSアカウントはいくつ作成しても無料ですから新規アカウントを推奨します。
（電子メイルアドレスさえ異なれば、同一クレジットカード・電話番号でも複数作成可能です）
ハンズオン資料の出力結果は新規アカウントで行った場合を想定しています。既に利用中のアカウントで他のデータが存在する場合、これと異なったり想定外の動作をする場合が有ります。自己責任で行ってください。


必要な権限
-----------

トラブル防止の為、全ての操作が可能なクレデンシャル（アカウント）を原則として使用してください。


JSON LINT
-------

JSONファイルの正当性を確認するために jsonlint コマンドを使用しています。
無くてもハンズオンの進行には問題ありませんがインストールを推奨します。 (<A HREF="http://qiita.com/tcsh/items/4bea17afecbc8fc8abe0#2-npm%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB" )target=_blank>導入方法はこちら</A>)


AWS CLI
-------

以下のバージョンで動作確認済

* AWS CLI 1.11.3

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.3 Python/2.7.11 Darwin/15.6.0 botocore/1.4.61
```

バージョンが古い場合、次のコマンドを実行して最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

SESが東京リージョンには無いため、今回はバージニア(us-east-1)リージョンで作業します。

```bash:変数の設定:
export AWS_DEFAULT_REGION='us-east-1'
```

0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```
```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile                <not set>             None    None
      access_key     ****************2LMA shared-credentials-file
      secret_key     ****************VXyK shared-credentials-file
          region                us-east-1              env    AWS_DEFAULT_REGION
```




1. Route53への登録
===========

1.1. ドメイン名の変数への格納
---------------

変数へドメイン名を格納します。
ここでは example.tk とします。自分のドメイン名に読み替えてください。

```bash:コマンド:
DOMAINNAME="example.tk" && echo ${DOMAINNAME}
```

```text:結果(例):
      example.tk
```

1.2. ドメイン名をRoute53へ登録
---------------

```bash:コマンド
HOSTED_ZONE_ID=`aws route53 create-hosted-zone \
 --name ${DOMAINNAME} --caller-reference ${DOMAINNAME} \
 --query HostedZone.Id --output text` && echo ${HOSTED_ZONE_ID}
```
```text:結果(例):
      /hostedzone/Z1S92TCRCPLEYH
```

オプションの --caller-reference は登録時に処理を区別するために指定する任意の文字列です。
ここではドメイン名と同じ文字列としていますが、例えば削除してすぐに同じドメインを登録する場合など、過去の同一ドメインの情報が残っている場合、別の文字列を指定しないと登録できません。
（この文字列とドメイン名によってRoute53は内部で一意性を保ち識別をしています）


1.3. ネームサーバ一覧の取得
---------------

```bash:コマンド:
aws route53 get-hosted-zone --id ${HOSTED_ZONE_ID} --query DelegationSet.NameServers
```
```text:結果(例):
      [
          "ns-1888.awsdns-44.co.uk",
          "ns-1349.awsdns-40.org",
          "ns-41.awsdns-05.com",
          "ns-575.awsdns-07.net"
      ]
```

次の手順で使いますからメモしておきましょう。

1.4. ネームサーバをレジストラへ登録
-----------------------

Route53により取得したネームサーバ4つを、レジストラへ登録します。
<A HREF="http://qiita.com/zakky/items/a1ff8af60415e05956e4#3-%E3%83%8D%E3%83%BC%E3%83%A0%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E5%A4%89%E6%9B%B4" target=_blank>「ACM入門 #1 無料でドメイン名を登録する」の「3. ネームサーバの変更」から再開し登録します</A>。
登録完了したら、ここへ戻ってきます。
自分で独自に取得したドメインの場合、適宜登録を行ってください。



2. Route53とSESの設定
=================

登録したドメイン名をRoute53とSESへ設定をして使用できるようにします。

2.1. ドメイン認証トークンの取得
-----------------------

SESを使用するためにはドメイン名所有確認のため認証が必要です。
これはDNSサーバへ指定の内容を登録することで行われます。

```bash:コマンド
TOKEN=`aws ses verify-domain-identity --domain ${DOMAINNAME} --output text` && echo ${TOKEN}
```
```text:結果(例):
      ASL17Ti+rLdMngS+GBw+2DQDVqVpJFJ64qkGvQYRZNI=
```


2.2. Route53への登録
-----------------

（待ち時間短縮のため、本項の作業はなるべく迅速に作業してください）

取得した認証トークンを _amazonses のTXTレコードとして登録します。
同時に電子メイル受信のためのMXレコードも登録します。
まずは登録内容を記載したJSONファイルを作成します。

```bash:コマンド:
cat << EOF > route53.json
{
  "Comment": "SESincoming",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "_amazonses.${DOMAINNAME}.",
        "Type": "TXT",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "\"${TOKEN}\""
          }
        ]
      }
    },
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "${DOMAINNAME}.",
        "Type": "MX",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "10 inbound-smtp.${AWS_DEFAULT_REGION}.amazonaws.com."
          }
        ]
      }
    }
  ]
}
EOF
cat route53.json
```
```text:結果(例):
      {
        "Comment": "SESincoming",
        "Changes": [
          {
            "Action": "CREATE",
            "ResourceRecordSet": {
              "Name": "_amazonses.example.tk.",
              "Type": "TXT",
              "ResourceRecords": [
                {
                  "Value": "\"ASL17Ti+rLdMngS+GBw+2DQDVqVpJFJ64qkGvQYRZNI=\""
                }
              ]
            }
          },
          {
            "Action": "CREATE",
            "ResourceRecordSet": {
              "Name": "example.tk.",
              "Type": "MX",
              "ResourceRecords": [
                {
                  "Value": "10 inbound-smtp.us-east-1.amazonaws.com."
                }
              ]
            }
          }
        ]
      }
```

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

```bash:コマンド:
jsonlint -q route53.json
```

```text:結果:
      返り値なし
```

問題無ければRoute53へ登録します。

```bash:コマンド:
aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} \
 --change-batch file://route53.json
```
```text:結果(例):
      {
          "ChangeInfo": {
              "Status": "PENDING",
              "Comment": "SESincoming",
              "SubmittedAt": "2016-10-09T11:00:58.997Z",
              "Id": "/change/C2O13TDYOGJCSD"
          }
      }
```


2.3. Route53登録内容の確認
-----------------

```bash:コマンド:
aws route53 list-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID}
```
```text:結果(例):
      {
          "ResourceRecordSets": [
              {
                  "ResourceRecords": [
                      {
                          "Value": "10 inbound-smtp.us-east-1.amazonaws.com."
                      }
                  ],
                  "Type": "MX",
                  "Name": "example.tk.",
                  "TTL": 300
              },
              {
                  "ResourceRecords": [
                      {
                          "Value": "ns-1139.awsdns-14.org."
                      },
                      {
                          "Value": "ns-336.awsdns-42.com."
                      },
                      {
                          "Value": "ns-975.awsdns-57.net."
                      },
                      {
                          "Value": "ns-1865.awsdns-41.co.uk."
                      }
                  ],
                  "Type": "NS",
                  "Name": "example.tk.",
                  "TTL": 172800
              },
              {
                  "ResourceRecords": [
                      {
                          "Value": "ns-1139.awsdns-14.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400"
                      }
                  ],
                  "Type": "SOA",
                  "Name": "example.tk.",
                  "TTL": 900
              },
              {
                  "ResourceRecords": [
                      {
                          "Value": "\"KuiiBVuRIrabYEPN2ARfzw3vgjVRkb7T3oQB6U6/DeI=\""
                      }
                  ],
                  "Type": "TXT",
                  "Name": "_amazonses.example.tk.",
                  "TTL": 300
              }
          ]
      }
```

2.4. SESドメイン認証の完了確認
-----------------

３分ぐらい待ってから実行してください。

```bash:コマンド:
aws ses get-identity-verification-attributes --identities ${DOMAINNAME}
```
```text:結果(例):
      {
          "VerificationAttributes": {
              "example.tk": {
                  "VerificationToken": "KuiiBVuRIrabYEPN2ARfzw3vgjVRkb7T3oQB6U6/DeI=",
                  "VerificationStatus": "Success"
              }
          }
      }
```

最後の行にSeccessとあれば成功です。
だめだと時間待ちです。ビールでも飲んでしばらく待ってから再度実行しましょう。
（これはDNSレコードへの登録確認はSESへverify-domain-identityコマンドを実行した直後はかなりの頻度で、時間が経つにつれ間隔が長くなっていくためです。のんびり作業しているとしばらく待つ事になるのです）