S3
S3 크로스 리전 복제 — Access Denied 해결
크로스 계정 S3 복제에서 객체 소유권이 갈리는 지점을 이해하고, Access Denied를 재현한 뒤 소유권 override로 해결하는 과정을 실습합니다. · 30분
Table of contents
Open Table of contents
0. 사전 준비
준비물입니다.
| 항목 | 내용 |
| AWS 계정 | 1개, 관리 계정으로 사용. 실습 계정 2개는 0.1절에서 만듭니다 |
| 이메일 | 실습 계정 2개용으로 서로 다른 주소 2개 |
| 브라우저 | 1개, 역할 전환으로 계정 이동 |
| 리전 | 소스 `ap-northeast-2`, 대상 `us-east-1` |
| 로컬 도구 | AWS CLI v2, 텍스트 편집기 |
Note 이후 모든 명령의
[각자 접두사]자리에는 본인이 정한 bucket 접두사를,[소스 계정 12자리]와[대상 계정 12자리]자리에는 0.1절에서 만든 계정 번호를 넣습니다.
0.1. Organization 만들고 실습 계정 두 개 만들기
본인의 AWS 관리 계정(Management Account)으로 로그인합니다.
- 검색창에
Organizations를 입력하고 결과에서AWS Organizations를 클릭합니다. - Organization이 없으면
Create an organization을 클릭합니다. - 왼쪽 메뉴에서 AWS accounts 를 클릭합니다.
- 오른쪽 위
Add an AWS account를 클릭합니다. - [Create an AWS account] 를 선택합니다.
- AWS account name 칸에
crr-source를 입력합니다. - Email address of the account’s owner 칸에
[각자 Gmail 앞부분][email protected]을 입력합니다. - IAM role name 칸은 기본값
OrganizationAccountAccessRole그대로 둡니다. - 오른쪽 아래
Create AWS account를 클릭합니다. - 같은 절차를 반복해
crr-dest계정을 만듭니다. 이메일은+crr-dest로 바꿉니다.
Note 계정 생성은 비동기로 처리되기 때문에 몇 분 걸릴 수 있습니다. 완성되면 AWS accounts 목록에서 두 계정(**
crr-source, crr-dest)**의 12자리 번호를 확인합니다
0.2. 관리 계정에 실습용 IAM 사용자 만들기
본인의 AWS 관리 계정(Management Account)으로 로그인합니다.
- AWS Console 검색창에
IAM을 입력하고 결과에서IAM을 클릭합니다. - 왼쪽 메뉴에서 Users 를 클릭합니다.
- 오른쪽 위
Create user를 클릭합니다. - User name 칸에
crr-lab-admin을 입력합니다. - Provide user access to the AWS Management Console 체크박스를 클릭합니다.
- [I want to create an IAM user] 를 선택합니다.
- Console password 에서 [Custom password] 를 선택하고 비밀번호를 입력합니다.
- Users must create a new password at next sign-in 체크박스를 해제하고
Next를 클릭합니다. - Permissions options 에서 [Attach policies directly] 를 선택합니다.
- 정책 목록에서
AdministratorAccess를 검색해 왼쪽 체크박스를 클릭하고Next를 클릭합니다. Create user를 클릭합니다.- 사용자 목록에서
crr-lab-admin을 클릭합니다. - Security credentials 탭을 클릭합니다.
- Access keys 항목에서
Create access key를 클릭합니다. - Use case 에서 [Command line interface (CLI)] 를 선택하고, 아래 확인 체크박스를 클릭한 뒤
Next를 클릭합니다. Create access key를 클릭합니다.- Access key 와 Secret access key 를 기록하고
Done을 클릭합니다.
⚠️Warning Secret access key는 이 화면에서만 확인할 수 있습니다. 창을 닫으면 다시 볼 수 없습니다. 놓쳤다면 그 access key를 지우고 새로 만듭니다.
0.3. 콘솔 역할 전환 준비
- 오른쪽 위 계정 메뉴에서 Add Sessions 을 클릭합니다.
- 로그인 화면에서 [IAM user] 를 선택합니다.
- Account ID 칸에 관리 계정(Management Account) 12자리를 입력합니다.
- IAM user name 칸에
crr-lab-admin을, Password 칸에 0.2절에서 정한 비밀번호를 입력하고Sign in을 클릭합니다. - 오른쪽 위 계정 메뉴에서
Switch role을 클릭합니다. - Account 칸에
[소스 계정 12자리]를 입력합니다. (AWS Organization에서 crr-source의 12자리 확인) - IAM role name 칸에
OrganizationAccountAccessRole을 입력합니다. - Display name 칸에
crr-source를 입력하고 색을 하나 고릅니다. Switch Role을 클릭합니다.- 계정 메뉴에서
Back to crr-lab-admin을 클릭합니다. - 같은 절차로
[대상 계정 12자리]를crr-dest라는 이름으로 등록합니다.
Note 이후 본문의
작업 세션: 소스 계정은crr-source로 전환한 상태,작업 세션: 대상 계정은crr-dest로 전환한 상태,작업 세션: 관리 계정은 전환을 풀고crr-lab-admin으로 돌아온 상태를 뜻합니다. 전환은 계정 메뉴의 기록에서 한 번 클릭으로 됩니다.
0.4. CLI profile 등록
AWS CLI 버전 확인
aws --version
관리 계정 CLI profile 만들기
aws configure --profile crr-lab-admin
대화형 프롬프트 입력값
| 항목 | 입력값 |
| AWS Access Key ID | `[관리 계정 access key ID]` |
| AWS Secret Access Key | `[관리 계정 secret access key]` |
| Default region name | `ap-northeast-2` |
| Default output format | `json` |
소스 계정 profile 등록
aws configure set role_arn arn:aws:iam::[소스 계정 12자리]:role/OrganizationAccountAccessRole --profile crr-source-admin
aws configure set source_profile crr-lab-admin --profile crr-source-admin
aws configure set region ap-northeast-2 --profile crr-source-admin
대상 계정 profile 등록
aws configure set role_arn arn:aws:iam::[대상 계정 12자리]:role/OrganizationAccountAccessRole --profile crr-dest-admin
aws configure set source_profile crr-lab-admin --profile crr-dest-admin
aws configure set region us-east-1 --profile crr-dest-admin
등록된 CLI profile 목록 확인
aws configure list-profiles
Note 목록에
crr-lab-admin,crr-source-admin,crr-dest-admin이 보이면 됩니다. 다른 이름은 기존에 쓰던 profile이라 사람마다 다릅니다.
0.5. 계정 값 확인
두 profile이 가리키는 계정 확인
aws sts get-caller-identity --profile crr-source-admin
aws sts get-caller-identity --profile crr-dest-admin
두 명령의 Account 값이 기록표의 계정 번호와 같은지 확인합니다.
두 계정의 canonical user ID 확인
aws s3api list-buckets --query Owner --profile crr-source-admin
aws s3api list-buckets --query Owner --profile crr-dest-admin
두 명령의 ID 앞 4자리를 기록표에 확인합니다.
1. 실습 환경 만들기
1.1. 소스 bucket 만들기
소스 계정(crr-source-admin)으로 로그인 한다
- 오른쪽 위 리전 선택기에서 [아시아 태평양(서울) ap-northeast-2] 를 선택합니다.
- 검색창에
S3를 입력하고 결과에서S3를 클릭합니다. - 왼쪽 메뉴에서 General purpose buckets 를 클릭합니다.
- 오른쪽 위
Create bucket을 클릭합니다. - Bucket name 칸에
[각자 접두사]-crr-source를 입력합니다.ex) dev-playbuilder-crr-source - Bucket Versioning 에서 [Enable] 을 선택합니다.
- 나머지 항목은 기본값으로 두고 맨 아래
Create bucket을 클릭합니다.
소스 bucket의 versioning 상태 확인
aws s3api get-bucket-versioning --bucket [각자 접두사]-crr-source --profile crr-source-admin
1.2. 대상 bucket 만들기
대상 계정(crr-dest-admin)으로 로그인한다.
- 오른쪽 위 리전 선택기에서 [미국 동부(버지니아 북부) us-east-1] 을 선택합니다.
- 검색창에
S3를 입력하고 결과에서S3를 클릭합니다. - 왼쪽 메뉴에서 General purpose buckets 를 클릭합니다.
- 오른쪽 위
Create bucket을 클릭합니다. - Bucket name 칸에
[각자 접두사]-crr-dest를 입력합니다. - Object Ownership 에서 [ACLs enabled] 를 선택합니다.
- 아래에 나타나는 선택지에서 [Object writer] 를 선택합니다.
- 확인 문구 체크박스를 클릭합니다.
- Bucket Versioning 에서 [Enable] 을 선택합니다.
- 나머지 항목은 기본값으로 두고 맨 아래
Create bucket을 클릭합니다.
Warning Object Ownership 을 [ACLs enabled] 와 [Object writer] 로 선택해야 합니다. 기본값인 [ACLs disabled] 로 두면 3.3절의 결과가 달라집니다.
대상 bucket의 versioning과 Object Ownership 확인
aws s3api get-bucket-versioning --bucket [각자 접두사]-crr-dest --profile crr-dest-admin
aws s3api get-bucket-ownership-controls --bucket [각자 접두사]-crr-dest --profile crr-dest-admin
2. 복제 권한 구성
2.1. 복제용 IAM role 만들기
trust policy 파일 만들기
cat > crr-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
복제용 권한 정책 파일 만들기
cat > crr-role-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-source/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetReplicationConfiguration"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-source"
},
{
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-dest/*"
}
]
}
EOF
Note 위 파일을 만들기 전에
[각자 접두사]를 본인 bucket 이름으로 바꿉니다. 편집기로 파일을 만든 뒤 저장해도 됩니다.복제용 IAM role 생성과 권한 정책 연결
aws iam create-role --role-name crr-replication-role --assume-role-policy-document file://crr-trust-policy.json --profile crr-source-admin
aws iam put-role-policy --role-name crr-replication-role --policy-name crr-replication-policy --policy-document file://crr-role-policy.json --profile crr-source-admin
첫 번째 명령의 Arn 값을 기록표에 적습니다.
2.2. 대상 bucket policy 등록
대상 계정(crr-dest-admin)으로 로그인한다.
- General purpose buckets 목록에서
[각자 접두사]-crr-dest를 클릭합니다. - Permissions 탭을 클릭합니다.
- Bucket policy 항목 오른쪽
Edit을 클릭합니다. - Policy 편집기에 아래 내용을 붙여 넣습니다.
[소스 계정 12자리]와[각자 접두사]를 본인 값으로 바꿉니다.- 맨 아래
Save changes를 클릭합니다.대상 bucket policy — 소유권 override 없음
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReplicationFromSourceAccount",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[소스 계정 12자리]:role/crr-replication-role"
},
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:GetObjectVersionTagging"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-dest/*"
}
]
}
3. 복제 규칙 등록과 Access Denied 재현
3.1. 복제 규칙 등록
소스 계정(crr-source-admin)으로 로그인한다.
- General purpose buckets 목록에서
[각자 접두사]-crr-source를 클릭합니다. - Management 탭을 클릭합니다.
- Replication rules 항목에서
Create replication rule을 클릭합니다. - Replication rule name 칸에
crr-ownership-lab을 입력합니다. - Status 에서 [Enabled] 를 선택합니다.
- Choose a rule scope 에서 [Apply to all objects in the bucket] 을 선택합니다.
- Destination 에서 [Specify a bucket in another account] 를 선택합니다.
- Account ID 칸에
[대상 계정 12자리]를 입력합니다. - Bucket name 칸에
[각자 접두사]-crr-dest를 입력합니다. - Change object ownership to destination bucket owner 체크박스는 선택하지 않고 그대로 둡니다.
- IAM role 에서 [Choose from existing IAM roles] 를 선택하고
crr-replication-role을 선택합니다. - 나머지 항목은 기본값으로 두고 맨 아래
Save를 클릭합니다. - 기존 object 복제 여부를 묻는 안내가 나오면 [No, do not replicate existing objects] 를 선택합니다.
소스 bucket에 등록된 복제 규칙 확인
aws s3api get-bucket-replication --bucket [각자 접두사]-crr-source --profile crr-source-admin
3.2. 파일 업로드와 복제 확인
첫 번째 실습 파일 만들고 업로드
echo "before override" > before-override.txt
aws s3 cp before-override.txt s3://[각자 접두사]-crr-source/before-override.txt --profile crr-source-admin
업로드한 object의 복제 상태 확인
aws s3api head-object --bucket [각자 접두사]-crr-source --key before-override.txt --profile crr-source-admin
Note
ReplicationStatus가PENDING이면 잠시 뒤 같은 명령을 다시 실행합니다.COMPLETED가 나오면 다음 절로 넘어갑니다.
3.3. 대상 계정에서 읽기 시도
대상 계정에서 복제된 object 목록 확인
aws s3api list-objects-v2 --bucket [각자 접두사]-crr-dest --profile crr-dest-admin
대상 계정에서 복제된 object 내려받기 시도
aws s3api get-object --bucket [각자 접두사]-crr-dest --key before-override.txt ./dest-before.txt --profile crr-dest-admin
Warning 이 절의 두 번째 명령은 AccessDenied 오류를 확인하는 단계입니다.
3.4. object 소유자 확인
복제된 object의 소유자 확인
aws s3api list-objects-v2 --bucket [각자 접두사]-crr-dest --fetch-owner --profile crr-dest-admin
Owner.ID 앞 4자리를 기록표의 소스 계정(crr-source) canonical user ID와 비교합니다.
4. 소유권 override 적용
4.1. 대상 bucket policy에 권한 추가
대상 계정(crr-dest-admin)으로 로그인한다.
- General purpose buckets 목록에서
[각자 접두사]-crr-dest를 클릭합니다. - Permissions 탭을 클릭합니다.
- Bucket policy 항목 오른쪽
Edit을 클릭합니다. - Policy 편집기의 내용을 아래로 바꿉니다.
[소스 계정 12자리]와[각자 접두사]를 본인 값으로 바꿉니다.- 맨 아래
Save changes를 클릭합니다.대상 bucket policy — 소유권 override 포함
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReplicationFromSourceAccount",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[소스 계정 12자리]:role/crr-replication-role"
},
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:GetObjectVersionTagging",
"s3:ObjectOwnerOverrideToBucketOwner"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-dest/*"
}
]
}
4.2. 복제용 role 정책에 권한 추가
소유권 override가 포함된 권한 정책 파일 만들기
cat > crr-role-policy-override.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-source/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetReplicationConfiguration"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-source"
},
{
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:ObjectOwnerOverrideToBucketOwner"
],
"Resource": "arn:aws:s3:::[각자 접두사]-crr-dest/*"
}
]
}
EOF
복제용 role의 권한 정책 교체
aws iam put-role-policy --role-name crr-replication-role --policy-name crr-replication-policy --policy-document file://crr-role-policy-override.json --profile crr-source-admin
교체된 권한 정책 확인
aws iam get-role-policy --role-name crr-replication-role --policy-name crr-replication-policy --query "PolicyDocument.Statement[2]" --profile crr-source-admin
4.3. 복제 규칙에 소유권 override 켜기
소스 계정(crr-source-admin)으로 로그인한다.
- General purpose buckets 목록에서
[각자 접두사]-crr-source를 클릭합니다. - Management 탭을 클릭합니다.
- Replication rules 목록에서
crr-ownership-lab왼쪽 라디오 버튼을 클릭합니다. - 오른쪽 위
Edit rule을 클릭합니다. - Destination 항목에서 Change object ownership to destination bucket owner 체크박스를 클릭합니다.
- Destination bucket owner account ID 칸에
[대상 계정 12자리]가 들어가 있는지 확인합니다. - 맨 아래
Save를 클릭합니다.
복제 규칙에 소유권 override가 들어갔는지 확인
aws s3api get-bucket-replication --bucket [각자 접두사]-crr-source --profile crr-source-admin
5. 결과 확인
5.1. 새 파일 업로드와 복제
두 번째 실습 파일 만들고 업로드
echo "after override" > after-override.txt
aws s3 cp after-override.txt s3://[각자 접두사]-crr-source/after-override.txt --profile crr-source-admin
두 번째 object의 복제 상태 확인
aws s3api head-object --bucket [각자 접두사]-crr-source --key after-override.txt --profile crr-source-admin
Note
ReplicationStatus가PENDING이면 잠시 뒤 같은 명령을 다시 실행합니다.COMPLETED가 나오면 다음 절로 넘어갑니다.
5.2. 대상 계정에서 소유자 비교와 읽기
대상 계정에서 두 object의 소유자 비교
aws s3api list-objects-v2 --bucket [각자 접두사]-crr-dest --fetch-owner --profile crr-dest-admin
두 object의 Owner.ID 앞 4자리를 기록표의 두 canonical user ID와 각각 비교합니다.
대상 계정에서 두 번째 object 내려받기
aws s3api get-object --bucket [각자 접두사]-crr-dest --key after-override.txt ./dest-after.txt --profile crr-dest-admin
5.3. 이전 object 상태 확인
대상 계정에서 첫 번째 object 내려받기 재시도
aws s3api get-object --bucket [각자 접두사]-crr-dest --key before-override.txt ./dest-before.txt --profile crr-dest-admin
Warning 이 절의 명령은 3.3절과 같은 결과를 확인하는 단계입니다.
6. 리소스 정리
6.1. 복제 규칙과 IAM role 삭제
복제 규칙과 복제용 IAM role 삭제
aws s3api delete-bucket-replication --bucket [각자 접두사]-crr-source --profile crr-source-admin
aws iam delete-role-policy --role-name crr-replication-role --policy-name crr-replication-policy --profile crr-source-admin
aws iam delete-role --role-name crr-replication-role --profile crr-source-admin
6.2. bucket 안의 모든 object version 삭제
소스 bucket의 모든 object version 삭제
aws s3api delete-objects --bucket [각자 접두사]-crr-source --delete "$(aws s3api list-object-versions --bucket [각자 접두사]-crr-source --output json --query '{Objects: Versions[].{Key:Key,VersionId:VersionId}}' --profile crr-source-admin)" --profile crr-source-admin
대상 bucket의 모든 object version 삭제
aws s3api delete-objects --bucket [각자 접두사]-crr-dest --delete "$(aws s3api list-object-versions --bucket [각자 접두사]-crr-dest --output json --query '{Objects: Versions[].{Key:Key,VersionId:VersionId}}' --profile crr-dest-admin)" --profile crr-dest-admin
Note 두 명령의
Deleted배열에before-override.txt와after-override.txt가 각각 들어 있으면 bucket이 비워진 상태입니다.
6.3. bucket 삭제
두 bucket 삭제
aws s3api delete-bucket --bucket [각자 접두사]-crr-source --profile crr-source-admin
aws s3api delete-bucket --bucket [각자 접두사]-crr-dest --profile crr-dest-admin
6.4. 삭제 확인
두 계정에 실습 bucket이 남아 있는지 확인
aws s3api list-buckets --query "Buckets[?starts_with(Name, '[각자 접두사]-crr')].Name" --profile crr-source-admin
aws s3api list-buckets --query "Buckets[?starts_with(Name, '[각자 접두사]-crr')].Name" --profile crr-dest-admin
복제용 IAM role이 남아 있는지 확인
aws iam list-roles --query "Roles[?RoleName=='crr-replication-role'].RoleName" --profile crr-source-admin
Note 세 명령이 모두 빈 배열을 돌려주면 정리가 끝난 상태입니다. 이름이 남아 있으면 그 리소스만 6.1이나 6.2로 돌아가 다시 지웁니다.
로컬에 만든 실습 파일 삭제
rm -f crr-trust-policy.json crr-role-policy.json crr-role-policy-override.json before-override.txt after-override.txt dest-after.txt
6.5. CLI profile과 관리 계정 사용자 삭제
~/.aws/credentials파일을 편집기로 엽니다.[crr-lab-admin]으로 시작하는 블록을 지웁니다.~/.aws/config파일을 편집기로 엽니다.[profile crr-lab-admin],[profile crr-source-admin],[profile crr-dest-admin]으로 시작하는 블록을 각각 지웁니다.- 두 파일을 저장합니다.
남아 있는 CLI profile 확인
aws configure list-profiles
Note 목록에
crr-lab-admin,crr-source-admin,crr-dest-admin이 없으면 정리가 끝난 상태입니다. 관리 계정에 root로 로그인한다.
- 브라우저에서 관리 계정 root 탭을 클릭합니다.
- 검색창에
IAM을 입력하고 결과에서IAM을 클릭합니다. - 왼쪽 메뉴에서 Users 를 클릭합니다.
crr-lab-admin왼쪽 체크박스를 클릭합니다.- 오른쪽 위
Delete를 클릭합니다. - 확인 칸에
crr-lab-admin을 입력하고Delete를 클릭합니다.
Note 이 단계만 콘솔에서 진행합니다. IAM 사용자는 자기 access key로 자기를 지울 수 없습니다. 실습 계정 두 개에는 지울 사용자가 없습니다.
6.6. 실습 계정 정리
실습 계정을 다음 챕터에서도 쓸 계획이면 이 절은 건너뜁니다. 6.4절까지 마쳤으면 계정 안에 남은 리소스가 없습니다. 관리 계정에 root로 로그인한다.
- 검색창에
Organizations를 입력하고 결과에서AWS Organizations를 클릭합니다. - 왼쪽 메뉴에서 AWS accounts 를 클릭합니다.
crr-source왼쪽 체크박스를 클릭합니다.- 오른쪽 위
Close를 클릭합니다. - 안내 문구를 읽고 확인 칸에 소스 계정 12자리를 입력한 뒤
Close account를 클릭합니다. - 같은 절차를 반복해
crr-dest계정을 닫습니다.
Warning 닫은 계정은 90일 동안
Suspended상태로 남고 그 뒤 영구 종료됩니다. 90일이 지나면 되돌릴 수 없습니다. 같은 이메일로 다시 계정을 만들 계획이라면 이 절을 건너뜁니다.
여기까지가 이번 실습입니다. 수고하셨습니다.