🫣

[CloudFront] カスタムSSL証明書のみを手動設定すると?

に公開

最初に

AWS CloudFrontを使って独自ドメインを運用する際、カスタムSSL証明書(ACM)を設定するケースがあると思います。この設定をAWSマネジメントコンソール上で手動で行っている場合、CDK(Cloud Development Kit)を使ってCloudFrontディストリビューションの構成を変更すると思わぬトラブルが発生します。

この記事では、そのリスクと注意点を書き留めておきます。

では始めます。

前提

  • CloudFrontのディストリビューションをCDKで定義
  • カスタムSSL証明書の設定はコンソールから手動で実施(CDKコード上には記述しない)
    • 今回はここが問題です。
  • 後日、CDKでlogBucketcacheBehaviorなどの別の設定だけを変更して再デプロイ

何が起きる?

CDKでは、cloudfront.Distributionを使ってディストリビューション全体の構成を定義します。再デプロイを行うと、CDKは「現状の設定」と「コード上の設定」を比較し、差分があればCloudFrontのリソースを再生成または更新します。

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront.Distribution.html

ここで問題になるのが..

CDKが認識していない(コード上に存在しない)手動設定は、再デプロイで上書き・削除される

という点です。

どのようなリスクが生じる?

おおよそは以下です。

  • カスタムSSL証明書が解除される
    • CDK上でDistribution.certificate(証明書の指定)とDistribution.domainNames(代替ドメインを設定する場合)を省略したまま再デプロイすると、CloudFront側では「この証明書設定は不要」と解釈されます。
      結果、せっかく手動で設定したSSL証明書が消えてしまうのです。
  • HTTPS通信ができなくなる
    • SSL証明書が外れると、HTTPS接続ができなくなり、CloudFrontはエラーを返すようになります。
      ユーザーはサイトにアクセスできなくなり、本番障害になる危険性があります。
  • CDKから変更するたびに証明書が消える
    • 仮に証明書を再設定しても、CDKで別の変更を加えて再デプロイすれば、また消えるという悪循環に陥ります。(もちろん、その都度システムは一時的に停止せざる終えなくなります)

解決法

「CDKで証明書を管理する」が正になるでしょう。
理由はCDKデプロイのたびに証明書の設定も行われるためです。

具体的には場合によりけりですが、ACMがすでに存在している場合は、arnで指定してimportしてあげれば良いです。

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_certificatemanager-readme.html#importing

そうするとCDKの定義は以下のような感じとなると思います。

const existCertificate = acm.Certificate.fromCertificateArn(this, 'ExistCert', 'arn:aws:acm:us-east-1:123456789012:certificate/xxxx-xxxx');

const distribution = new Distribution(
      this,
      "EXAMPLE" + stageSuffix,
      {
        webAclId: webACL.attrArn,
        comment: "example-distribution",
        certificate: existCertificate
        domainName: [任意のドメイン名]
        defaultBehavior: {
          origin: new HttpOrigin(cdk.Fn.parseDomainName(appURL)),
          allowedMethods: AllowedMethods.ALLOW_ALL,
          cachePolicy: CachePolicy.CACHING_DISABLED,
          originRequestPolicy:
            OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER,
        logBucket,
        logFilePrefix: "cloudfront-logs/example/",
      }
    );

まとめ

CDKによるインフラ構築は非常に強力ですが、その分状態の整合性に注意が必要です。CloudFrontのような構成の大きなリソースでは、手動設定を加えると不整合が起きやすくなります。
証明書を含む全ての設定をコードで管理することで、安全・安心な運用を実現でき、より変更に強くかつ柔軟に対応できるCDK本来の力が発揮できると感じました。

今回の記事が誰かのお役に立てれば幸いです。

NCDCエンジニアブログ

Discussion