3. Amazon RDS の作成
作成
- 作成者: moritalous
- 作成日: 2023/08/14
RDSを作成
参考:Starting an instance database
データベースインスタンスを作成します。
import * as rds from "aws-cdk-lib/aws-rds";
const rdsInstance = new rds.DatabaseInstance(this, 'RdsDBInstance', {
vpc: vpc,
engine: rds.DatabaseInstanceEngine.MYSQL,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
databaseName: 'wordpress'
})
rdsInstance.connections.allowDefaultPortFrom(instance)
最低限の指定を行ってcdk synth
を行ってみると、エラーになります。
Error: There are no 'Private' subnet groups in this VPC. Available types: Isolated,Deprecated_Isolated,Public
これはサブネットのタイプが影響しています。
サブネットの種類は4つあり、3種類に分類されます。
- Public(PUBLIC)
インターネットとやり取りができるサブネット - Private(PRIVATE_WITH_EGRESS / PRIVATE_WITH_NAT)
NAT Gatewayなどを使ってサブネットからインターネット側への通信が可能でインターネットからの通信はできないサブネット - Isolated(PRIVATE_ISOLATED)
インターネットと通信できないサブネット
デフォルトでRDSコンストラクトはPrivateなサブネットに配置する動作ですが、今回のVPCにはNATがないためPrivateタイプのサブネットが存在しません。
かわりにIsolatedタイプのサブネットに配置するよう設定します。
const rdsInstance = new rds.DatabaseInstance(this, 'RdsDBInstance', {
vpc: vpc,
engine: rds.DatabaseInstanceEngine.MYSQL,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
databaseName: 'wordpress',
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
}
})
これでエラーなく、RDSが作成されます。
データベースのマスターユーザーの認証情報が未指定ですが、これらの情報は自動生成され、Secrets Managerに登録されます。
これもベストプラクティスに則った動作です。
課題
RDSを作成してください。
- t2.microタイプ
- MySQL
- データベース名:WordPress
- PRIVATE_ISOLATEDサブネットに配置
- EC2インスタンスからのMySQLのポートの通信を許可
- RDSドメイン名をOutputで出力
回答
bin/handson-cdk.ts
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
// import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as ec2 from "aws-cdk-lib/aws-ec2";
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as rds from "aws-cdk-lib/aws-rds";
export class HandsonCdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// example resource
// const queue = new sqs.Queue(this, 'HandsonCdkQueue', {
// visibilityTimeout: cdk.Duration.seconds(300)
// });
const vpc = new ec2.Vpc(this, "VPC", {
natGateways: 0,
});
const instance = new ec2.Instance(this, 'EC2Instance', {
vpc: vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.latestAmazonLinux2023(),
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC
},
associatePublicIpAddress: true,
instanceName: 'webserver1-user1',
})
instance.connections.allowFromAnyIpv4(ec2.Port.tcp(80))
const asset = new Asset(this, 'Asset', {
path: './asset/install_wordpress.sh'
})
const localPath = instance.userData.addS3DownloadCommand({
bucket: asset.bucket,
bucketKey: asset.s3ObjectKey
})
instance.userData.addExecuteFileCommand({
filePath: localPath
})
asset.grantRead(instance.role)
new cdk.CfnOutput(this, 'EC2PublicIP', {
value: instance.instancePublicIp
})
const rdsInstance = new rds.DatabaseInstance(this, 'RdsDBInstance', {
vpc: vpc,
engine: rds.DatabaseInstanceEngine.MYSQL,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
databaseName: 'wordpress',
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
},
})
rdsInstance.connections.allowDefaultPortFrom(instance)
new cdk.CfnOutput(this, 'RDSDomainName', {
value: rdsInstance.dbInstanceEndpointAddress
})
}
}