본문 바로가기

블로그

LG CNS 기술블로그 DX Lounge에서 최신 IT 소식을 만나보세요!

AWS Ambassador

S3 기능을 활용한 bucket replication

2023.02.01

[ 머리말 ] 

우리는 지난 edition에서 S3 Object 복제를 lambda로 수행하는 방법을 확인했습니다.  이후 S3는 해당 replication 기능을 자체 feature로 흡수했습니다. 하지만, 제가 Lambda 기반에서 구성을 변경하려고 보니 예상보다 쉽지 않은 항목들로 트러블 슈팅에 오랜 시간을 할애했습니다. 그 내용을 공유해 보고자 합니다! 

[ Architecture ]

[ Content ]

1. S3 replication with S3 feature 

Lambda를 통한 S3의 object 복제는 Lambda code 자체를 작성 해야한다는 점부터가 부담으로 다가옵니다.
모두가 코드를 원활하게 쓸 수 있는 것이 아니며 어떻게 얻어낸 코드도 손쉽게 돌아주는 것이 아닙니다.
이런 점에서 S3 replication 기능이 AWS S3 feature로 포함되었다는 것은 매우 반가운 소식입니다. 

얼마나 차이가 발생하는지 보기 위해 우선 lambda 기반의 복제와 S3 replication rules 기반의 복제 시 필요한 것들을 비교해 보겠습니다.

1. Account A, B     :  S3 bucket이 위치한 2개의 다른 Account 
2. IAM                    :  (1) User 와 User에 부여한 권한(permission) 
                                 (2) Service에 할당될 Role과 해당 Role에 부여한 권한(policy) 
3. KMS Key A, B    : CMS으로 생성된 각각의 Bucket을 암호화한 KMS Key 와 Key Policy
4. S3 bucket A, B  : 각 Account 별 생성된 S3 bucket 과 Bucket 별 Policy                     
5. Lambda              : Lambda의 구현과 그를 위한 환경 변수, Log 관리       >> s3 replication 구현 시 불필요 
6. Cloudwatch logs : Lambda의 수행 로그를 기록할 Cloudwatch logs      >> s3 replication 구현 시 불필요

2개의 Account , IAM 설정 , KMS 기반의 S3 암호화 는 동일하나 IAM 의 설정 변경과 S3 설정 변경이 가장 큰 변화입니다! 

2. S3 bucket 생성 및 bucket policy 작성, Versioning의 Enable 

먼저 Bucket을 생성합니다. Account A의 Source bucket – s3-repl-test-src, Account B의 Destination bucket – s3-repl-test-dsc 입니다.

(1) source bucket

(2) destination bucket

(3) AWS KMS

Account A에서 Source / Destination Bucket 암호화를 위한 Key를 생성합니다.

Key Policy는 아래와 같이 설정합니다.

————————————— < Key Policy > ——————————————

{
    “Id”: “key-consolepolicy-3”,
    “Version”: “2012-10-17”,
    “Statement”: [
        {
            “Sid”: “Enable IAM User Permissions”,
            “Effect”: “Allow”,
            “Principal”: {
                “AWS”: “arn:aws:iam::{Account A  ID} :root”
            },
            “Action”: “kms:“,             “Resource”: “
        },
        {
            “Sid”: “Allow use of the key”,
            “Effect”: “Allow”,
            “Principal”: {
                “AWS”: [
                    “arn:aws:iam::{Account B ID}:root”    –>  Tips! – Account B에 사용 권한을 부여하는 것이 아닙니다. 
                ]                                                                               Account B의 IAM을 통해, key policy의 Action에 정의된 권한을 활용할 수 있는 것입니다.
            },
            “Action”: [
                “kms:Encrypt”,
                “kms:Decrypt”,
                “kms:ReEncrypt“,                 “kms:GenerateDataKey“,
                “kms:DescribeKey”
            ],
            “Resource”: “”         },         {             “Sid”: “Allow attachment of persistent resources”,             “Effect”: “Allow”,             “Principal”: {                 “AWS”: [                     “arn:aws:iam::{Account B ID}:root”                 ]             },             “Action”: [                 “kms:CreateGrant”,                 “kms:ListGrants”,                 “kms:RevokeGrant”             ],             “Resource”: ““,
            “Condition”: {
                “Bool”: {
                    “kms:GrantIsForAWSResource”: “true”
                }
            }
        }
    ]
}


(4) Replication 구성  

S3 > Management > Replication rules에서 설정이 가능합니다. 
    Source bucket , Apply to all objects in the bucket 
    Destination bucket , Specify a bucket in another acocunt 

* Tips!         

Replication 구성을 위해선 source / destination 양쪽 버킷 모두 versioning이 다 enable 되어야 합니다. 아래 이미지와 같이 Enable 되지 않으면 경고 메시지가 발생합니다.

  Encryption : Replicate object encrypted with AWS KMS 
    보안을 위해서 파일 이동 시 암호화 조건을 활성화 시키는 것이 좋습니다. 

    AWS KMS key for encryption destiation object > 같은 계정안에 key가 있다면 choose from your AWS KMS keys이 가능하지만
    타 계정에 있는 경우 AWS KMS key ARN에 입력하면 됩니다

    IAM Role은 Create new role을 선택합니다.

*Tips!

KMS의 암호화 Key를 선택함에 있어 어떤 키를 써야 할까요?
source bucket 암호화키? destination bucket암호화 키?를 고민하실 것입니다. 위에 답이 나와 있습니다.
encryption destination object 이니 destination의 key 값을 입력하면 됩니다. 

그 외에도 제공하는 중요한 4가지 기능이 있습니다. 

Replication Time Control (RTC) , Replication metrics and notifications , Delete marker replication , Replica modification sync입니다. 
각 항목은 object의 복제 중요도 및 각 요구 조건에 맞춰서 설정할 수 있으며 반드시 적용 필요 여부의 검토가 필요합니다.

참고 : https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication-walkthrough-5.html

3. IAM의 차이

S3 replication 구성 시 필요한 IAM role은 “service role”입니다. 이것이 어떤 특징을 가지고 있는지는 IAM Rule을 다룬 Blog에서 설명드린 바 있습니다.

특징을 다시 한번 강조합니다. 

AWS service role : AWS Service가 특정 권한을 사용할 수 있도록 만들어진 Role입니다.
                               일반적으로 AWS Service를 구축할 때 IAM 항목에서 서비스가 사용할 수 있는 권한을 부여하고 그때 사용되는 role입니다.
                               Create a Role을 선택하면 AWS 내부적으로 신규로 생성되며 서비스가 정상적으로 작동하기 위한 필요 권한을 모두 보유하게 됩니다.

** Tips!!

IAM 콘솔에서 3번 service role은 수동 생성이 불가능하고, AWS 서비스 배포 시 Create Role 을 통해 AWS 직접 생성 방식으로 만들어야 합니다. 한번 생성 한 후에 남아 있는 role을 지정하여 권한을 부여할 수 있습니다. 수동 생성이 어려운 만큼, 선택할 수 있는 방식은 먼저 실제 replication의 동작 여부와 관련 없이 위 작업을 통해 replication 작업을 완료하여 Role 생성을 완료한 다음, 해당 Role에 bucket을 암호화한 KMS에 대한 권한을 추가해야 합니다.
    
Create a Role을 통해 생성한 policy는 아래와 같습니다.

—————————————- < IAM Policy  > ——————————————

{
    “Version”: “2012-10-17”,
    “Statement”: [
        {
            “Action”: [
                “s3:ListBucket”,
                “s3:GetReplicationConfiguration”,
                “s3:GetObjectVersionForReplication”,
                “s3:GetObjectVersionAcl”,
                “s3:GetObjectVersionTagging”,
                “s3:GetObjectRetention”,
                “s3:GetObjectLegalHold”
            ],
            “Effect”: “Allow”,
            “Resource”: [
                “arn:aws:s3:::SOURCE_BUCKET_NAME”,
                “arn:aws:s3:::SOURCE_BUCKET_NAME/”,                
“arn:aws:s3:::DESTINATION_BUCKET_NAME”,                
“arn:aws:s3:::DESTINATION_BUCKET_NAME/”
            ]
        },
        {
            “Action”: [
                “s3:ReplicateObject”,
                “s3:ReplicateDelete”,
                “s3:ReplicateTags”,
                “s3:ObjectOwnerOverrideToBucketOwner”
            ],
            “Effect”: “Allow”,
            “Condition”: {
                “StringLikeIfExists”: {
                    “s3:x-amz-server-side-encryption”: [
                        “aws:kms”,
                        “AES256”
                    ]
                }
            },
            “Resource”: [
                “arn:aws:s3:::DESTINATION_BUCKET_NAME/*”
            ]
        },
    * Tips! – 아래는 Role- Policy 가 1차로 생성된 이후, 매뉴얼로 inline 형태로 추가된 항목 
        {
            “Action”: [
                “kms:Encrypt”,
                “kms:Decrypt”,
            ],
            “Effect”: “Allow”,
            “Resource”: [
                “SOURCE_BUCKET_ENCRYPTION_KMS_ARN”, 
                “DESTINATION_BUCKET_ENCRYPTION_KMS_ARN”  
            ]
        }
    ]

4.  Destination bucket policy

Destination Bucket에선 해당 Role이 object를 저장할 수 있도록 Bucket Policy를 통해 권한을 부여해야합니다. 

—————————————- < Destination Bucket Policy > —————————————————————–

        {
            “Sid”: “Set permissions for objects”,
            “Effect”: “Allow”,
            “Principal”: {
                “AWS”: [    ——–> 각 생성된 role을 넣어야 한다
                    “arn:aws:iam::SOURCE_ACCOUNT_ID:role/service-role/ROLE_NAME”
                ]
            },
            “Action”: [
                “s3:ReplicateObject”,
                “s3:ReplicateDelete”
            ],
            “Resource”: “arn:aws:s3:::DESTINATION_BUCKET_NAME/”         },         {             “Sid”: “Set permissions on bucket”,             “Effect”: “Allow”,             “Principal”: {                 “AWS”: [                     “arn:aws:iam::SOURCE_ACCOUNT_ID:role/service-role/ROLE_NAME”                 ]             },             “Action”: [                 “s3:List“,
                “s3:GetBucketVersioning”,
                “s3:PutBucketVersioning”
            ],
            “Resource”: “arn:aws:s3:::DESTINATION_BUCKET_NAME”
        },
        {
            “Sid”: “1”,                         > Tips! – 이 건은 bucket replicatation 구현 시, Ownership을 변경할 경우 추가해야 하는 항목입니다. 
            “Effect”: “Allow”,                             아래 Principal이 위에선 Role이지만 아래에선 root라는 점을 체크해 주십시오
            “Principal”: {
                “AWS”: [
                    “arn:aws:iam::SOURCE_ACCOUNT_ID:root”
                ]
            },
            “Action”: “s3:ObjectOwnerOverrideToBucketOwner”,
            “Resource”: “arn:aws:s3:::DESTINATION_BUCKET_NAME/*”
        }     


해당 구성이 완료되고 나면 아래와 같이 화면을 확인하실 수 있습니다. 

이후 Source Bucket에 Object를 업로드한 후, 해당 object를 클릭하면 replication 상태 확인을 할 수 있습니다. 

>정상 복제가 되지 않으면, COMPLETED가 아닌 FAILED가 됩니다.

Destination Bucket의 Object를 클릭하시면 아래와 같이 표현됩니다.

>REPLICA라고 표시됩니다. 

이 내용만 보시면 쉽게 설정할 수 있을 것 같지만 KMS Policy, IAM Role – Policy, Bucket Policy 등 매뉴얼로 설정해야 하는 값이 많으며, Allow 정책을 타이트하게 가져갈 수록 수많은 적용 에러가 발생할 수 있습니다.


[ 결론 ] 

람다의 코드 작성과 그 외 추가적인 구성 없이도 성공적으로 s3 replication을 구성할 수 있다는 점에서 해당 기능이 S3 기본 기능에 추가된 것은 아주 훌륭하다고 평가하고 싶습니다. 단, 많은 설정이 연계되어 있는 만큼, 그저 구성을 성공하겠다는 욕심으로 과다한 권한을 부여하는 것을 주의해 주십시오! 또한 설명은 하지 않았지만 RTC와 같은 기능은 오브젝트가 정상적으로 복제되었음을 확실히 할 수 있는 중요한 기능입니다. 기능에 대한 정의를 꼭 참고해 주십시오!

챗봇과 대화를 할 수 있어요