6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ZOZOAdvent Calendar 2021

Day 6

DataSyncを利用したEFSからS3のデータ転送時の注意点

Last updated at Posted at 2021-12-05

この記事は何か

DataSyncを利用して、EFSとS3のデータ転送を行う際に、つまづきポイントがあったので、簡単にまとめる。
今回DataSyncは初利用だったので、見事にハマったなーという思いと、公式ドキュメントに明記されていなかった部分なので、もしも同じ部分でつまづいた人がいたら、参考になれば嬉しい。

DataSyncとは

AWSが提供するオンラインデータ転送のサービス。
昨年からAWSのストレージサービス間ならエージェント不要でデータ転送が可能となった。めでたい。
つまり、EC2やECSなどのリソースは不要で、マネージドサービスだけでデータの転送が可能 :tada:
image.png

何をしようとしたか

EFSのデータを定期的にS3転送する

極力マネージドサービスで完結したかったので、DataSync TaskでEFSのデータをS3に定期的に転送しようとした

EFSの設定状況

  • VPC内に配置されている
  • File System Policyが設定され許可したIAMRoleしかMountやWriteができないように制御している
  • ECSで稼働中のサービスからマウントされている

進め方

初のDataSyncの利用だったので、素直に公式ドキュメントをみてリソースの作成と設定を試みた。

参考にしたドキュメント

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_DataSync.html
https://docs.aws.amazon.com/datasync/latest/userguide/create-efs-location.html
https://docs.aws.amazon.com/datasync/latest/userguide/create-s3-location.html

リソース作成、実行、そして失敗

EFSからS3へのデータ同期となるので、SourceLocationとしてEFS、DestinationLocationとしてS3のlocationをそれぞれ作成し、後はDataSyncのTaskを作成すれば良いと理解。
IAMRoleやSecurityGrouoなどはつまづきがちな部分は公式でもきっちりフォローされているので大きなトラブルはなさそうと思い、作業をスタート。なお、リソースの作成はCloudFormationで行った。

  • Source Location(EFS)の作成
  DataSyncLocationEFS:
    Type: AWS::DataSync::LocationEFS
    Properties:
      Ec2Config:
          SecurityGroupArns:
            - !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/${EC2SecurityGroupDataSyncEFS}'
          SubnetArn: !Sub
            - 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${SubnetId}'
            - SubnetId: ${SubnetId}
      EfsFilesystemArn: !GetAtt EFSFileSystemSessions.Arn
      Subdirectory: '/dirctory'
  • Destination Location(S3)の作成
  DataSyncLocationS3:
    Type: AWS::DataSync::LocationS3
    Properties:
      S3BucketArn: !GetAtt S3BucketImageData.Arn
      S3Config:
          BucketAccessRoleArn: !GetAtt IAMRoleDataSyncLocationS3.Arn
      S3StorageClass: STANDARD
  • DataSync Taskの作成
  DataSyncEFStoS3:
    Type: AWS::DataSync::Task
    Properties:
      DestinationLocationArn: !GetAtt DataSyncLocationS3.LocationArn
      Name: !Sub 'EFStoS3'
      Schedule:
          ScheduleExpression: "cron(55 * * * ? *)"
      SourceLocationArn: !GetAtt DataSyncLocationEFS.LocationArn
  • IAM Roleの作成
  IAMRoleDataSyncLocationS3:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: 'Allow'
            Principal:
              Service: 'datasync.amazonaws.com'
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyDocument:
            Statement:
              - Effect: 'Allow'
                Action:
                  - 's3:GetBucketLocation'
                  - 's3:ListBucket'
                  - 's3:ListBucketMultipartUploads'
                Resource:
                  - !GetAtt S3BucketImageData.Arn
              - Effect: 'Allow'
                Action:
                  - 's3:AbortMultipartUpload'
                  - 's3:DeleteObject'
                  - 's3:GetObject'
                  - 's3:ListMultipartUploadParts'
                  - 's3:GetObjectTagging'
                  - 's3:PutObjectTagging'
                  - 's3:PutObject'
                Resource: !Sub '${S3BucketImageData.Arn}/*'
          PolicyName: 'datasync-location-s3'
  • Security GroupでDataSyncタスクのSubnetからEFSに対して2049のポートアクセスを許可
  • EFS側のFile System Policyに今回作成したDataSync TaskのIAMRoleを追加

ここまででリソース作成が完了した形....が、いざタスクを実行すると失敗 :cry:

具体的にはDataSyncのタスクで以下のエラーが発生した。

Task failed to access location loc-XXXXXXXXXXX: x40016: mount.nfs: Connection timed out

原因調査

エラーメッセージを見るとコネクションタイムアウトとあるので、ネットワーク的な部分で遮断されているように見える。
エラーメッセージが表示されるケースも調べたが、やはり所属するSubnetかSecurity Groupの設定ミスが原因とあり、ネットワーク周りの設定ミスが原因に見えた。

ネットワーク的な問題と思いSubnetの指定ミスやSecurity Groupの設定ミスを疑い確認したが、少なくとも設定ミスはなさそう :thinking:
問題の切り分けのためにSecurity Groupの制限を緩めたりしてみたけれど、エラーは変わらず :cry:
ネットワークの制限を緩めてもエラーが変わらなかったので、おそらくネットワークではないどこかでつまづいていると思い、サポートに問い合わせを投げた :pray:

失敗の原因

サポートからの返答を抜粋。

DataSync のタスクが EFS をマウントする際に Connection timed out にてエラーが発生する事象について調査のご報告をいたします。
お客様の設定状況を拝見いたしましたところ、DataSync ロケーションの設定や、EFS マウントターゲットのセキュリティグループやサブネット等の設定に問題は見受けられませんでした。
一方で、調査の結果、当該 EFS に設定されたファイルシステムポリシーが原因となり、当該エラーが発生している可能性が考えられました。
DataSync では、大変恐縮ではございますが、現時点において EFS のアクセスポリシーでの制限をサポートいたしておりません。
また、こちらの制約に関して現在有効なワークアラウンドはなく、EFS のファイルシステムポリシーを削除いただく、あるいは、DataSync を利用せずにコマンドラインツール等にて EFS からデータを転送いただくことが代替案となります。

つまり、 EFSのファイルシステムポリシーを利用しているとDataSyncが使えない という結論。完全に盲点だった。
検証のため、ファイルシステムポリシーを削除したところ、問題なくDataSyncのTaskが成功したので、まさにこのサポートの回答通りの挙動だった。

代替案

DataSyncを利用した代替案はないので(File System Policyを削除すればできるけれど、それを削除するわけにはいかなかったので)、LambdaでEFSからS3にデータ転送を行うスクリプトを書いて定期的に実行することにした。
今回、この同期のスクリプトは本筋ではないので割愛。

まとめ

DataSyncを利用したEFSからのデータ転送やEFSへのデータ転送を行う際、File System Policyを利用している場合は現時点だとできないので、気をつけよう!
反面、今回のようにFile System Policyが利用されているEFSでなければ、S3への定期的なデータ転送が自前のスクリプトなしでできたので、DataSyncがNoOps的な側面で嬉しい機能であることに間違いないなと思えた。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?