😸

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

2022/08/07に公開

1. はじめに

 こんにちわ、Mitsuoです。
今回はCloudFormationを用いてAWS DataSyncの機能をデプロイしてみました。
AWS DataSyncとは、AWSマネージドのデータ転送サービスでストレージ間で大量のデータをコピー、同期をする事が出来ます。
様々なストレージに対応しており、例を挙げるとNFS、SMBのファイルサーバーやS3、EFSからデータの転送処理が可能です。

DataSyncは以下のリソースで構成されており、タスクを実行することで転送が出来ます。

項目 備考
ロケーション データの送信元(Source)、データの送信先(Destination)
タスク` データ転送を行うリソースの実体
タスク内でロケーションやその他設定値を指定する

この記事ではDataSyncの概要に関しては解説がないため、公式ドキュメントや他の技術ブログを参照してください。
特に、ロケーション指定出来る組み合わせやデータ種類は設計前に確認いただくのが良いと思います。

<参考>
What is AWS DataSync?
DataSyncタスクを作成してみた

2. 作成したリソース

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

  • 送信元ロケーション
    • S3
    • IAM Role,InstanceProfile,ManagedPolicy
  • 送信先ロケーション
    • EFS(MountTarget含む)
    • EFS用セキュリティグループ
  • DataSyncタスク

構成図からはマウントターゲットやIAM、ネットワークリソースを省略しています。
なお、このテンプレートではVPCネットワークを作成しないので、デプロイする場合に、別途準備する必要があります。

image

3 テンプレート情報

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


AWSTemplateFormatVersion: 2010-09-09
Description: Deploy Datasync resources such as locations and a task.
# ------------------------------------------------------------#
#  Caution:
#  This template is for deploying resources in Tokyo region(ap-northeast-1).
#  If you deploy them in another region, make sure that you understand below content and make modification for parameters properly.
# ------------------------------------------------------------#
#  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
          - VPCID
          - VPCCIDR          
          - PrivateSubnet1
          - PrivateSubnet2
          - S3BucketName1
          - SourceS3BucketPath
          - DestinationEFSPath

    ParameterLabels:
      SystemName:
        default: "Type the Systemname"
      EnvType:
        default: "Select the environment in which you deploy resources"
      Tagprefix:
        default: "Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
      Owner:
        default: "Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
      VPCID:
        default: "Select the VPC ID"
      VPCCIDR:
        default: "This is for deciding Security Group Ingress CIDR for instance in VPC. Type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918."
      PrivateSubnet1CIDR: 
        default: "Please type your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
      PrivateSubnet2CIDR: 
        default: "Please type your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"            
      S3BucketName1:
        default: "Type the name you want to include to bucketName"                        
      SourceS3BucketPath:
        default: "Type a subdirectory in the Amazon S3 bucket that is used to read data from the S3 source location"
      DestinationEFSPath:
        default: "Type a subdirectory in the EFS file system that is used to send data to destination location"   

# ------------------------------------------------------------#
# 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
      - prod
  Tagprefix:
    Type: String
  Owner:
    Type: String
  VPCID:
    Type: AWS::EC2::VPC::Id
    ConstraintDescription: "Select the VPC ID"
  VPCCIDR:
    Type: String
    Default: "10.0.0.0/16"
    ConstraintDescription: "This is for deciding Security Group Ingress CIDR for instance in VPC. So please type VPC's CIDR such as NN.NN.NN.NN/NN based on RFC 1918."
  PrivateSubnet1:
    Type: AWS::EC2::Subnet::Id
    ConstraintDescription: "Select your subnet's CIDR in AZ-A such as NN.NN.NN.NN/NN based on RFC 1918"
  PrivateSubnet2:
    Type: AWS::EC2::Subnet::Id
    ConstraintDescription: "Select your subnet's CIDR in AZ-C such as NN.NN.NN.NN/NN based on RFC 1918"   
  S3BucketName1:
    Type: String
    ConstraintDescription: "Type the name you want to include to bucketName"       
  SourceS3BucketPath:
    Type: String
    Default: /
    ConstraintDescription: "Type a subdirectory in the Amazon S3 bucket that is used to read data from the S3 source location"    
  DestinationEFSPath:
    Type: String
    Default: /
    ConstraintDescription: Type a subdirectory in the EFS file system that is used to send data to destination location

# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#

Resources:

# ------------------------------------------------------------#
# DataSync resources
# S3,IAM,EFS(SG,MountTarget),Locations,Task
# ------------------------------------------------------------#

# ------------------------------------------------------------#
# Create S3 Bucket for DataSync source location.
# ------------------------------------------------------------#

  S3Bucket1:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}
      PublicAccessBlockConfiguration: 
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      VersioningConfiguration:
        Status: Suspended          
      BucketEncryption:
        ServerSideEncryptionConfiguration: 
          - ServerSideEncryptionByDefault: 
              SSEAlgorithm: AES256                  
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerEnforced
      NotificationConfiguration:
        EventBridgeConfiguration:
          EventBridgeEnabled: false           
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}   
        - Key: Owner
          Value: !Sub ${Owner}         

# ------------------------------------------------------------#
# Create IAM resources for DataSync Source location.
# ------------------------------------------------------------#

  IAMRoleforDataSyncSource1:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-Source-IAM-Role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Effect: "Allow"
            Principal:
              Service:
                - "datasync.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      MaxSessionDuration: 3600        
      Path: /
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-Source-IAM-Role
        - Key: Owner
          Value: !Ref Owner

  InstanceProfileforDataSyncSource1:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      InstanceProfileName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-Source-IAM-Role
      Path: /
      Roles:
        - !Ref IAMRoleforDataSyncSource1
    DependsOn: IAMRoleforDataSyncSource1

  IAMPolicyforDataSyncSource1:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      Description: Policy for IAM-Role with DataSync Source
      Path: /
      ManagedPolicyName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-Source-IAM-Policy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Sid: ReadOnly
            Action:
              - s3:GetBucketLocation
              - s3:ListBucket
              - s3:ListBucketMultipartUploads
            Resource:
              - !Sub 'arn:aws:s3:::${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}'
              - !Sub 'arn:aws:s3:::${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}/*'        
          - Effect: Allow
            Sid: WriteandReadPolicy          
            Action:
              - s3:AbortMultipartUpload
              - s3:DeleteObject
              - s3:GetObject
              - s3:ListMultipartUploadParts
              - s3:PutObjectTagging
              - s3:GetObjectTagging
              - s3:PutObject
            Resource:
              - !Sub 'arn:aws:s3:::${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}/*'   
      Roles:
        - !Ref IAMRoleforDataSyncSource1

#---------------------------------
# Create Security Group for Mount target in EFS. 
#---------------------------------

  EFSSecurityGroup1:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEFS
      GroupDescription: Security Group for Mount target in EFS 
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 2049
          ToPort: 2049
          CidrIp: !Ref VPCCIDR
      VpcId: !Ref VPCID          
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-SG-ForEFS
        - Key: Owner
          Value: !Ref Owner

#---------------------------------
# Create EFS File system 
# BypassPolicyLockoutSafetyCheck is not used because this EFS does not set up File system Policy.
# For more information about BypassPolicyLockoutSafetyCheck, see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-efs-filesystem.html#cfn-efs-filesystem-bypasspolicylockoutsafetycheck
# LifecyclePolicies is not used because this EFS does not use itself for infrequent access and basically uses EFS Standard class.
#---------------------------------

  EFSFileSystem1:
    Type: AWS::EFS::FileSystem
    Properties:
      BackupPolicy:
        Status: DISABLED
      Encrypted: true
      FileSystemTags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-EFS-FileSystem
        - Key: Owner
          Value: !Ref Owner
      PerformanceMode: generalPurpose
      ThroughputMode: bursting

#---------------------------------
# Create EFS Mount Target 
#---------------------------------

  EFSMountTarget1:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref EFSFileSystem1
      SecurityGroups:
        - !Ref EFSSecurityGroup1
      SubnetId: !Ref PrivateSubnet1
    DependsOn: 
      - EFSFileSystem1  

  EFSMountTarget2:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref EFSFileSystem1
      SecurityGroups:
        - !Ref EFSSecurityGroup1
      SubnetId: !Ref PrivateSubnet2
    DependsOn: 
      - EFSFileSystem1 

# ------------------------------------------------------------#
# Create DataSync Task LogGroup
# ------------------------------------------------------------#

  DataSyncLogGroup1:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/datasync/${SystemName}-${EnvType}-${Tagprefix}-Task"
      RetentionInDays: 30

# ------------------------------------------------------------#
# Create DataSync Location of Source Configuration
# ------------------------------------------------------------#

  DataSyncSource1:
    Type: AWS::DataSync::LocationS3
    Properties:
      S3BucketArn: !Sub arn:aws:s3:::${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}
      S3Config:
        BucketAccessRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/${SystemName}-${EnvType}-${Tagprefix}-DataSync-Source-IAM-Role
      S3StorageClass: STANDARD
      Subdirectory: !Ref SourceS3BucketPath
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-SourceS3
        - Key: Owner
          Value: !Ref Owner
    DependsOn: 
      - IAMPolicyforDataSyncSource1 
          
# ------------------------------------------------------------#
# Create DataSync Location of Destination Configuration
# ------------------------------------------------------------#

  DataSyncDestination1:
    Type: AWS::DataSync::LocationEFS
    DependsOn:
      - DataSyncSource1
      - DataSyncLogGroup1
      - EFSMountTarget1
      - EFSMountTarget2
    Properties:
      Ec2Config:
        SecurityGroupArns:
          - !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/${EFSSecurityGroup1}
        SubnetArn: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${PrivateSubnet1}
      # SubnetArn: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${PrivateSubnet2}
      EfsFilesystemArn: !Sub arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${EFSFileSystem1}
      Subdirectory: !Ref DestinationEFSPath
      InTransitEncryption: TLS1_2
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-DestinationEFS
        - Key: Owner
          Value: !Ref Owner      

# ------------------------------------------------------------#
# Create DataSync Task
# ------------------------------------------------------------#

  DataSyncTask1:
    Type: AWS::DataSync::Task
    DependsOn:
      - DataSyncSource1
      - DataSyncDestination1
      - DataSyncLogGroup1
    Properties:
      Name: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-Task
      SourceLocationArn: !GetAtt DataSyncSource1.LocationArn
      DestinationLocationArn: !GetAtt DataSyncDestination1.LocationArn
      CloudWatchLogGroupArn:  !GetAtt DataSyncLogGroup1.Arn
      Schedule:
        ScheduleExpression: "cron(0 15 * * ? *)"
      Options:
        LogLevel: "TRANSFER"
        Atime:  "BEST_EFFORT"
        Mtime:  "PRESERVE"
        ObjectTags: "NONE"
        OverwriteMode: "ALWAYS" 
        PosixPermissions: "PRESERVE"
        PreserveDeletedFiles: "REMOVE"
        PreserveDevices: "NONE"
        TaskQueueing: "DISABLED"
        TransferMode: "CHANGED"
        Uid: "INT_VALUE"
        VerifyMode: "ONLY_FILES_TRANSFERRED"
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-DataSync-Task
        - Key: Owner
          Value: !Ref Owner 

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

Outputs:

  S3Bucket1:
    Description: S3Bucket1
    Value: !Ref S3Bucket1

  EFSSecurityGroup1:
    Description: EFSSecurityGroup1 
    Value: !Ref EFSSecurityGroup1

  EFSFileSystem1:
    Description: EFSFileSystem1
    Value: !Ref EFSFileSystem1

  EFSMountTarget1:
    Description: EFSMountTarget1
    Value: !Ref EFSMountTarget1

  EFSMountTarget2:
    Description: EFSMountTarget2
    Value: !Ref EFSMountTarget2  

  DataSyncLogGroup1:
    Description: DataSyncLogGroup1
    Value: !Ref DataSyncLogGroup1
    
  DataSyncSource1:
    Description: DataSyncSource1
    Value: !Ref DataSyncSource1

  DataSyncDestination1:
    Description: DataSyncDestination1
    Value: !Ref DataSyncDestination1

  DataSyncTask1:
    Description: DataSyncTask1
    Value: !Ref DataSyncTask1


4 補足情報

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

4.1 Metadata/Parameters

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

項目 備考
SystemName プロジェクト名や利用目的等を入力する
EnvType デプロイする環境を選択する
検証、ステージング、本番の3点
Tagprefix 任意のPrefix値を入力する
Owner 作業者、所有者、コスト管理用に入力する
VPCID EFS用セキュリティグループを配置するVPCを選択する
VPCCIDR EFS用セキュリティグループを配置するVPCのCIDRを入力する
PrivateSubnet1 EFS用マウントターゲットを配置するサブネットを選択する
PrivateSubnet2 EFS用マウントターゲットを配置するサブネット値選択する
S3BucketName1 DataSyncタスクの送信元になるS3バケット名を入力する ※
SourceS3BucketPath 送信元S3バケットのディレクトリパス
転送対象のパス
DestinationEFSPath 送信先EFSのディレクトリパス
転送先のパス

※バケット名は以下の命名規則で作成しているので、バケット名に入力した値がそのままバケット名になる訳では無いのでご注意ください

!Sub ${SystemName}-${EnvType}-${Tagprefix}-${S3BucketName1}-${AWS::AccountId}

4.2 想定ユースケース

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

  • DataSyncエージェントを用いない転送設定である
  • ロケーションに転送元をS3、転送先をEFSに指定する
  • EFSのファイルシステムポリシーは利用しない
  • EFSのマウントターゲットはプライベートサブネットに配置する前提である
  • 転送元ロケーション(S3)に関する設定は以下の通り行う
    • カスタマー管理ポリシーを用いた権限設定を行う
  • 転送先ロケーション(EFS)に関する設定は以下の通り行う
    • 転送時の暗号化を有効化にする
    • EFSアクセスポイントは行わない
    • EFSファイルシステムをマウントする時に利用するIAMロールは指定しない
  • タスク実行設定は以下の通り行う
    • 転送されたデータのみを検証を行う
    • 帯域幅の制限は特に行わない
    • キューイング設定を行わない
  • データ転送設定に関する設定は以下の通り行う
    • 転送モードは「変更されたデータのみ転送する」
    • スキャン対象は全て(特定のプレフィックスの指定を行わない)
    • 転送時のフィルタリング設定は行わない
    • 転送元で削除されたファイルを転送先で保持しない
    • ファイルの上書きを許可する
  • 以下の3点の有効化しておく、直接関係しない設定の様にも推察出来る、デフォルト設定がそうなっているので、その様にしておく
    不要であれば無効化して使ってもらうでよい
    • タイムスタンプ(atime,mtime)のコピー
    • 所有権情報
    • パーミッション情報

テンプレートに関しては、公式ドキュメントを参照ください。

<参考>
AWS::DataSync::Task
AWS::DataSync::LocationS3
AWS::DataSync::LocationEFS

4.3 動作確認

 実際に動作を確認してみます。
上記のテンプレートを用いて、DataSyncの関連リソースを作成します。

スタック名:DataSync

項目 備考
SystemName mitsuo
EnvType dev
Tagprefix synchronization
Owner mitsuo
VPCID 別途作成済みのVPCID
VPCCIDR 別途作成済みのVPCCIDR
PrivateSubnet1 別途作成済みのプライベートサブネット
PrivateSubnet2 別途作成済みのプライベートサブネット
S3BucketName1 source
SourceS3BucketPath /
DestinationEFSPath /

ではスタックを作成します。

image

タスクおよびロケーション(と関連リソース)が作成された事を確認します。

image

送信元ロケーション(S3)の画面です。

image

送信先ロケーション(EFS)の画面です。

image

次にS3バケットに転送するオブジェクトをアップロードし、DataSyncタスクを実行します。

image

コンソール上ではDataSyncタスクの詳細画面の右上にある「開始」→ 「デフォルトから開始する」の準備に押下する事で、タスクの実行が出来ます。

image

image

タスクが実行中の場合は、ステータスが「実行中」に遷移します。

image

しばらく待つと、ステータスが「利用可能」になります。処理が完了した事を確認します。

image

image

ログが問題なく出力されている事が確認します。

image

4.4 留意事項

 留意事項は以下の通りです。

  • EFSロケーション1つにつき指定出来るサブネットは1つであるため、AZ障害やサブネットに問題があった時に転送処理が失敗する可能性があります。
    • 上記に加えて、作成したロケーションのサブネットを変更する事が出来ないため、サブネット毎にタスクを作成してスケジュールで制御する必要がありそうです。(他にいい方法があればむしろ教えて欲しい)
  • タスクリソースにおける所有権は、タスク作成時のクレデンシャルに依存します。以下の通り公式ドキュメントに記載がありましたのでご参考ください。
Understanding resource ownership

A resource owner is the AWS account that created the resource. That is, the resource owner is the AWS account of the principal entity (the root account, an IAM user, or an IAM role) that authenticates the request that creates the resource. The following examples illustrate how this behavior works:

If you use the root account credentials of your AWS account to create a task, your AWS account is the owner of the resource (in DataSync, the resource is the task).

If you create an IAM user in your AWS account and grant permissions to the CreateTask action to that user, the user can create a task. However, your AWS account, to which the user belongs, owns the task resource.

If you create an IAM role in your AWS account with permissions to create a task, anyone who can assume the role can create a task. Your AWS account, to which the role belongs, owns the task resource.

<参考>
Understanding resource ownership

そのため、単一アカウント内であれば特に問題無いですが、クロスアカウント接続の場合はタスクリソースのクレデンシャルをバケットポリシーのPrincipalセクションに指定する必要がありそうです。
クロスアカウント想定でのS3のバケットポリシーに関して、公式ドキュメントに記載がありましたので、ご参考にしてみてください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::1111222233334444:role/datasync-config-role",
          "arn:aws:iam::1111222233334444:role/datasync-transfer-role"
        ]
      },
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads"
      ],
      "Resource": [
        "arn:aws:s3:::example-source-bucket"
      ]
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::1111222233334444:role/datasync-config-role",
          "arn:aws:iam::1111222233334444:role/datasync-transfer-role"
        ]
      },
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:ListMultipartUploadParts",
        "s3:PutObjectTagging",
        "s3:GetObjectTagging",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::example-source-bucket/*"
      ]
    }
  ]
}

ポリシーの補足部分を抜粋

Be sure to replace the following values in the preceding policy:
datasync-config-role with the IAM role that's used for DataSync configuration (example: create a source S3 location and the task in DataSync)
Note: You might also use an IAM user. This article considers the use of the IAM role.

<参考>
How can I use AWS DataSync to transfer the data to or from a cross-account Amazon S3 location?

  • DataSyncからCloudWatch Logsにログを送信するためには、CloudWatch Logsのリソースベースポリシーを設定が必要です。datasync.amazonaws.comに対してPutLogEventsCreateLogStreamのアクションを許可してください。
{
  "Statement": [
    {
      "Sid": "DataSyncLogsToCloudWatchLogs",
      "Effect": "Allow",
      "Action": [
        "logs:PutLogEvents",
        "logs:CreateLogStream"
      ],
      "Principal": {
        "Service": "datasync.amazonaws.com"
      },
      "Resource": "*"
    }
  ],
  "Version": "2012-10-17"
}

上記は公式ドキュメントの抜粋になります。詳細は以下を参考ください。

<参考>
Why can't I find my DataSync task logs in the CloudWatch log group?

他のAWSサービスでもリソースベースポリシーの付与を忘れて、ロギングが上手くいかない事が散見されますが、DataSyncに関しても同様の配慮が必要になります。

4.5 まとめ

 今回はDataSyncリソースをテンプレートで作成してみました。DataSyncのTIPSは他のサービスと比べてあまりネット上に落ちていないかなと思っているので、自動化を考えている方がいれば是非とも工数削減に使っていただけると嬉しいです。

このブログが誰かの役に立てばと思います。Mituoでした!!

5. 参考資料

What is AWS DataSync?
DataSyncタスクを作成してみた
AWS::DataSync::Task
AWS::DataSync::LocationS3
AWS::DataSync::LocationEFS
Understanding resource ownership
How can I use AWS DataSync to transfer the data to or from a cross-account Amazon S3 location?
Why can't I find my DataSync task logs in the CloudWatch log group?

Discussion