배경
Multi Account 환경에서 S3의 Object를 복제를 하는 것은 생각보다 많은 작업이 필요하다. 단일 Account의 S3에서는 간단한 작업이겠지만 Bucket to Bucket일 경우 잡다한 과정들이 많이 들어간다. 처음 개념을 잡아 놓고 가면 좋을 것 같아 기록하려고한다.
특히 실행하는 Role의 IAM Policy뿐만 아니라 Source와 Destination의 Bucket Policy, KMS Key Policy, Object Ownership까지 같이 확인해야한다.
방법
AWS CLI는 아래와 같다.
aws s3 sync s3://[SOURCE_BUCKET]/[PREFIX] s3://[DESTINATION_BUCKET]/[PREFIX] \
--source-region [SOURCE_REGION] \
--region [DESTINATION_REGION]sync는 Source와 Destination을 비교해서 누락되었거나 크기와 수정 시간이 다른 Object를 복사한다.
Source에서 삭제된 Object를 Destination에서도 삭제하고 싶다면 --delete를 사용한다. 하지만 대량으로 삭제될 수 있기 때문에 먼저 --dryrun으로 확인하는 것이 좋다.
aws s3 sync s3://[SOURCE_BUCKET] s3://[DESTINATION_BUCKET] --dryrunCross-account 권한
Multi Account에서는 먼저 어느 Account의 어떤 Role이 명령을 실행하는지를 정해야한다. 예를 들어 Account A의 Source를 Account B로 복사할 때 Account B의 S3SyncRole을 Assume해서 실행한다면 아래의 권한들이 필요하다.
Source bucket
- bucket:
s3:ListBucket, 필요하면s3:GetBucketLocation - object:
s3:GetObject - source가 SSE-KMS이면 source KMS key에
kms:Decrypt
Destination bucket
- bucket:
s3:ListBucket, 필요하면s3:GetBucketLocation - object:
s3:PutObject --delete사용 시s3:DeleteObject- destination이 SSE-KMS이면 destination KMS key에
kms:GenerateDataKey, multipart upload에서는kms:Decrypt도 필요
실행 Role의 IAM Policy에 권한이 있더라도 다른 Account의 Bucket과 KMS Key에서 해당 Role을 허용하지 않는다면 접근할 수 없다. 따라서 Cross Account에서는 다음을 같이 확인해야한다.
- 실행 role의 IAM identity policy
- source와 destination bucket policy
- source와 destination KMS key policy 또는 grant
- SCP, permissions boundary, VPC endpoint policy의 명시적 deny
SSE-KMS 주의 사항
SSE-KMS object를 account 간에 공유하려면 cross-account 권한을 줄 수 있는 customer managed KMS key가 필요하다. AWS managed key는 다른 account principal에 key policy를 추가할 수 없으므로 cross-account 복사에 사용할 수 없다.
복사는 Source Object를 복호화한 뒤 Destination의 암호화 설정으로 새로운 Object를 생성한다. Destination Bucket의 기본 암호화가 Customer Managed KMS Key라면 해당 Key가 사용된다. 특정 Key를 직접 지정하고 싶다면 다음 Option을 사용한다.
실제 key user policy에는 작업 방식에 따라 kms:Encrypt, kms:Decrypt, kms:ReEncrypt*, kms:GenerateDataKey*, kms:DescribeKey 중 필요한 작업만 허용한다. 특히 AWS CLI가 큰 object를 multipart upload로 전환할 수 있으므로 destination key의 kms:Decrypt 누락도 확인한다.
aws s3 sync s3://[SOURCE_BUCKET] s3://[DESTINATION_BUCKET] \
--sse aws:kms \
--sse-kms-key-id arn:aws:kms:[REGION]:[ACCOUNT_ID]:key/[KEY_ID]Object Ownership
새로운 Bucket은 기본적으로 Bucket owner enforced가 적용되어 ACL이 비활성화되고 Destination Bucket Owner가 Object를 소유한다.
기존 Bucket에서 ACL을 사용하고 있다면 업로드한 Account가 Object Owner가 될 수 있고 s3:PutObjectAcl 권한도 추가로 필요할 수 있다. 가능하면 Bucket owner enforced로 통일하고 Policy를 통해 권한을 관리하는 것이 편하다.
검증 절차
aws sts get-caller-identity로 실제 실행 account와 role을 확인한다.--dryrun으로 복사·삭제 대상을 확인한다.- 작은 prefix로 먼저 실행한다.
- source/destination의 object 수와 대표 object의 size, ETag, encryption을 비교한다.
AccessDenied가 나면 S3 권한과 KMS 권한을 분리해 CloudTrail event를 확인한다.
aws s3api head-object --bucket [DESTINATION_BUCKET] --key [OBJECT_KEY]sync와 Replication의 차이
aws s3 sync는 명령어를 실행한 시점에 Object를 복사하는 방식이다. 이후의 변경 사항까지 계속 복제해주는 것은 아니다.
지속적으로 Object를 복제하거나 Version과 Delete Marker까지 관리해야한다면 S3 Replication을 사용해야한다. 일회성 이관이나 다시 동기화할 때는 sync, 지속적인 DR이나 동기화는 Replication으로 구분하면 된다.