この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
今回は RDS の Aurora DB クラスターを作成します。
クラスターの作成のみで DB インスタンスは作りません。(こいつは次回)
前回の記事はこちら。
AWS 構成図
設計
プロパティは以下の通り。
devio-stg-rds-cluster
項目 | 値 |
---|---|
DB クラスター ID | devio-stg-rds-cluster |
エンジン | Aurora MySQL |
エンジンバージョン | 5.7.mysql_aurora.2.10.0 |
キャパシティータイプ | プロビジョニング済み: シングルマスター |
DB 名 | devio |
マスターユーザー名 | admin(Secrets Manager から取得) |
マスターパスワード | Secrets Manager で自動生成 |
暗号化 | 有効 |
ログエクスポート | CloudWatch Logs: エラーログ |
メンテナンスウィンドウ | 月曜 4:30-5:00 JST(日曜 19:30-20:00 UTC) |
自動バックアップ | 有効(7 日) |
バックアップウィンドウ | 4:00-4:30 JST(19:00-19:30 UTC) |
サブネットグループ | devio-stg-rds-sng |
クラスターパラメータグループ | 前回作ったやつ |
VPC セキュリティグループ | devio-stg-sg-rds |
データベースポート | 3306 |
実装
RDS に関する処理を行うクラスに、ハイライト部分を追記しました。
lib/resource/rds.ts
import * as cdk from '@aws-cdk/core';
import { CfnDBSubnetGroup, CfnDBClusterParameterGroup, CfnDBParameterGroup, CfnDBCluster } from '@aws-cdk/aws-rds';
import { CfnSubnet, CfnSecurityGroup } from '@aws-cdk/aws-ec2';
import { CfnSecret } from '@aws-cdk/aws-secretsmanager';
import { Resource } from './abstract/resource';
import { SecretsManager, OSecretKey } from './secretsManager';
export class Rds extends Resource {
public dbCluster: CfnDBCluster;
private readonly subnetDb1a: CfnSubnet;
private readonly subnetDb1c: CfnSubnet;
private readonly securityGroupRds: CfnSecurityGroup;
private readonly secretRdsCluster: CfnSecret;
private static readonly databaseName = 'devio';
constructor(
subnetDb1a: CfnSubnet,
subnetDb1c: CfnSubnet,
securityGroupRds: CfnSecurityGroup,
secretRdsCluster: CfnSecret
) {
super();
this.subnetDb1a = subnetDb1a;
this.subnetDb1c = subnetDb1c;
this.securityGroupRds = securityGroupRds;
this.secretRdsCluster = secretRdsCluster;
};
createResources(scope: cdk.Construct) {
const subnetGroup = this.createSubnetGroup(scope);
const clusterParameterGroup = this.createClusterParameterGroup(scope);
const parameterGroup = this.createParameterGroup(scope);
this.dbCluster = this.createCluster(scope, subnetGroup, clusterParameterGroup);
}
private createSubnetGroup(scope: cdk.Construct): CfnDBSubnetGroup {
const subnetGroup = new CfnDBSubnetGroup(scope, 'RdsDbSubnetGroup', {
dbSubnetGroupDescription: 'Subnet Group for RDS',
subnetIds: [this.subnetDb1a.ref, this.subnetDb1c.ref],
dbSubnetGroupName: this.createResourceName(scope, 'rds-sng')
});
return subnetGroup;
}
private createClusterParameterGroup(scope: cdk.Construct): CfnDBClusterParameterGroup {
const clusterParameterGroup = new CfnDBClusterParameterGroup(scope, 'RdsDbClusterParameterGroup', {
description: 'Cluster Parameter Group for RDS',
family: 'aurora-mysql5.7',
parameters: { time_zone: 'UTC' }
});
return clusterParameterGroup;
}
private createParameterGroup(scope: cdk.Construct): CfnDBParameterGroup {
const parameterGroup = new CfnDBParameterGroup(scope, 'RdsDbParameterGroup', {
description: 'Parameter Group for RDS',
family: 'aurora-mysql5.7'
});
return parameterGroup;
}
private createCluster(scope: cdk.Construct, subnetGroup: CfnDBSubnetGroup, clusterParameterGroup: CfnDBClusterParameterGroup): CfnDBCluster {
const cluster = new CfnDBCluster(scope, 'RdsDbCluster', {
engine: 'aurora-mysql',
backupRetentionPeriod: 7,
databaseName: Rds.databaseName,
dbClusterIdentifier: this.createResourceName(scope, 'rds-cluster'),
dbClusterParameterGroupName: clusterParameterGroup.ref,
dbSubnetGroupName: subnetGroup.ref,
enableCloudwatchLogsExports: ['error'],
engineMode: 'provisioned',
engineVersion: '5.7.mysql_aurora.2.10.0',
masterUserPassword: SecretsManager.getDynamicReference(this.secretRdsCluster, OSecretKey.MasterUserPassword),
masterUsername: SecretsManager.getDynamicReference(this.secretRdsCluster, OSecretKey.MasterUsername),
port: 3306,
preferredBackupWindow: '19:00-19:30',
preferredMaintenanceWindow: 'sun:19:30-sun:20:00',
storageEncrypted: true,
vpcSecurityGroupIds: [this.securityGroupRds.attrGroupId]
});
return cluster;
}
}
事前に Secrets Manager で作成しておいた マスターユーザー名
と マスターパスワード
を以下のコードでクラスターのプロパティに設定しています。
masterUserPassword: SecretsManager.getDynamicReference(this.secretRdsCluster, OSecretKey.MasterUserPassword),
masterUsername: SecretsManager.getDynamicReference(this.secretRdsCluster, OSecretKey.MasterUsername),
[お詫び]
一貫性を保つため、これまでに作成した RDS 関連リソースの 論理 ID
と リソース名
を変更しました。
前回までの表記と異なる部分がありますのでご注意ください。すみませんが 最新のソースコード を 正 とさせてください。
変更箇所は こちら です。
メインのプログラムはこちら。
ハイライト部分を追記しました。
lib/devio-stack.ts
~ 省略 ~
export class DevioStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
~ 省略 ~
// RDS
const rds = new Rds(
subnet.db1a,
subnet.db1c,
securityGroup.rds,
secretsManager.secretRdsCluster
);
rds.createResources(this);
}
}
セキュリティグループと Secrets Manager の Cfn インスタンスを Rds クラスのコンストラクタに追加で渡しています。
テスト
テストコードはこちら。
ハイライト部分を追記しました。
test/resource/rds.test.ts
import { expect, countResources, haveResource, anything } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';
import * as Devio from '../../lib/devio-stack';
test('Rds', () => {
const app = new cdk.App();
const stack = new Devio.DevioStack(app, 'DevioStack');
expect(stack).to(countResources('AWS::RDS::DBSubnetGroup', 1));
expect(stack).to(haveResource('AWS::RDS::DBSubnetGroup', {
DBSubnetGroupDescription: 'Subnet Group for RDS',
SubnetIds: anything(),
DBSubnetGroupName: 'undefined-undefined-rds-sng'
}));
expect(stack).to(countResources('AWS::RDS::DBClusterParameterGroup', 1));
expect(stack).to(haveResource('AWS::RDS::DBClusterParameterGroup', {
Description: 'Cluster Parameter Group for RDS',
Family: 'aurora-mysql5.7',
Parameters: { time_zone: 'UTC' }
}));
expect(stack).to(countResources('AWS::RDS::DBParameterGroup', 1));
expect(stack).to(haveResource('AWS::RDS::DBParameterGroup', {
Description: 'Parameter Group for RDS',
Family: 'aurora-mysql5.7'
}));
expect(stack).to(countResources('AWS::RDS::DBCluster', 1));
expect(stack).to(haveResource('AWS::RDS::DBCluster', {
Engine: 'aurora-mysql',
BackupRetentionPeriod: 7,
DatabaseName: 'devio',
DBClusterIdentifier: 'undefined-undefined-rds-cluster',
DBClusterParameterGroupName: anything(),
DBSubnetGroupName: anything(),
EnableCloudwatchLogsExports: ['error'],
EngineMode: 'provisioned',
EngineVersion: '5.7.mysql_aurora.2.10.0',
MasterUsername: anything(),
MasterUserPassword: anything(),
Port: 3306,
PreferredBackupWindow: '19:00-19:30',
PreferredMaintenanceWindow: 'sun:19:30-sun:20:00',
StorageEncrypted: true,
VpcSecurityGroupIds: anything()
}));
});
以下を確認しています。
- DB クラスターのリソースが 1 つあること
- リソースのプロパティが正しいこと
確認
マネジメントコンソール上でリソースを確認してみましょう。
クラスターが作成されております。
インスタンスが紐付いていないのでエンドポイントのステータスは 作成中
ですが、こちらはインスタンスを作成すれば 利用可能
になるはずです。
設定したプロパティも正しく反映されています。
Secrets Manager から取得した マスターユーザー名
と マスターパスワード
も問題ありません。
ヨシ!
CloudFormation 版
今回のコードを CFn で書くと以下のようになります。
RdsDbCluster:
Type: AWS::RDS::DBCluster
Properties:
Engine: aurora-mysql
BackupRetentionPeriod: 7
DatabaseName: devio
DBClusterIdentifier: devio-stg-rds-cluster
DBClusterParameterGroupName:
Ref: RdsDbClusterParameterGroup
DBSubnetGroupName:
Ref: RdsDbSubnetGroup
EnableCloudwatchLogsExports:
- error
EngineMode: provisioned
EngineVersion: 5.7.mysql_aurora.2.10.0
MasterUsername:
Fn::Join:
- ""
- - "{{resolve:secretsmanager:"
- Ref: SecretRdsCluster
- :SecretString:MasterUsername}}
MasterUserPassword:
Fn::Join:
- ""
- - "{{resolve:secretsmanager:"
- Ref: SecretRdsCluster
- :SecretString:MasterUserPassword}}
Port: 3306
PreferredBackupWindow: 19:00-19:30
PreferredMaintenanceWindow: sun:19:30-sun:20:00
StorageEncrypted: true
VpcSecurityGroupIds:
- Fn::GetAtt:
- SecurityGroupRds
- GroupId
設定したプロパティが多めなのでちょいと長いですね。
GitHub
今回のソースコードは コチラ です。
おわりに
DB クラスターの作成が完了しました。
通常はクラスターのみという構成はなかなかないと思いますが、今回のような単体での作成もできるんですね。
次回はこのクラスターにインスタンスを紐付けていきましょう。