Java에서 DynamoDB 테이블을 S3로 내보내자
환경
- Java
- Gradle
- AWS(DynamoDB, S3, IAM)
- AWS Java SDK(1.x 또는 2.x)
- IntelliJ
시작하기 전에
- 해당 내용은 AWS IAM에서 사용자의 생성, 사용자의 역할 및 권한 부여, 사용자의 키(aws_access_key_id, aws_secret_access_key) 발급에 대해서 알고 있다고 가정한다.
- 해당 내용은 S3에서 버킷의 개념에 대해 알고 있다고 가정한다.
- 해당 내용은 DynamoDB에서 테이블이 이미 생성되어 있고 해당 테이블의 PITR이 활성화 되어있다고 가정한다. 이 부분에 관해서는 Amazon S3 로 DynamoDB 데이터 내보내기: 작동 방식을 참고한다.
사전 준비
AWS 설정
사용자 및 Credential 설정
- AWS IAM에서 사용자는 생성되어 있다고 가정한다.
- 사용자에 해당하는 credential은 이 코드가 실행되는곳에 이미 설정되어 있다고 가정한다. 관련 내용은 Step 1: Set up for this tutorial를 참고한다.
(옵션) AWS IAM 사용자가 아니라 AWS IAM 역할을 사용하는 경우
- EC2 인스턴스에 IAM 역할을 부여해서 사용하는것처럼 AWS IAM의 역할을 사용하는 경우 해당 역할의 ARN만 사용해주면 되며 정책의 적용 방법은 아래와 모두 동일하다.
- 사용자 권한 설정의 IAM 정책을 역할에 연결해주고 해당 역할의 ARN을 대상 S3 버킷 정책 설정에 적용하면 된다.
사용자 권한 설정
- AWS IAM에서 생성해서 아래의 코드를 실행할 AWS 사용자는 아래와 같은 권한이 필요하다.
- https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DataExport.Requesting.html#DataExport.Requesting.Permissions
- 물론 그대로 사용하는게 아니며 실행하는 환경에 따라 아래의 ARN, Region, AWS 계정 ID와 같은 내용들을 수정해야한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowDynamoDBExportAction",
"Effect": "Allow",
"Action": "dynamodb:ExportTableToPointInTime",
"Resource": "arn:aws:dynamodb:us-east-1:111122223333:table/my-table"
},
{
"Sid": "AllowWriteToDestinationBucket",
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::your-bucket/*"
}
]
}
대상 S3 버킷 정책 설정
- 대상 S3의 버킷에서도 아래 버킷 정책 설정이 필요하다.
- https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DataExport.Requesting.html#DataExport.Requesting.Permissions
- 물론 그대로 사용하는게 아니며 실행하는 환경에 따라 아래의 사용자, ARN, Region, AWS 계정 ID와 같은 내용들을 수정해야한다.
- 만약 서로 다른 AWS 계정에서 접근한다면 ACL 설정도 추가해주면 되며 리소스 기반 ACL(액세스 제어 목록) 및 IAM 정책을 참고하면 된다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ExampleStatement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/Dave"
},
"Action": [
"s3:AbortMultipartUpload",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::awsexamplebucket1/*"
}
]
}
IntelliJ 설정
- build.gradle을 이용해서 SDK를 가져왔으며 각 버전에 해당하는 정보는 아래 코드를 참고한다.
코드
Java SDK 1.x
build.gradle
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation group: 'com.amazonaws', name: 'aws-java-sdk-dynamodb', version: '1.12.42'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
ExportDynamoDbTableToS3.java
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.ExportTableToPointInTimeRequest;
public class ExportDynamoDbTableToS3 {
public static void main(String[] args) {
// Please fill out below values
String tableArn = "";
String s3Bucket = "";
String s3Prefix = "";
String exportFormat = "";
String s3BucketOwner = "";
AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.defaultClient();
ExportTableToPointInTimeRequest exportTableToPointInTimeRequest = new ExportTableToPointInTimeRequest();
exportTableToPointInTimeRequest.setTableArn(tableArn);
exportTableToPointInTimeRequest.setS3Bucket(s3Bucket);
exportTableToPointInTimeRequest.setS3Prefix(s3Prefix);
exportTableToPointInTimeRequest.setExportFormat(exportFormat);
exportTableToPointInTimeRequest.setS3BucketOwner(s3BucketOwner);
amazonDynamoDB.exportTableToPointInTime(exportTableToPointInTimeRequest);
}
}
Java SDK 2.x
build.gradle
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation platform('software.amazon.awssdk:bom:2.17.14')
implementation 'software.amazon.awssdk:dynamodb'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
ExportDynamoDbTableToS3.java
import software.amazon.awssdk.services.dynamodb.model.ExportTableToPointInTimeRequest;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
public class ExportDynamoDbTableToS3 {
public static void main(String[] args) {
// Please fill out below values
String tableArn = "";
String s3Bucket = "";
String s3Prefix = "";
String exportFormat = "";
String s3BucketOwner = "";
DynamoDbClient dynamoDbClient = DynamoDbClient.builder().build();
ExportTableToPointInTimeRequest exportTableToPointInTimeRequest = ExportTableToPointInTimeRequest
.builder()
.tableArn(tableArn)
.s3Bucket(s3Bucket)
.s3Prefix(s3Prefix)
.exportFormat(exportFormat)
.s3BucketOwner(s3BucketOwner)
.build();
dynamoDbClient.exportTableToPointInTime(exportTableToPointInTimeRequest);
}
}
결과
DynamoDB
- AWS ID와 버킷명은 가렸습니다.
S3
GitHub
참고자료
- https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DataExport.html
- https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DataExport.HowItWorks.html
- https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DataExport.Requesting.html
- https://docs.aws.amazon.com/ko_kr/sdk-for-java/latest/developer-guide/get-started.html#get-started-setup
- https://aws.amazon.com/ko/premiumsupport/knowledge-center/cross-account-access-s3/
- Java 1.x Interface AmazonDynamoDB
- Java 1.x Class ExportTableToPointInTimeRequest
- Java 1.x AmazonDynamoDB.exportTableToPointInTime
- Java 2.x Interface DynamoDbClient
- Java 2.x Class ExportTableToPointInTimeRequest
- Java 2.x DynamoDbClient.exportTableToPointInTime