AWS Certificate Manager(ACM)による証明書の自動更新について勘違いしていたのでまとめ

# はじめに

* パブリック証明書のお話です
* AWSコンソールからの操作を前提としています
* なるべく簡潔に書いてます

# ACMあるある?

**こんな人いませんか？**

* Eメール検証で証明書をリクエストしていたため、更新メールの見落としていた！二ヶ月も前に受信していたのに！
* DNS検証にしておけば自動更新が簡単だったのに！今更移行しようと思ってもサービス動いているし大変そう


# それは勘違いかもしれない

ACM、意外と勘違いしていました。かくいう私が知らなかったことが多かったのでまとめてみます。

## 勘違い１： Eメール検証は自動更新できない

**結論、自動更新できます。**
「え？でも毎回、証明書更新してねメールが来るんだけど？」な人がいそうです。
自動更新には条件があります。そちらを見てみましょう。

### **【Eメール検証の証明書が自動更新されるための条件】**

|証明書のドメイン名|自動更新するために必要なドメイン名|条件1|条件2|
| --- | --- | --- | --- |
| example.com | example.com<br>www.example.com |左記のドメインにHTTPSでアクセスできる|アクセスしたドメインに左記の証明書が適用されている|
| *.example.com | example.com<br>www.example.com|〃|〃|

ACMはHTTPS接続の確立後、証明書とACMが更新すべき証明書が一致するかを確認します。
そのため、`HTTPSでアクセスできる＆更新対象の証明書が適用されている`必要があります。

**ちなみに、証明書のドメイン名がワイルドカードであってもそうでなくても、自動更新に必要なドメインは`www.example.com`か`example.com`です。**

### Eメール検証の証明書が自動更新できなかったときのチェックポイント

* HTTPSアクセスできるサイトがあるのか
* そのサイトには更新したい証明書が適用されているのか

**【よくあるミス】**

|原因| 例|
| --- | --- |
| example.comかwww.example.comのサイトがない | 「subdomain.example.comしかなかった」など |
| サイトに適用している証明書が違う | 「*.example.comの証明書を更新したいのに、適用されているのはexample.comの証明書だった」など |

ある意味、毎回証明書更新のメールが来る人は自動更新の条件をクリアできず**失敗**していることになりますね。

## 勘違い２：ダウンタイムなしでDNS検証に切り替えるのは大変そう

**結論、証明書の変更はサービスに影響しません。**
Eメール検証で自動更新に手間取るくらいならDNS検証に切り替えたいところです。

### 前提1：そもそも最初からDNS検証にできるならそのほうが良い

ACMで証明書をリクエストするときの方法は2種類あります。

* Eメール検証
* DNS検証

![スクリーンショット 2018-06-28 22.25.39.png](https://qiita-image-store.s3.amazonaws.com/0/157454/3fbc5057-760d-73ec-c0a3-97cd98d3e478.png)

さきほどの話は、Eメール検証時のお話です。
Eメール検証では、さきほどご覧になったとおり、自動更新するための条件がやや面倒です。

となると、DNSによる検証のほうが圧倒的に楽です。
これは公式にも書いてあります。

> DNS 検証は、E メール検証よりも多数のメリットがあります
[DNS を使用したドメインの所有権の検証 - AWS Certificate Manager](https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/gs-acm-validate-dns.html)

つまり、最初に証明書をリクエストするときは、DNS検証にしておくのがおすすめということです。
**Route53を利用している場合は、ワンクリックで自動的に「レコードを登録からDNS検証」までを終わらせてくれます。**
気づいたら証明書が利用可能になっているので、地味に便利です。Eメール検証でポチポチするような作業はありません。

### 前提2： 証明書を切り替えたとしてもサービスに影響はない

さらに、置き換えて大丈夫なのか？という話も先にしておきます。
結論から言うと、影響はないのですが、簡潔に見ていきましょう。

* [SSL/TLS 証明書の更新 - Amazon CloudFront](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-rotate-certificates.html)

> ビューワーは、プロセスが完了した後だけでなく、証明書を更新している間もコンテンツにアクセスし続けることができます。


* [サーバー証明書の更新 - Elastic Load Balancing](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-update-certificates.html)

> 証明書を更新または置き換えしても、ロードバランサーノードが受信し、正常なターゲットへのルーティングを保留中の未処理のリクエストには影響しません。証明書更新後、新しいリクエストは更新された証明書を使用します。証明書置き換え後、新しいリクエストは新しい証明書を使用します。

### 線路切り替えのイメージ


![image.png](https://qiita-image-store.s3.amazonaws.com/0/157454/194114d3-0dfb-aa08-16de-7a88c4804bed.png)

LBもCloudfrontも、旧証明書へのリクエストが終わるまではたとえ更新中であってもその証明書を使うようにできています。
証明書が置き換えられたあとのリクエストは、新しい証明書に向かいます。

![スクリーンショット 2018-07-04 16.20.26.png](https://qiita-image-store.s3.amazonaws.com/0/157454/b0d14cae-0f2e-d2aa-b8cb-384a06dd403c.png)

よって、インサービスの状態でも証明書を切り替えることができます。

## 本題：DNS検証に切り替える

さて今回の問題はEメール検証で運用ミスがでると困るからDNS検証にしたいという話でした。
すでに動いているサービスに証明書が適用されています。
**しかもEメール検証で発行した証明書を、そのままDNS検証に切り替えることはできないという問題があります。**

なので、大まかに以下の方法で切り替えます。

**1. DNS検証で新しい証明書をリクエストする
2. Cloudfront、LBに適用されている証明書を置き換える
3. 切り替わっていることを確認してから削除する**



## 1. DNS検証で新しい証明書をリクエストする

同名でもDNS検証用の証明書リクエストは可能なのでご安心ください。

1 新たに証明書をリクエストする**(cloudfrontで証明書を使用する場合はバージニアで取得することを忘れずに)**

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.amazonaws.com/0/157454/71c97c91-8b3f-d31e-16ba-a276f740d8e4.png)

 * `*.example.com`で取得して、`example.com`も使用したい場合は`追加の名前`に`example.com`を追加します
 
![AWS_Certificate_Manager2.png](https://qiita-image-store.s3.amazonaws.com/0/157454/ee682184-79a4-1d84-efb6-1fe52d94d7e7.png)

* DNS検証を選択します

![スクリーンショット 2018-07-04 15.01.45.png](https://qiita-image-store.s3.amazonaws.com/0/157454/df105c50-8fc1-e244-90e0-286a9d58b69d.png)

![スクリーンショット 2018-07-04 15.03.50.png](https://qiita-image-store.s3.amazonaws.com/0/157454/1d69a1e7-146e-d4cf-0458-b9044d57fda9.png)

2　「確認とリクエスト」→ 「続行」をクリックしてACMのページへ

* リクエストした証明書のプルダウンを押すと、 「Route 53 でのレコードの作成」があるのでクリック。さらに「作成」を押します

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.amazonaws.com/0/157454/bb1790cc-bc52-3bfc-10d2-048d6ad4311a.png)

* ※ Route53以外でドメイン管理している場合は、「名前」と「値」をCNAMEとしてドメイン管理先に登録します
* 時間がかるので待つ

これで証明書の再リクエストは完了です。

## 2. Cloudfront、LBに適用されている証明書を置き換える

1 Cloudfront、LBに適用されている証明書を変更する

### 【LBの証明書変更】

* 「ロードバランサー」ページにて対象のLBを選択します
* 「リスナー」のタグを選択します

![EC2_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/157454/1f50feba-3949-3551-9e8c-55b3072bcec7.png)

* 「編集」にチェックを入れ、「編集」を押します

![EC2_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/157454/78f19fac-391a-517f-5a3f-0a26a6a9f143.png)

* 「デフォルトのSSL証明書」のプルダウンから新しい証明書を選択し、ページ上部の「更新」をクリックする

![EC2_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/157454/6989a6a4-2038-6fe9-2c29-4655c9f66ec6.png)

これで完了です。

### 【Cloudfrontの証明書変更】

* 「Cloudfront」のページにて対象のディストリビューションを選択
* 「Edit」をクリックする

![AWS_CloudFront_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/157454/30b8fe95-1086-53ee-78d0-3ec44aa37863.png)

* 「State」が「Enabled」になるまで待つ（あるいは他のディストリビューションを変更していく）

## 切り替わっていることを確認する

証明書がすべて変更されたかは、ACMのページから確認できそうです。
ACMのページにて、対象の証明書をプルダウンすると詳細が見れます。

「関連リソース」という項目がなくなっていれば問題ないでしょう。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.amazonaws.com/0/157454/17f9a001-82dd-5aa8-cdd3-92e518dd27bc.png)

### 完全に更新されるまでは旧証明書は**削除しない**


**完全に切り替わったことを確認するまでは旧証明書は削除してはいけません！**

## 3. 切り替わっていることを確認してから削除する

* ACMのページにて対象の証明書を削除します
* 右上の「アクション」をクリックし、「削除」を選択します

これで完了です。

# おわりに

「証明書の自動更新がされず、サービスダウンさせた」なんてことにならないようにしましょう。
DNS検証のほうが圧倒的に便利なので、これからリクエストする人はぜひそちらを選択してみてください。

※ 間違いなどありましたらご指摘ください。

# 関連リンク

* [SSL/TLS 証明書の更新 - Amazon CloudFront](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-rotate-certificates.html)
* [サーバー証明書の更新 - Elastic Load Balancing](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/listener-update-certificates.html)
* [DNS を使用したドメインの所有権の検証 - AWS Certificate Manager](https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/gs-acm-validate-dns.html)