COLUMN

AWS DataSyncを使ってS3からEFSへデータを転送する!

こんにちは!皆さんデータ転送サービスのAWS DataSyncを利用していますか?私は使ったことがありませんので、新技術習得のため利用してみたいと思います。AWS DataSyncの中でもS3からEFSに転送できる機能はとても面白いので、今回はそちらに挑戦したいと思います。

本稿はAWSのストレージをなんとなく知っていることを前提としていますので、AWSのストレージが良く分からないという方は、こちらのAWSでファイルサーバーを構築する際のストレージの選び方を先に読んでから本稿を読み進めて頂けると幸いです。

本題に入る前にAWSの転送サービスは複数ありますので、注意喚起をしたいと思います。本稿ではS3からEFSへの転送にAWS DataSyncを利用しますが、状況によっては他のサービスを利用した方が好ましい場合もありますので、データ転送の利用の際は慎重に検討されることをお勧めします。

  • AWS DataSync

オンプレミスのデータをAWSストレージサービス(Amazon S3、Amazon EFS、Amazon FSx)に簡単かつ迅速に移行するためのデータ転送サービス。

  • AWS Transfer Family

セキュアなファイル転送プロトコル(SFTP、FTPS、FTP)を使用して、オンプレミスのファイルシステムとAWSクラウド間でデータを転送するためのサービス。

  • AWS Snow Family (Snowcone, Snowball, Snowmobile)

物理的なデバイスを使用して大量のデータ(ペタバイト規模)をAWSに転送するためのサービス。インターネット経由での転送が現実的でない場合に特に便利です。

  • AWS Direct Connect:

オンプレミス環境とAWSクラウド間で専用のネットワーク接続を確立することにより、インターネットを経由せずにデータを転送するためのサービス。

※このサービス単体でのデータ移行は出来ませんが、転送時に考慮するサービスの代表格の為、記載しました。

  • AWS Storage Gateway

オンプレミスとAWSクラウドのストレージをシームレスに統合し、データをバックアップ、アーカイブ、災害復旧のためにAWSに転送するためのハイブリッドストレージサービス。

  • AWS Database Migration Service (DMS)

データベースをAWSのデータベースサービスに移行するためのサービス。オンプレミスのデータベースからAmazon RDS、Amazon DynamoDB、Amazon Redshiftなどにデータを移行することができます。

  • Amazon S3 Transfer Acceleration

インターネットを介したAmazon S3へのファイルアップロードを高速化するサービス。グローバルなAWSエッジロケーションを使用して、データ転送を最適化します。

1. AWS DataSyncの基本

AWS DataSyncは、オンプレミスのストレージシステムとAWSクラウドストレージサービス間、またはAWSの異なるストレージサービス間でデータを簡単かつ迅速に転送するためのマネージドサービスです。このサービスはデータ転送の自動化、スケジューリング、追跡を簡素化し、効率的なデータ移行、データプロセッシング、データバックアップの実現をサポートします。

主な特徴

1.高速転送 – AWS DataSyncは、ネットワーク最適化技術を使用してデータを高速で転送します。

2.データ同期 – 定期的なデータ同期が必要な場合、特にバックアップや災害復旧のためのシナリオで有用です。

3.マネージドサービス – 複雑なスクリプト作成やリソースの管理が不要で、GUIを通じて簡単に設定できます。

4.セキュリティ – データ転送はSSL/TLSを使用して暗号化されます。

5.柔軟なデータソース – NFS、SMBプロトコルをサポートするファイルシステムや、AWS EFS、FSx、S3などの複数のAWSサービスと互換性があります。

6.スケジューリング – 転送タスクを自動的にスケジュールする機能があります。

使用シナリオ

(1)オンプレミスからクラウドへのデータ移行

  データセンターからAWSへの移行を効率的に実施できます。

(2)クラウド間データ転送

  異なるAWSリージョン間、または異なるAWSアカウント間のデータ転送。

(3)バックアップと復旧

  データのバックアップや災害復旧用のデータ複製を自動化します。

(4)データ同期

  本番環境とバックアップ環境間でのデータを定期的に同期します。

私が調べたところ、このような使われ方が多いようです。データの転送や同期を行えるサービスでオンプレミスからAWS、AWSからAWSと幅広い環境で利用できることが分かりました。

2. AWS DataSyncのセットアップ

では、実際に触って行きたいと思います。今回はS3とEFS間でデータ転送を実施したいのでS3とEFSを作成します。しかしEFSの作成にはVPCも必要で、個別にGUIで設定していくと大変なので、terraformを利用しました。provider.tfとlocals.tfは適宜ご用意頂ければと思います。

//EFS

resource "aws_efs_file_system" "example" {
  creation_token = local.myself
  tags = local.tags
}
 
resource "aws_efs_mount_target" "examplea" {
  file_system_id  = aws_efs_file_system.example.id
  subnet_id       = aws_subnet.example_subnet.id
  security_groups = [aws_security_group.example_sg.id]
}

//S3

resource "aws_s3_bucket" "example" {
  bucket = local.myself
  tags = local.tags
}

//VPC

resource "aws_vpc" "example_vpc" {
  cidr_block = local.cidr_block
  enable_dns_support   = true
  enable_dns_hostnames = true
 
  tags = local.tags
}
 
resource "aws_subnet" "example_subnet" {
  vpc_id            = aws_vpc.example_vpc.id
  cidr_block        = local.subnet_cidr_block
  availability_zone = local.availability_zone
 
  tags = local.tags
}
 
resource "aws_security_group" "example_sg" {
  name        = local.myself
  description = "aws_security_group"
  vpc_id      = aws_vpc.example_vpc.id
 
  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    self        = true
  }
 
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1" 
    cidr_blocks = ["0.0.0.0/0"]
  }
 
  tags = local.tags
}
 
resource "aws_vpc_endpoint" "ssm_endpoint" {
  vpc_id             = aws_vpc.example_vpc.id
  service_name       = "com.amazonaws.${local.region}.ssm"
  vpc_endpoint_type  = "Interface"
  subnet_ids         = [aws_subnet.example_subnet.id]
 
  security_group_ids = [aws_security_group.example_sg.id]
 
  private_dns_enabled = true
  tags = {
    Name = "ssm-endpoint"
  }
}
 
resource "aws_vpc_endpoint" "ssmmessages_endpoint" {
  vpc_id             = aws_vpc.example_vpc.id
  service_name       = "com.amazonaws.${local.region}.ssmmessages"
  vpc_endpoint_type  = "Interface"
  subnet_ids         = [aws_subnet.example_subnet.id]
  security_group_ids = [aws_security_group.example_sg.id]
  private_dns_enabled = true
  tags = {
    Name = "ssmmessages-endpoint"
  }
}
 
resource "aws_vpc_endpoint" "ec2messages_endpoint" {
  vpc_id             = aws_vpc.example_vpc.id
  service_name       = "com.amazonaws.${local.region}.ec2messages"
  vpc_endpoint_type  = "Interface"
  subnet_ids         = [aws_subnet.example_subnet.id]
  security_group_ids = [aws_security_group.example_sg.id]
  private_dns_enabled = true
  tags = {
    Name = "ec2messages-endpoint"
  }
}
 
resource "aws_internet_gateway" "example_igw" {
  vpc_id = aws_vpc.example_vpc.id
 
  tags = local.tags
}
 
resource "aws_subnet" "example_public_subnet" {
  vpc_id            = aws_vpc.example_vpc.id
  cidr_block        = local.public_subnet_cidr_block
  availability_zone = local.availability_zone
  map_public_ip_on_launch = true
 
  tags = local.tags
}
 
resource "aws_eip" "example_eip" {
  domain                    = "vpc"
}
 
resource "aws_nat_gateway" "example_natgw" {
  allocation_id = aws_eip.example_eip.id
  subnet_id     = aws_subnet.example_public_subnet.id
 
  tags = local.tags
}
 
resource "aws_route_table" "example_public_rt" {
  vpc_id = aws_vpc.example_vpc.id
 
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.example_igw.id
  }
 
  tags = local.tags
}
 
resource "aws_route_table_association" "example_public_rta" {
  subnet_id      = aws_subnet.example_public_subnet.id
  route_table_id = aws_route_table.example_public_rt.id
}
 
resource "aws_route_table" "example_private_rt" {
  vpc_id = aws_vpc.example_vpc.id
 
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.example_natgw.id
  }
 
  tags = local.tags
}
 
resource "aws_route_table_association" "example_private_rta" {
  subnet_id      = aws_subnet.example_subnet.id
  route_table_id = aws_route_table.example_private_rt.id
}

それではマネコンを触って行きたいと思います。

左側メニューのロケーションを選択します。

ロケーションを作成するを押下します。

ロケーションタイプはS3

S3バケットは先ほど作成したもの

フォルダは指定しません

IAMロールは自動生成するで作成してもらいました。

ロケーションを作成するを押下します。

このような画面になりました。

タスクを作成することによって、スケジューリングや同期が可能なのでしょうか。

さすがAWS。いきなりタスクから入ってもロケーションの作成は可能だったようです。

次へボタンを押下します。

なるほど、送信元だけをロケーションと呼ぶのかと思っていましたが、送信先もロケーションという表現を用いるようです。

送信先(EFS)のロケーションも作成します。

これで、送信元と送信先の設定が完了です。

次へボタンを押下します。

設定項目が多いですが、一旦デフォルトで進めます。

このような設定になりました。

タスクを設定するを押下します。

右上に開始ボタンがあります。

押してみます。

タスクのステータスが実行中になりました。

これにて設定は完了です。

 

3. 実際に使ってみる

S3に何か適当なファイルを配置してみたいと思います。

10MB程度のよさげなファイルがありましたので、アップロードしました。

履歴タブを押下します。

開始時刻がファイルアップロード時刻ではありませんが、こちらを選択します。

ファイルが一つ転送されたのでしょうか。

しかしこれだけでは自分がアップロードしたのかどうかがわかりません。

CloudWatch ロググループも参照してみたいと思います。

時間的にはそれっぽいものを見つけましたが、オブジェクト名が記載されていないのでこれが本当にS3にアップロードしたものかどうかわかりません。EFSの中身を直接見たいと思います。

EFSの中身をみるためにEC2を構築したいと思います。

セッションマネージャーで接続したいので、VPCエンドポイント等も設定します。

resource "aws_instance" "example_instance" {
  ami                    = local.ami_id
  instance_type          = local.instance_type
  subnet_id              = aws_subnet.example_subnet.id
  vpc_security_group_ids = [aws_security_group.example_sg.id]
  tags = local.tags
  iam_instance_profile = aws_iam_instance_profile.ssm_profile.name
}
 
resource "aws_iam_instance_profile" "ssm_profile" {
  name = "ssm_profile"
  role = aws_iam_role.ssm_role.name
}
resource "aws_iam_role" "ssm_role" {
  name = "ssm_role"
 
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })
}
 
resource "aws_iam_role_policy_attachment" "ssm_policy_attachment" {
  role       = aws_iam_role.ssm_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}
 
resource "aws_vpc_endpoint" "ssm_endpoint" {
  vpc_id             = aws_vpc.example_vpc.id
  service_name       = "com.amazonaws.${local.region}.ssm"
  vpc_endpoint_type  = "Interface"
  subnet_ids         = [aws_subnet.example_subnet.id]
 
  security_group_ids = [aws_security_group.example_sg.id]
 
  private_dns_enabled = true
  tags = {
    Name = "ssm-endpoint"
  }
}
 
resource "aws_vpc_endpoint" "ssmmessages_endpoint" {
  vpc_id             = aws_vpc.example_vpc.id
  service_name       = "com.amazonaws.${local.region}.ssmmessages"
  vpc_endpoint_type  = "Interface"
  subnet_ids         = [aws_subnet.example_subnet.id]
  security_group_ids = [aws_security_group.example_sg.id]
  private_dns_enabled = true
  tags = {
    Name = "ssmmessages-endpoint"
  }
}
 
resource "aws_vpc_endpoint" "ec2messages_endpoint" {
  vpc_id             = aws_vpc.example_vpc.id
  service_name       = "com.amazonaws.${local.region}.ec2messages"
  vpc_endpoint_type  = "Interface"
  subnet_ids         = [aws_subnet.example_subnet.id]
  security_group_ids = [aws_security_group.example_sg.id]
  private_dns_enabled = true
  tags = {
    Name = "ec2messages-endpoint"
  }
}

EFSのファイルを確認するだけなのですが、結構手間暇かかりました。EFSからS3にDataSyncして確認する方が速い気もしますが、ここは一旦EC2で確認します。

マウントコマンドを実行後

確認してみましたが、ファイルは転送されていませんでした。

再度転送手順を実施してみます。

上記ボタン(デフォルトから開始する)ボタンを押下

S3に他のファイルを投げてみる

確認する

としたところファイルが転送されていました。

もしかして、勝手に転送されるのではなくて、毎回開始しないといけないのでしょうか。

開始を押さずにS3に投入して待ってみたいと思います。

15時41分に追加しました。

16時03分まで待ってみましたが、追加されませんでした。

再度開始ボタンを押下してみます。

無事転送されました!勝手にイベント駆動でファイルが転送されるものと思っていましたがそうではないようです。

タスクを再度見直したところ、

スケジュール設定がありました。

毎時と毎日を選択したところ、頻繁に実行するとS3のコストが上がる可能性があるとの注意が出てきました。

  • タスクを実行するたびに、DataSyncHEADオブジェクトメタデータの取得をリクエストします。これらのリクエストにより、オブジェクトを移動していなくても料金が発生します。これらのリクエストが請求にどの程度影響するかは、DataSyncオブジェクトが使用しているストレージクラスとスキャンするオブジェクトの数によって異なります。
  • オブジェクトを(直接またはバケットライフサイクル設定を通じて)S3 Glacier Instant Retrieval ストレージクラスに移動した場合、このクラスのオブジェクトに対するリクエストは他のストレージクラスのオブジェクトよりも高価になります。
  • DataSyncソースとターゲットのロケーションが完全に同期していることを確認するようにタスクを設定すると、すべてのストレージクラス (S3 Glacier Flexible Retrieval と S3 Glacier Deep Archive を除く) GET で各オブジェクトに対するリクエストが送信されます。
  • GETリクエストに加えて、S3 標準 — IA、S3 Glacier Flexible Retrieval、または S3 Glacier Flexible Retrieval ストレージクラスのオブジェクトを取り出す時に料金が発生します。

引用:Amazon S3 AWS DataSync でTransfer を設定する

なるほど、何も転送しなくてもS3の走査料金はかかりますってことみたいですね。オブジェクトが沢山あるようなバケットをそのまま使いづけるのは検討の余地がありそうです。しかし、EFSにコピーできる点は非常に優秀だと思います。

また、S3イベントとLambdaを組み合わせてタスクを実行させれば即時実行も可能になると思います。

Amazon Web Services(AWS)は、米国その他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。

ページ上部へ戻る

相談無料!プロが中立的にアドバイスいたします

クラウド・AWS・Azureでお困りの方はお気軽にご相談ください。