본문 바로가기

Storage

[실습] AWS CLI 이용한 서로 다른 AWS 계정간 S3 bucket 동기화(sync) 구성하기

반응형

안녕하세요 서후아빠입니다. ^_^
이번 세션은 서로 다른 계정에 위치하는 S3 bucket을 aws cli 명령어를 통해서 동기화하는 실습을 해보겠습니다.


구성도

1. EC2에서 IAM User의 Access Key를 이용하여 aws cli 접속
2. IAM User가 Source 버킷에 접근하여 Destination 버킷으로 파일 동기화

동기화된 파일 접근 시 "HTTP 403 Forbidden 에러" 발생 시

구성 가정 : A계정(111111111111)에 A버킷(bucketA), B계정(22222222222)에 B버킷(bucketB), 리전(ap-northeast-2)
Sync 방향 : Source(bucketA), Destination(bucketB), A계정 IAM user로 동기화 진행
명령어 : $ aws s3 sync s3://bucketA s3://bucketB
원인 : 최초 생성된 컨텐츠가 A계정으로 생성됨에 따라 B계정에 대한 권한이 부여되지 않음

해결 방법

구분 내용
B계정의 IAM user로 동기화 진행 아래 1단계~5단계 진행
A계정의 IAM user로 동기화 진행 2단계 : B계정에 적용 (A계정 내용을 B계정 내용으로 변경)
3단계 : A계정에 적용 (B계정 내용을 A계정 내용으로 변경)
5단계 : sync 명령어 옵션 추가
  ex : aws s3 sync s3://bucketA s3://bucketB --acl bucket-owner-full-control
--acl bucket-owner-full-control 옵션 : 자동으로 버킷 소유자(B계정)의 소유로 객체 소유권 등록 되도록 하는 기능
  ※ 참고 URL
      http://xn--https-2e0tm31eoy7a05h//repost.aws/knowledge-center/s3-require-object-ownership
      https://aws.amazon.com/ko/blogs/storage/enforcing-ownership-of-amazon-s3-objects-in-a-multi-account-environment/

1단계 : 계정별 S3 bucket 생성(설명 SKIP)

2단계 (A계정) : S3 bucket에 Policy 등록

S3 > Buckets > bucketA > Permissions(tab) > Bucket policy의 Edit

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DelegateS3Access",
			"Action": [
				"s3:GetObject",
				"s3:ListBucket",
				"s3:GetObjectTagging"
			],
			"Effect": "Allow",
			"Resource": [
				"arn:aws:s3:::bucketA",
				"arn:aws:s3:::bucketA/*"
			],
			"Principal": {
				"AWS": [
					"22222222222"
				]
			}
		}
	]
}
s3:GetObjectTagging 권한 이슈
 - On-premise에서 S3 bucket으로 sync 시에는 권한 불필요 
 - S3 bucket에서 다른 S3bucket으로 sync 시에는 권한 필요 (권한 누락 시 일정 크기 이상의 객체 누락됨)

3단계 (B계정) : aws cli를 동작시킬 IAM user 설정

IAM > Policies > Create policy > JSON(tab) > 아래 내용 추가 > Name(S3syncIAMUserPolicy)

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DestinationBucketAccess",
			"Action": [
				"s3:ListBucket",
				"s3:PutObject",
				"s3:DeleteObject",
				"s3:GetObjectAcl"
			],
			"Effect": "Allow",
			"Resource": [
			"arn:aws:s3:::bucketB",
			"arn:aws:s3:::bucketB/*"
			]
		},
		{
			"Sid": "SourceBucketAccess",
			"Action": [
				"s3:ListBucket",
				"s3:GetObject"
			],
			"Effect": "Allow",
			"Resource": [
			"arn:aws:s3:::bucketA",
			"arn:aws:s3:::bucketA/*"
			]
		}
	]
}

 

Permissions(tab) > Add permissions > Permissions options(Attach policies directly) > Permissions policies (S3syncIAMUserPolicy)
IAM > Users > 사용자 선택 (없는 경우 생성) > Security credentials(tab) > Access keys의 Create access key > csv파일 다운로드

신규 생성하거나 좀 더 상세한 내용은 "https://sh-t.tistory.com/62"의 1~2단계를 참조하시기 바랍니다.

4단계 : EC2(Amazon Linux AMI) 생성하여 터미널 접속(설명 SKIP)

이전 단계에서 생성한 IAM user를 통해서 S3를 접근하기 때문에 EC2에 S3에 대한 권한 부여가 불필요합니다.
Amazon Linux AMI로 EC2를 생성하면 aws cli를 별도 설치할 필요가 없습니다.

5단계 : aws cli 명령어로 S3 bucket 동기화 실행

# 대량 파일 경우 시간이 많이 소요되므로 테스트 명령어 실행
aws s3 sync s3://bucketA s3://bucketB --dryrun

# 동기화 명령어 실행 (--delete 옵션 : bucketA 없는 파일은 bucketB에서 삭제 처리)
aws s3 sync s3://bucketA s3://bucketB --delete

# crontab으로 주기적인 동기화 실행 (예시 : 1분마다)
sudo crontab -e
* * * * * aws s3 sync s3://bucketA s3://bucketB --delete

# crontab 실행 결과 확인
sudo cat /var/log/cron | grep s3

# 만약 정상동작하지 않는다면 위의 모든 명령어를 root 권한으로 진행
sudo su 
aws s3 sync s3://bucketA s3://bucketB --delete
aws cli 로그인은 "https://sh-t.tistory.com/62"의 3단계를 참조하시기 바랍니다.

주의사항

s3 sync 명령어를 옵션없이 실행할 경우 Server(=EC2)의 CPU 사용율이 100%까지 사용할 수 있습니다.

만약, 운영중인 서버에서 실행할 경우 장애가 발생할 수 있기 때문에 주의를 요합니다. 

혹은 아래처럼 CPU 스레드를 조정한 후,  동기화를 진행하면 장애는 발생하지 않으나, 전송 속도는 떨어질 수 있습니다. 

# 기본 프로필 설정 (기본값은 10, 1로 설정하는 경우)
aws configure set default.s3.max_concurrent_requests 1   

# 사용자 프로필 설정
aws configure set s3.max_concurrent_requests 1 --profile [사용자 프로필]

# 세팅확인
cat .aws/config

누락 및 에러 

s3 sync 명령어를 통해 복제된 파일이 누락이나 에러로 전송되지 않는 경우에 대한 의심을 하시는 분들을 위해서 아래 가이드를 권고 드립니다.

aws s3 ls 명령어는 1000개 이상 동시 조회 불가능하므로 1000개 이상일 경우 aws s3api list-objects 명령어를 사용해야 합니다.

# 작업전후 파일 비교 방법 (예시)
aws s3 ls --recursive s3://[버킷명] --summarize 
Total Objects: 333    
Total Size: 344375 

aws s3api list-objects --bucket "[버킷명]" --prefix "prefix-name"  --output json --query "[sum(Contents[].Size), length(Contents[])]"

# Output결과를 넣고, vi나 여러가지 방법으로 error 필터링하는 방법
aws s3 ls | tee -a "output.log"

# 디버깅 로그 기록 (AWS Support로 Case open 시 실패한 Request Id 정보를 전달하기 위해 필요)
aws s3 sync s3://bucketA s3://bucketB --debug& >> ./s3_debug.log

빈폴더 누락 해결 방법

s3 sync 명령어 혹은 cp 명령어로 작업하는 경우 빈폴더는 누락됩니다. 무슨 짓을 해도 안되더라고요. 

그런데 특정 고객사에서 폴더 구조를 유지해야하기 때문에 빈폴더도 복사되어야 한다고 하여 결국 아래처럼 작업을 하였습니다. (ec2-01은 소스 보관 중인 서버, ec2-02는 s3버킷 마운트 서버)

1. ec2-02을 준비하여 s3 버킷과 마운트(ex : mountpath)합니다. (https://sh-t.tistory.com/142 참조)

2. ec2-02에 root 패스워드를 등록하고, root로 접근할 수 있도록 설정합니다. (https://sh-t.tistory.com/43의 "관리 콘솔에서 EC2 직렬 콘솔로 연결" 참조)

3. ec2-01에서 명령어(ex : scp -r 소스폴더 root@ec2-02-ip:/mountpath)를 이용하여 ec2-02로 모든 폴더 및 파일 복사 

4. 리눅스 sync 명령어 구성을 통해 주기적으로 동기화 실행

다른 방법

DataSync를 이용한 동기화 방법은 아래 링크를 참조하세요

2023.02.27 - [Storage] - [실습] DataSync 이용한 서로 다른 AWS 계정간 S3 bucket 동기화(sync) 구성하기

 

[실습] DataSync 이용한 서로 다른 AWS 계정간 S3 bucket 동기화(sync) 구성하기

안녕하세요 서후아빠입니다. ^_^ 이번 세션은 지난번 진행한 aws cli를 통한 동기화가 아닌 DataSync 서비스를 이용하여 서로 다른 계정에 위치하는 S3 bucket을 동기화하는 실습을 해보겠습니다. 구성

sh-t.tistory.com

S3 버킷의 Replication rules을 이용하여 복제하는 방법도 있습니다. 

  - 사전 설정 : S3 버킷 선택 > Properties (tab) > Bucket Versioning의 Edit > Bucket Versioning (Enable) > Save changes

  - 경로 : 출발지 S3 버킷 선택 > Management (tab) > Replication rules의 Create replication rule

Replication rule configuration Source bucket Destination IAM role 옵션
Replication rule name : 규칙명 입력
Status : Enabled (or Disabled)
Source bucket name : 자동 선택
Choose a rule scope : 모든 오브젝트 (or 필터링된 오브젝트)
Destination : 목적지 버킷 선택 Create new role Encryption
Destination storage class
Additional replication options

 

반응형