데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      계정간 Migration 방법 I : AWS RDS 스냅샷

      JIK 23.05.25
      3,094 17 0

      글 기고서를 시작하며!

      AWS RDS에서 DB 데이터를 다른 계정으로 마이그레이션(cross account migration)을 하는 경우가 가끔 생기게 된다.

      이때, 아래 그림과 같이 snapshot에 “Shared with me”를 이용하면 쉽게 마이그레이션 할 수 있다.

      image1.png

      하지만, 다른 계정으로 snapshot을 공유할 때 몇가지 사항을 고려해 줘야 한다.

      해당 문제들은 주로 AWS RDS의 encrypted와 관련된 것으로 본 기고에서는 RDS의 encryption, AWS KMS 에 대해 정리해 보았다.

      AWS RDS의 Encryption 방식

      기본적으로 AWS RDS는 MFA(multi-factor authentication)를 이용한 접근 제한이나 CloudTrail을 이용한 로깅 방법, 접근을 위한 SSL/TLS 등 DB 내 데이터를 보호하기 위하여 다양한 보안 체계를 구성하고 있다 [1].

      그 중 AWS 서비스 안에서 데이터의 보안 컨트롤이 가능하도록 encryption solution을 이용하며, 이를 위해 AWS KMS (Key Management Service)를 활용한다 [2].

      AWS KMS의 Key는 DB 인스턴스의 백업이나 snapshot, 모든 로그를 encrytion하기 위해 사용되며, 아래 그림과 같이 AWS managed keys와 Customer managed keys로 구성되어 있다.

      image2.png

      위 그림에서 AWS managed key는 우리가 아는 AWS 서비스의 encryption을 위해 다양한 key를 디폴트로 정의하고 있다.

      아래 정의는 AWS CDK의 serverless RDS를 생성할 때 storageEncryptionKey 대한 것으로 기본적으로 default master key를 활용하여 encyption을 진행한다.

      즉, 위 그림의 aws/rds aliases key를 기반으로 encyption을 한다는 의미이다.

      (property) ServerlessClusterProps.storageEncryptionKey?: cdk.aws_kms.IKey | undefined
      The KMS key for storage encryption.
      
      @default
      
      - the default master key will be used for storage encryption

      따라서, storageEncryptionKey를 설정하지 않았을때 default master key를 이용해 encryption을 진행한다.

      하지만, RDS를 default key를 이용해 생성하면, 해당 스냅샷으로 share snapshot을 진행하는 경우 아래와 같이 snapshot 공유가 되지 않는다.

      (참고로, snapshot 생성은 AWS RDS에 Databases에서 Actions->Take snapshot 을 통해 생성 가능하다)

      image3.png

      맨 밑에 보면 “Sharing snapshots encrypted with the default service key for RDS is currently not supported.”로 default service key를 이용해

      RDS를 encryption 하는 경우 sharing snapshot이 안된다는 경고 문구와 함께 save가 활성화 되지 않는다.

      권한을 고려한 custom key로 AWS RDS 생성하기

      RDS를 생성할 때, 아래 AWS CDK 코드와 같이 storageEncryptionKey를 custom managed key로 encryption하면 snapshot에 대한 공유가 가능하다.

      storageEncryptionKey:new kms.Key(this, 'MyKey', {
              alias: `aws/myrds`,
      }),

      image4.png

      하지만, 이렇게 공유만 한다고해서 해당 snapshot을 통해 다른 계정에서 배포하는게 잘 안된다.

      이유는 KMS 권한 때문에 문제가 생기게 된다. 따라서, 위 코드에서 아래 policy를 추가해 줘야 한다.

      storageEncryptionKey:new kms.Key(this, 'MyKey', {
              alias: `aws/myrds`,
              policy: new iam.PolicyDocument({
                statements: [new iam.PolicyStatement({
                  actions: [
                    "kms:*"
                  ],
                  principals: [new iam.AccountRootPrincipal()],
                  resources: ['*'],
                }),
                new iam.PolicyStatement({
                  actions: [
                    "kms:Encrypt",
                    "kms:Decrypt",
                    "kms:ReEncrypt*",
                    "kms:GenerateDataKey*",
                    "kms:CreateGrant",
                    "kms:ListGrants",
                    "kms:DescribeKey"
                  ],
                  principals: [
                    new iam.AccountPrincipal("1054xxxxxxx"),
                    new iam.AccountPrincipal("6726xxxxxxx"),
                    new iam.ArnPrincipal("arn:aws:iam::6726xxxxxxx:role/cdk-hnb659fds-cfn-exec-role-6726xxxxxxx-ap-northeast-2")
                  ],
                  resources: ['*'],
                })],
              })
            }),

      위 경우는 snapshot을 이용하여 RDS를 생성하는 두가지 권한을 포함하고 있다.

      먼저, IAM user가 공유된 snapshot을 이용하는 경우 AccountPrincipal()을 통해 사용자 account ID(1054xxxxxxx와 6726xxxxxxx)를 추가해야 한다.

      두번째로, AWS CDK를 이용해 snapshot을 이용하는 경우 CDK 를 통해 리소스를 생성하는 권한인

      “cdk-hnb659fds-cfn-exec-role-6726xxxxxxx-ap-northeast-2” (account ID: 6726xxxxxxx, region: ap-northeast-2)를 추가해 줘야 한다.

      위 스크립트를 통해 생성된 권한은 아래 그림과 같이 KMS에서 확인 가능하며 수정도 가능하다.

      image5.png

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": "arn:aws:iam::0346xxxxxxx:root"
                  },
                  "Action": "kms:*",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Principal": {
                      "AWS": [
                          "arn:aws:iam::1054xxxxxxx:root",
                          "arn:aws:iam::6726xxxxxxx:root",
                          "arn:aws:iam::6726xxxxxxx:role/cdk-hnb659fds-cfn-exec-role-6726xxxxxxx-ap-northeast-2"
                      ]
                  },
                  "Action": [
                      "kms:Encrypt",
                      "kms:Decrypt",
                      "kms:ReEncrypt*",
                      "kms:GenerateDataKey*",
                      "kms:CreateGrant",
                      "kms:ListGrants",
                      "kms:DescribeKey"
                  ],
                  "Resource": "*"
              }
          ]
      }

      RDS 를 생성할 때 default key가 아닌 custum key를 이용해 encryption을 했을 때, 아래 그림과 같이 snapshot을 이용해 다른 계정에 공유하고, 배포할 수 있게 된다.

      image1.png

      default key를 사용한 DB 계정간 마이그레이션 방법

      그러면, 처음 DB를 생성할때 default key를 사용한 DB는 snapshot 공유를 할 수 없을까? 가능하다. snapshot에서 복사본을 생성하고, 복사본 생성하면서 키를 대체하면 공유가 가능하다[3].

      즉, default key를 사용한 DB의 snapshot을 만들고, RDS→Snapshots→Copy snapshot을 클릭하면 아래와 같이 Encryption에서 default가 아닌 다른 키를 이용해 snapshot을 복사할 수 있다.

      image8.png

      이 경우에는 문제없이 snapshot을 다른 계정으로 공유가 가능하고, 위에서 설명한 해당 key를 사용할 수 있는 권한을 설정해 주면 문제없이 동작한다.

      snapshot을 이용한 serverless RDS 배포 방법

      아래는 snapshot을 통한 serverless RDS를 배포하는 AWS CDK 코드이다.

      const sg = new ec2.SecurityGroup(this, 'RdsSecurityGroup', {
            vpc,
            description: `SG for db`,
            allowAllOutbound: true,
            securityGroupName: `sg-db`,
          });
      
          // inbound rule to connect RDS with 3306 port for same vpc
          sg.addIngressRule(
            ec2.Peer.ipv4(vpc.vpcCidrBlock), 
            ec2.Port.tcp(3306), 
          );
      
      new rds.ServerlessClusterFromSnapshot(this, `RdsServerlessCluster`, {
            engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
            vpc,
            credentials: rds.SnapshotCredentials.fromGeneratedSecret('mysqladmin'),
            scaling: {
              autoPause: cdk.Duration.minutes(0),
              minCapacity: rds.AuroraCapacityUnit.ACU_2,
              maxCapacity: rds.AuroraCapacityUnit.ACU_8,
            },
            clusterIdentifier: `db`,
            snapshotIdentifier: "arn:aws:rds:ap-northeast-2:0346xxxxxxx:cluster-snapshot:db-snapshot"",
            parameterGroup: new rds.ParameterGroup(this, `RdsParamGroup`, {
      	        description: `Parameter Group for db`,
      	        engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
      	        parameters: {
      	          lc_time_names: "ko_KR",
      	          time_zone: "Asia/Seoul",
      	          lower_case_table_names: "1",
      	          innodb_file_per_table: "1",
      	          character_set_server: "utf8mb4",
      	          collation_server: "utf8mb4_unicode_ci",
      	        },
      	      },
      	    ),
            securityGroups: [sg],
            vpcSubnets: vpc.selectSubnets({
              subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS
            }),
            removalPolicy: cdk.RemovalPolicy.SNAPSHOT
          });

      RDS Serverless를 생성하기 위해 security group과 parameter group을 생성해야 된다.

      security group은 VPC내 리소스만 접근 가능하도록 vpcCidrBlock으로 설정하였고, RDS port는 MySQL 기본 포트인 3306으로 설정 하였다.

      parameter group은 RDS DB의 설정 파라미터로 타임존과 캐릭터 등을 설정하기 위해 정의한다.

      스냅샷을 받아오기 위해 snapshotIdentifier를 설정하는데, 해당 값은 원래 snapshot name으로 설정하면 된다.

      하지만 계정간 스냅샷을 받아오는 경우에는 arn을 전부 넣어야 동작하게 된다.

      정리하며!

      본 기고글에서는 AWS RDS를 계정간 마이그레이션 하는 방법을 정리 하였다.

      기본적으로 Snapshot을 가져와 serverless DB를 생성하는 방법으로 DB의 Encryption과 관련된 KMS에 관해 소개하였다.

      KMS의 default key를 이용하는 경우 계정간 공유가 안되기 때문에 custom key를 이용해 encryption 하는 방법과

      만약 default key를 이용해 DB를 생성한 경우에도 snapshot 복사를 이용해 계정간 마이그레이션이 가능한 방법을 소개하였다.

      참고로 해당 내용은 클라우드 인코더 과제에서 상용 계정에서 신규 상용 계정 DB로 마이그레이션 하면서 생긴 문제와 해결 방법들을 중심으로 정리하였다.

      시간이 되면 상용에서 발생한 이벤트를 중심으로 정리해 보려 한다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      JIK 님의 최신 블로그

      더보기
      동영상 기고하기