Day 18 – 使用 CDK 控制 Relational Database Service(RDS)

2020 12th 鐵人賽

我們 EC2、LB、ASG 與 CloudFront 都說明了剩下一個架站機乎一定要用到的服務還沒講到那就是 AWS 提供的資料庫 RDS

https://i0.wp.com/ithelp.ithome.com.tw/upload/images/20201004/20117701StJQWB7sCd.jpg?w=640&ssl=1

AWS RDS

在 AWS RDS 裡面除了我們常用的 MySQL、MariaDB 與 PostgreSQL 還有 Oracle 與 Microsoft SQL Server 可以選擇,而其實 AWS 還有自己研發一個資料庫叫做 Amazon Aurora Amazon Aurora 的特色是他可以同時相容 MySQL 和 PostgreSQL,官方文件說在速度上比 MySQL 資料庫快五倍的速度,比標準 PostgreSQL 資料庫快三倍的速度而且價格是 1/10

https://i0.wp.com/ithelp.ithome.com.tw/upload/images/20201002/20117701lq8QzcEe9L.png?w=640&ssl=1

建立測試使用的 RDS 機器 MySQL

以網站來說通常比較常使用 MySQL,所以這邊使用 MySQL 做介紹

建立 RDS

首先我們先來理解最簡單建立 RDS 的方法,而且為了方便好測試我們先把它放在 Public Subnet 其實密碼管理在 AWS 比較推薦使用 AWS Secrets Manager,不過這邊因為使用明碼直接說明比較簡單,所以就先直接放入密碼,AWS Secrets Manager 就放到後面的章節說明吧! 千萬要記得正式使用請勿把資料庫放在 Public Subnet

import * as rds from "@aws-cdk/aws-rds";

const rdsSecurityGroup = new ec2.SecurityGroup(this, "RdsSecurityGroup", {
  vpc,
});
rdsSecurityGroup.addIngressRule(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcp(3306),
  "allow public mysql access"
);

const instance = new rds.DatabaseInstance(this, "Database", {
  engine: rds.DatabaseInstanceEngine.mysql({
    version: rds.MysqlEngineVersion.VER_8_0_19,
  }),
  vpc,
  deleteAutomatedBackups: true,
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T3,
    ec2.InstanceSize.MICRO
  ),
  allocatedStorage: 10,
  credentials: {
    username: "admin",
    password: cdk.SecretValue.plainText("password"),
  },
  vpcSubnets: {
    subnetType: ec2.SubnetType.PUBLIC,
  },
  securityGroups: [rdsSecurityGroup],
});

new cdk.CfnOutput(this, "RDS", {
  value: instance.dbInstanceEndpointAddress,
});

使用以上的方法就可以建立一個 MySQL 版本 8.0.19 的資料庫拉!

測試一下

  • CDK output
CdkRdsStack.RDS = cd1c72041shs1y1.cub7t8ijymvz.us-west-2.rds.amazonaws.com
  • 使用指令測試 MySQL 連線
$ mysql -h cd1c72041shs1y1.cub7t8ijymvz.us-west-2.rds.amazonaws.com -u admin -p    1
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 8.0.19 Source distribution

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> quit
Bye

建立正式使用的 RDS 機器

已正式來說比較標準的架構我們會把 RDS 放在 private subnet 畢竟資料庫平常可以存取的只有我們內網的機器可以存取

建立 RDS

以實際使用來說通常會把 EC2 放在 public subnet 而 RDS 放在 private subnet 來保護它,所以我們這次的測試會使用 public 的 EC2 安裝 mysql client 來測試連線 private subnet 的 RDS

const vpc = new ec2.Vpc(this, "VPC", {
  maxAzs: 3,
  natGateways: 1,
});

const mySecurityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
  vpc,
  allowAllOutbound: true,
});
mySecurityGroup.addIngressRule(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcp(22),
  "allow public ssh access"
);

const ec2Instance = new ec2.Instance(this, "Instance", {
  vpc,
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T3,
    ec2.InstanceSize.NANO
  ),
  machineImage: ec2.MachineImage.latestAmazonLinux({
    generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
  }),
  securityGroup: mySecurityGroup,
  vpcSubnets: {
    subnetType: ec2.SubnetType.PUBLIC,
  },
  keyName: "KeyPair",
});
new cdk.CfnOutput(this, "EC2PublicDns", {
  value: ec2Instance.instancePublicDnsName,
});
new cdk.CfnOutput(this, "EC2PublicIp", {
  value: ec2Instance.instancePublicIp,
});

const instance = new rds.DatabaseInstance(this, "Database", {
  engine: rds.DatabaseInstanceEngine.mysql({
    version: rds.MysqlEngineVersion.VER_8_0_19,
  }),
  vpc,
  deleteAutomatedBackups: true,
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T3,
    ec2.InstanceSize.MICRO
  ),
  allocatedStorage: 10,
  credentials: {
    username: "admin",
    password: cdk.SecretValue.plainText("password"),
  },
});
instance.connections.allowFrom(ec2Instance, ec2.Port.tcp(3306));

new cdk.CfnOutput(this, "RDS", {
  value: instance.dbInstanceEndpointAddress,
});

登入 EC2 安裝 MySQL Client 登入測試

  1. 下載 rpm 並且安裝
$ sudo yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
  1. 安裝 MySQL Client
$ sudo yum install -y mysql-community-client
  1. 使用 MySQL Client 連線 RDS
$ mysql -h cd1ayqd9sllf992.cub7t8ijymvz.us-west-2.rds.amazonaws.com -u admin -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 8.0.19 Source distribution

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

以上就可以看到一個比較好的範例

建立測試 RDS 機器使用 Amazon Aurora

建立 RDS

這邊因為目前滿少使用的所以就簡單帶過拉 ~

const cluster = new rds.DatabaseCluster(this, "Database", {
  engine: rds.DatabaseClusterEngine.auroraMysql({
    version: rds.AuroraMysqlEngineVersion.VER_2_09_0,
  }),
  instances: 1,
  instanceProps: {
    instanceType: ec2.InstanceType.of(
      ec2.InstanceClass.BURSTABLE3,
      ec2.InstanceSize.SMALL
    ),
    vpc,
  },
  credentials: {
    username: "admin",
    password: cdk.SecretValue.plainText("password"),
  },
});

new cdk.CfnOutput(this, "RDS", {
  value: cluster.clusterEndpoint.hostname,
});

Amazon Linux 2 科普小教室

  • 如果今天想要在 Amazon Linux 2 裡面安裝 rpm 檔案要怎麼選擇版本呢?

我們可以到看看這份文件 How do I enable the EPEL repository for my Amazon EC2 instance running CentOS, RHEL, or Amazon Linux? 裡面有提到,如果是 Amazon Linux 2 請安裝 RHEL 7 版本

在系統裡面安裝 MySQL Client

以目前 8.0 來說可以先參考文件 Installing MySQL on Linux Using the MySQL Yum Repository 就可以知道怎麼安裝了

簡單處理

  1. 安裝 rpm
$ sudo yum install mysql80-community-release-el7-{version-number}.noarch.rpm
  1. 安裝 MySQL client
$ sudo yum install -y mysql-community-client

今天的說明是 RDS 希望有幫助到大家!