😸

【CloudFormation】DataSyncのタスク実行結果を通知してみた(EventBridge,KMS,SNS)

2022/08/29に公開

1. はじめに

 こんにちわ、Mitsuoです。
今回はDataSyncのタスク実行結果を通知するテンプレートを作成してみました。
DataSyncはリソースの状態によって様々なイベント情報を使用することが出来ます。
それによって、タスク実行時のステータスもEventBridgeでドリブンすることが可能です。
このイベント情報を用いてSNS経由でe-mailに通知するリソースを実装します。

コンソール上での設定方法になりますが、詳細を知りたい方は、以下のドキュメントを参考ください。

How can I be notified when a DataSync task execution succeeds or fails?

また、DataSyncのイベント情報は以下のドキュメントを参考ください。

CloudWatch events for DataSync


2. 作成するリソース

 テンプレートで作成するリソースは以下の通りです。

  • EventBridge ルール × 1
  • KMS(Customer Managed Keyキー) × 1
  • SNS(Simple Notification Service)
    • トピック × 1
    • ポリシー × 1
    • サブスクリプション × 1

image

上記の構成では、SNSの暗号化方式に「デフォルト」を使うことが出来ないので、CMKを作成しています。

また、動作確認を行うため、以下のリソースを事前に作成済みです。

  • VPCなどのネットワークサービス
  • DataSync関連リソース(ロケーションで使うリソース含む)

DataSyncリソースのテンプレートは別の記事で紹介していますので、そちらを参考ください。

【CloudFormation】DataSyncリソースをデプロイしてみた

3 テンプレート情報

 作成したテンプレートになります。

AWSTemplateFormatVersion: "2010-09-09"
Description: Deploy an EventBridge Rule and SNS Topic.
# ------------------------------------------------------------#
#  Caution:
#  This template is for deploying resources in Tokyo region(ap-northeast-1).
# ------------------------------------------------------------#
#  Metadata:
#  This can privide details about the template.
#  For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
#  As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
#  when they are displayed in the AWS CloudFormation console.
#  For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#

Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Parameters:
          - SystemName
          - EnvType
          - Tagprefix
          - Owner
          - NotifyEmailAddress

    ParameterLabels:
      SystemName:
        default: "Systemname: Type the Systemname"
      EnvType:
        default: "EnvType: Select the environment to which you want to deploy resources"
      Tagprefix:
        default: "Tagprefix: Type the Optinal logicatl name(e.g. Webserver,Monitoring,Logging)"
      Owner:
        default: "Owner: Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
      NotifyEmailAddress:
        default: "NotifyEmailAddress: Type e-mail for Target "

# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#

Parameters:
  SystemName:
    Type: String
  EnvType:
    Type: String
    Default: "dev"
    AllowedValues:
      - dev
      - stg
      - prd
  Tagprefix:
    Type: String
  Owner:
    Type: String
  NotifyEmailAddress:
    Type: String

Resources:

  # ------------------------------------------------------------#
  # Create KMS for SNS (Customer Managed Key)
  # ------------------------------------------------------------#

  KmsKey:
    Type: "AWS::KMS::Key"
    Properties:
      Description: "The customer managed key for event notifications outside"
      Enabled: true
      EnableKeyRotation: true
      KeyPolicy:
        Version: "2012-10-17"
        Statement:
          - Sid: "Allow administration of the key"
            Effect: "Allow"
            Principal:
              AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
            Action:
              - "kms:Create*"
              - "kms:Describe*"
              - "kms:Enable*"
              - "kms:List*"
              - "kms:Put*"
              - "kms:Update*"
              - "kms:Revoke*"
              - "kms:Disable*"
              - "kms:Get*"
              - "kms:Delete*"
              - "kms:ScheduleKeyDeletion"
              - "kms:CancelKeyDeletion"
            Resource: "*"
          - Sid: "Enable EventBridge to permit certain KMS actions"
            Effect: "Allow"
            Principal:
              Service: "events.amazonaws.com"
            Action:
              - "kms:Decrypt"
              - "kms:GenerateDataKey"
            Resource: "*"
      KeySpec: "SYMMETRIC_DEFAULT"
      KeyUsage: "ENCRYPT_DECRYPT"
      MultiRegion: false
      PendingWindowInDays: 30
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-CMK-For-SNS
        - Key: Owner
          Value: !Ref Owner

  KmsAlias:
    Type: "AWS::KMS::Alias"
    Properties:
      AliasName: !Sub alias/${SystemName}-${EnvType}-${Tagprefix}-CMK-Alias-For-SNS
      TargetKeyId: !Ref KmsKey

  # ------------------------------------------------------------#
  # Create Simple Notification Sevices(SNS)
  # ------------------------------------------------------------#

  EventTypeNotifyTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SNS-Topic-From-TaskEvents
      TopicName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SNS-Topic-From-TaskEvents
      KmsMasterKeyId: !GetAtt KmsKey.KeyId
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SNS-Topic-From-TaskEvents
        - Key: Owner
          Value: !Ref Owner

  EventTypeNotifyTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "events.amazonaws.com"
            Action: "sns:Publish"
            Resource: !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${SystemName}-${EnvType}-${Tagprefix}-SNS-Topic-From-TaskEvents
      Topics:
        - !Ref EventTypeNotifyTopic

  Subscription:
    Type: AWS::SNS::Subscription
    Properties:
      Endpoint: !Ref NotifyEmailAddress
      Protocol: email
      TopicArn: !Ref EventTypeNotifyTopic

  # ------------------------------------------------------------#
  # Create EventBridgeRule
  # ------------------------------------------------------------#

  DataSyncEventBridgeRule:
    Type: "AWS::Events::Rule"
    Properties:
      Name: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EventBridge-Rule-DataSync-TaskEvent
      Description: "Events Rule triggered by DataSync Task Events"
      EventBusName: "default"
      EventPattern:
        source:
          - aws.datasync
        detail-type:
          - DataSync Task Execution State Change
        detail:
          State:
            - "SUCCESS"
            - "ERROR"
            - "LAUNCHING"
      Targets:
        - Arn:
            Ref: EventTypeNotifyTopic
          Id: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EventBridge-Rule-DataSync-TaskEvent

# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#

Outputs:
  EventTypeNotifyTopic:
    Description: EventTypeNotifyTopic
    Value: !Ref EventTypeNotifyTopic

  EventTypeNotifyTopicPolicy:
    Description: EventTypeNotifyTopicPolicy
    Value: !Ref EventTypeNotifyTopicPolicy

  Subscription:
    Description: Subscription
    Value: !Ref Subscription

  DataSyncEventBridgeRule:
    Description: DataSyncEventBridgeRule
    Value: !Ref DataSyncEventBridgeRule

  KmsKey:
    Description: KmsKey
    Value: !Ref KmsKey

4 補足情報

テンプレートに関して、以下の通り補足します。

4.1 Metadata/Parameters

 メタデータおよびパラメターセクションで、以下の値を定義します。

項目 備考
SystemName プロジェクト名や利用目的等を入力する
EnvType デプロイする環境を選択する
検証、ステージング、本番の3点
Tagprefix 任意で入力するPrefix値
Owner 作業者、所有者、コスト管理用に入力する
NotifyEmailAddress 通知先のメールアドレスを入力

4.2 ユースケース

 今回のテンプレートは、次の様なユースケースを想定して作成しました。

  • DataSyncのタスク実行時のステータスを確認したい
  • 開始、終了時に通知する事で、問題無くタスクが完了していること、コンソールにアクセスせずにおおよその処理時間を確認したい
  • エラー発生時も通知するようにしたい
  • 監視体制があまり整備されていないので、とりあえずメール通知だけでも実装しておきたい
  • SNSの暗号化を無効化したくない

4.3 各リソースのプロパティについて

参考として記載しますが、各属性の詳細は公式ドキュメントを参照ください。

Type: AWS::KMS::Key
KMS_Syntax

Type: AWS::KMS::Key
Properties: 
  Description: String
  Enabled: Boolean
  EnableKeyRotation: Boolean
  KeyPolicy: Json
  KeySpec: String
  KeyUsage: String
  MultiRegion: Boolean
  PendingWindowInDays: Integer
  Tags: 
    - Tag

AWS::KMS::Alias
KMS_Alias_Syntax

Type: AWS::KMS::Alias
Properties: 
  AliasName: String
  TargetKeyId: String

AWS::SNS::Topic
SNS_Topic_Syntax

Type: AWS::SNS::Topic
Properties: 
  ContentBasedDeduplication: Boolean
  DisplayName: String
  FifoTopic: Boolean
  KmsMasterKeyId: String
  Subscription: 
    - Subscription
  Tags: 
    - Tag
  TopicName: String

AWS::SNS::Subscription
SNS_Subscription_Syntax

Type: AWS::SNS::Subscription
Properties: 
  DeliveryPolicy: Json
  Endpoint: String
  FilterPolicy: Json
  Protocol: String
  RawMessageDelivery: Boolean
  RedrivePolicy: Json
  Region: String
  SubscriptionRoleArn: String
  TopicArn: String

AWS::SNS::TopicPolicy
SNS_TopicPolicy_Syntax

Type: AWS::SNS::TopicPolicy
Properties: 
  PolicyDocument: Json
  Topics: 
    - String

AWS::Events::Rule
EventBridge_Rule_Syntax

Type: AWS::Events::Rule
Properties: 
  Description: String
  EventBusName: String
  EventPattern: Json
  Name: String
  RoleArn: String
  ScheduleExpression: String
  State: String
  Targets: 
    - Target

5. 動作確認

 では、実際に動作を確認してみます。

5.1 スタック作成

 上述したテンプレートを基にスタックを作成します。

項目 備考
SystemName mitsuopj
EnvType dev
Tagprefix notification
Owner mitsuo
NotifyEmailAddress XXXXX(個人のメールアドレス)

image

テンプレート作成後は受信したメールからサブスクライブ設定を行います。

メールのリンク「Confirm subscription」をクリックします。

image

クリックすると、サブスクライブされます。

image

5.2 DataSyncの実行

 DataSyncタスクのソースであるS3バケットに転送するファイルを格納し手動でタスクを実行します。

image

タスクを実行すると、ステータスがLaunchingに遷移します。

image

イベントがメールアドレス宛に通知されることを確認します。

image

タスクが完了すると、ステータスがSuccessに遷移します。

image

イベントがメールアドレス宛に通知されることを確認します。

image

検証おわり!!

6. まとめ

 DataSyncがCloudWatch Logsに格納するタスクログはスキャン、転送するデータの履歴が主になります。
メトリクスフィルターで設定するよりも、AWS側で管理するイベント情報を用いる方がお手軽なので、是非ともご利用ください。

このブログが誰かの役に立てば嬉しいです。
最近ますます子供が可愛くて仕方がない、Mitsuoでした!

7. 参考資料

How can I be notified when a DataSync task execution succeeds or fails?
CloudWatch events for DataSync
【CloudFormation】DataSyncリソースをデプロイしてみた

テンプレートのSyntax

KMS_Syntax
KMS_Alias_Syntax
SNS_Topic_Syntax
SNS_TopicPolicy_Syntax

Discussion