23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
AWS RDS에서 DB 데이터를 다른 계정으로 마이그레이션(cross account migration)을 하는 경우가 가끔 생기게 된다.
이때, 아래 그림과 같이 snapshot에 “Shared with me”를 이용하면 쉽게 마이그레이션 할 수 있다.
하지만, 다른 계정으로 snapshot을 공유할 때 몇가지 사항을 고려해 줘야 한다.
해당 문제들은 주로 AWS RDS의 encrypted와 관련된 것으로 본 기고에서는 RDS의 encryption, AWS KMS 에 대해 정리해 보았다.
기본적으로 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로 구성되어 있다.
위 그림에서 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 을 통해 생성 가능하다)
맨 밑에 보면 “Sharing snapshots encrypted with the default service key for RDS is currently not supported.”로 default service key를 이용해
RDS를 encryption 하는 경우 sharing snapshot이 안된다는 경고 문구와 함께 save가 활성화 되지 않는다.
RDS를 생성할 때, 아래 AWS CDK 코드와 같이 storageEncryptionKey를 custom managed key로 encryption하면 snapshot에 대한 공유가 가능하다.
storageEncryptionKey:new kms.Key(this, 'MyKey', {
alias: `aws/myrds`,
}),하지만, 이렇게 공유만 한다고해서 해당 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에서 확인 가능하며 수정도 가능하다.
{
"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을 이용해 다른 계정에 공유하고, 배포할 수 있게 된다.
그러면, 처음 DB를 생성할때 default key를 사용한 DB는 snapshot 공유를 할 수 없을까? 가능하다. snapshot에서 복사본을 생성하고, 복사본 생성하면서 키를 대체하면 공유가 가능하다[3].
즉, default key를 사용한 DB의 snapshot을 만들고, RDS→Snapshots→Copy snapshot을 클릭하면 아래와 같이 Encryption에서 default가 아닌 다른 키를 이용해 snapshot을 복사할 수 있다.
이 경우에는 문제없이 snapshot을 다른 계정으로 공유가 가능하고, 위에서 설명한 해당 key를 사용할 수 있는 권한을 설정해 주면 문제없이 동작한다.
아래는 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로 마이그레이션 하면서 생긴 문제와 해결 방법들을 중심으로 정리하였다.
시간이 되면 상용에서 발생한 이벤트를 중심으로 정리해 보려 한다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.