エラー備忘録：CloudFrontのHTTPS化で遭遇した「InvalidViewerCertificate」の原因と対策

## はじめに  
CloudFront を利用してサイトを HTTPS 化しようとした際に `InvalidViewerCertificate` のエラーが発生しました。

:::note warn
**このエラーは CloudFront に設定した SSL 証明書に問題がある場合に起こります。**
:::

本記事では、エラーの原因を特定し、解決するための手順を詳しく解説します。  

## 書こうと思ったきっかけ  
CloudFront の設定を Terraform で管理している際に `InvalidViewerCertificate` のエラーに遭遇し、原因調査と修正に時間がかかりました。

同様の問題に直面する人が少なくないと考え、エラーの具体的な原因と解決策を整理してまとめておくことで、今後のトラブルシューティングをスムーズにできるようにしたいと思いました。  

## エラー：InvalidViewerCertificate

CloudFront の SSL 証明書 (`viewer_certificate`) の設定に問題があると、以下のエラーメッセージが発生することがあります。

```
Error: creating CloudFront Distribution: operation error CloudFront: CreateDistributionWithTags, 
InvalidViewerCertificate: The specified SSL certificate doesn't exist, 
isn't in us-east-1 region, isn't valid, or doesn't include a valid certificate chain.
```

## 原因
- CloudFront で使用する SSL 証明書が `us-east-1` に存在しない
- 証明書が無効 (`invalid`)、期限切れ (`expired`)、または適切な証明書チェーンが含まれていない (`certificate chain`)
- CloudFront に関連付けられている ACM 証明書の ARN が間違っている

## 解決策

### SSL 証明書が `us-east-1` にあるか確認
CloudFront で使用できる ACM (AWS Certificate Manager) の証明書は `us-east-1` のリージョンにある必要があります。

#### AWS CLI で確認
```sh
aws acm list-certificates --region us-east-1
```

期待する出力 (証明書が存在する場合)
```json
{
    "CertificateSummaryList": [
        {
            "CertificateArn": "arn:aws:acm:us-east-1:xxx",
            "DomainName": "honda333.blog"
        }
    ]
}
```
- 証明書 (`CertificateArn`) が `us-east-1` にあることを確認する
- `DomainName` が `honda333.blog` と一致しているか確認する

#### もし `us-east-1` に証明書がない場合
新しい証明書を作成して適用する必要があります。

```sh
aws acm request-certificate \
    --domain-name "honda333.blog" \
    --validation-method DNS \
    --region us-east-1
```
この後、Route 53 で CNAME レコードを追加し、証明書を検証する

### Terraform の `main.tf` の修正
Terraform の `aws_cloudfront_distribution` リソースで、正しい ACM 証明書の ARN (`us-east-1`) を設定する必要があります。

#### 修正前 (エラーが出る可能性が高い)
```hcl
resource "aws_cloudfront_distribution" "my_distribution" {
  viewer_certificate {
    acm_certificate_arn = "arn:aws:acm:ap-northeast-1:xxx"
    ssl_support_method = "sni-only"
  }
}
```
エラーの原因
- ACM 証明書が `ap-northeast-1 (東京)` にあるため、CloudFront で使用できない
- CloudFront で使用する証明書は `us-east-1` でなければならない

#### 修正後 (`us-east-1` の証明書を指定)
```hcl
resource "aws_cloudfront_distribution" "my_distribution" {
  viewer_certificate {
    acm_certificate_arn = "arn:aws:acm:us-east-1:xxx"
    ssl_support_method = "sni-only"
  }
}
```

### Terraform の再適用
修正後、Terraform の設定を適用します。

```sh
terraform apply
```

#### もし `InvalidViewerCertificate` のエラーが続く場合
`terraform state rm` で古い証明書を削除して再適用。

```sh
terraform state rm aws_cloudfront_distribution.my_distribution
terraform apply
```

### CloudFront で正しい証明書が設定されたか確認
Terraform の適用後、CloudFront に反映されているか確認します。

#### AWS CLI で確認
```sh
aws cloudfront get-distribution --id xxx
```

期待する出力
```json
{
    "Distribution": {
        "ViewerCertificate": {
            "ACMCertificateArn": "arn:aws:acm:us-east-1:xxx",
            "SSLSupportMethod": "sni-only"
        }
    }
}
```
`ACMCertificateArn` が `us-east-1` のものになっていれば成功

## まとめ

| 問題 | 解決策 |
|----------|----------|
| `InvalidViewerCertificate` のエラー | CloudFront の証明書が `us-east-1` にない |
| ACM 証明書が `ap-northeast-1` にある | `us-east-1` で新しい証明書を発行して使用 |
| Terraform の `aws_cloudfront_distribution` でエラー | `acm_certificate_arn` を `us-east-1` のものに修正 |
| Terraform の再適用時にエラーが発生 | `terraform state rm` でリソースを削除して再適用 |

この手順で `InvalidViewerCertificate` は解決するはずです。
1. ACM 証明書が `us-east-1` にあるか確認 (`aws acm list-certificates --region us-east-1`)
2. Terraform の `acm_certificate_arn` を修正 (`us-east-1` のものを指定)
3. Terraform を再適用 (`terraform apply`)
4. CloudFront に正しく証明書が設定されたか確認 (`aws cloudfront get-distribution`)