ACM証明書の有効期限切れが近づいてきたイベントをEventBridge+SNSで通知してみた

2023.09.20

みなさんこんにちは、杉金です。
ACM証明書の有効期限切れが近づいてきたイベントをAmazon EventBridgeとAmazon SNSを使って通知させてみます。この方法は以下のre:Postでも紹介されている内容ですが、本記事ではCloudFormationを使ってサクっと実装してみます。

上記リンクには有効期限が切れる45日以上前の通知設定も記載されていますが、本記事ではその設定は含めていません。

通知はどのくらいの頻度で届くのか

本記事の設定を行うことで、有効期限が45日を下回ると毎日一回、有効期限が残り1日になるまでメールが届きます。

やってみた

以下のCloudFormationテンプレートを使用します。
ローカルに適当なファイル名をつけてyamlの拡張子で保存します。

使用するCloudFormationテンプレート

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  ResourcePrefix:
    Type: String
    Description: The prefix to use for all resources
    AllowedPattern: "[a-zA-Z0-9-]*"
    Default: acm-certificate-expiration
  Email:
    Type: String
    Description: The email address to send notifications to

Resources:
  SnsTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: !Ref ResourcePrefix
      FifoTopic: false
      Subscription:
        - Endpoint: !Ref Email
          Protocol: email
      TopicName: !Ref ResourcePrefix
  EventTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "events.amazonaws.com"
            Action: "sns:Publish"
            Resource: "*"
      Topics:
        - !Ref SnsTopic
  EventBridge:
    Type: AWS::Events::Rule
    Properties:
      Description: !Sub "${ResourcePrefix}-event-bridge-rule"
      Name: !Sub "${ResourcePrefix}-event-bridge-rule"
      EventPattern:
        source:
          - aws.acm
        detail-type:
          - ACM Certificate Approaching Expiration
      State: ENABLED
      Targets:
        - Arn: !Ref SnsTopic
          Id: !Sub "${ResourcePrefix}-sns-topic"
          InputTransformer:
            InputPathsMap:
              CommonName: $.detail.CommonName
              DaysToExpiry: $.detail.DaysToExpiry
              Region: $.region
              Resource: $.resources
              Time: $.time
            InputTemplate: |-
              "ACM証明書の有効期限が近づいてきました。"

              "リージョン:<Region>"
              "有効期限:<Time>"
              "コモンネーム:<CommonName>"
              "残り日数:<DaysToExpiry>"
              "リソースARN:<Resource>"

CloudFormationスタックの作成

AWSマネジメントコンソールのCloudFormationスタックから「スタック作成」を選びます。

テンプレートのアップロードを選び、ローカルに作成したyamlファイルを選択して次に進みます。

パラメータを決めます。

  • スタック名 : 適当な名前で構いません。acm-certificate-expirationとしました。
  • Email : 期限切れが近づいてきたときのメール通知先です。ひとつだけ入力でき、複数メールアドレスには対応していません。通知先はメーリングリストが望ましいですね。
  • ResourcePrefix : CloudFormationスタックによって作成されるAWSリソース名に付与される接頭語です。デフォルトで値が入力されていますが、お好みで変更ください。

先へと進みスタック作成を実行します。その後、スタックのステータスを確認して問題なく作成完了したことを確認します。

通知先メールアドレス宛にサブスクリプション依頼のメールが届きますので承認します。

リンクをクリックすると次の画面に遷移します。配信解除となってしまうため、unsubscribeのリンクはクリックしないようご注意ください。

動作確認

設定後、有効期限が近づくと(45日前)、以下のようにメールが届きます。 EventBridgeの入力トランスフォーマーを使って通知内容を整形しています。

以上が設定方法です。

(おまけ)今回の検証環境の作り方

この仕組みを試そうとしたとき、期限間際の証明書をどう用意するのか考えました。
以下のブログを参考に、期限短めのプライベート証明書を作りました。

流れとしては短期間証明書モードのプライベートCAを作り、証明書を作ってインポートした形です。

(おまけ2) EventBridgeコンソールからCloudFormationテンプレートを作成する

今回のテンプレート作りで役に立ったのが、EventBridgeからCloudFormationテンプレートを作る機能です。

入力トランスフォーマーで通知内容を整形する際、EventBridgeのサンプルイベントを使いながら出力内容を試行錯誤したのですが、これをCloudFormationテンプレートに落とし込むときにこの機能のおかげで時短になりました。

AWS User Notificationsを使って通知できないのか

通知設定は可能です。ですが、対象となる証明書の名前であったり、残り日数が通知内容に含まれていないため使いどころは難しいです。検証してみたブログは以下です。

最後に

ACM証明書の有効期限の通知を設定してみました。個人的には、まずはドメイン検証タイプを使って証明書を自動更新させることをおすすめしたいです。なんらかの理由があってドメイン検証が選択できない場合に、今回の仕組みで通知させると更新し忘れに役立ちそうです。

ついでに宣伝ですが、Software Design でAWS活用ジャーニーという記事を連載しています。2023年10月号ではSecurity Hubを紹介しています。他にも魅力的な記事が盛りだくさんですので、もしよかったらお手にとってご覧ください。

参考資料