RDSを利用したECSサーバ基盤

作成日:2021-05-10

RDSを利用したECSサーバ基盤の構築

前述、SLBを利用したECSサーバ基盤の構築が出来たら、今度はこれにRDSをアタッチしてみます。

構成図

  TerraformでデータベースサービスであるRDSを作ってみます。ゴールの構成図は以下の通りです。

図 1

またECSからRDS for MySQLへ接続するためにdocker-composeを使います。docker-composeはコンテナオーケストレーションの一つで、環境構築を再現するのが楽になる手法です。docker-compose.ymlファイルは以下の通りです。

version: '3'
services:
# MySQL
db:
image: mysql:5.7
container_name: mysql_host
environment:
- MYSQL_HOST='rds-sample.mysql.japan.rds.aliyuncs.com'
- MYSQL_DATABASE='rds_setting_sample'
- MYSQL_USER='test_user'
- MYSQL_PASSWORD='!Password2019'
- TZ='Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/db/data:/var/lib/mysql
- ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/db/sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306

パラメータ構成

それぞれのパラメータは以下の通りです。

ネットワーク構成:

リソースリソース名パラメータ必須設定値内容
alicloud_vpcvpcvpc_name任意${var.project_name}-vpcVPC の名称。この例の場合、RDS-Sample-for-Terraform-vpc として表示されます。
vpccidr_block必須192.168.1.0/24VPC の CIDR ブロック
vpcdescription任意Enable SLB-Setteing-Sample vpcVPC の説明。
alicloud_vswitchvswvswitch_name任意${var.project_name}-vswitchvswitch の名称。この例の場合、RDS-Sample-for-Terraform-vswitch として表示されます。
vswvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
vswcidr_block必須192.168.1.0/28vswitch の CIDR ブロック
vswzone_id必須${var.zone}使用するアベイラビリティゾーン
vswdescription任意Enable RDS-Setteing-Sample vswitchvswitch の説明。

ECSインスタンスセキュリティグループ構成:

リソースリソース名パラメータ必須設定値内容
alicloud_security_groupsgname任意${var.project_name}_sg"セキュリティグループ の名称。この例の場合、RDS-Sample-for-Terraform_sgとして表示されます。
sgvpc_id必須${alicloud_vpc.vpc.id}アタッチするVPCのID
sgdescription任意Enable SSH access via port 22セキュリティグループ の説明。
alicloud_security_group_ruleallow_httptype必須ingressセキュリティグループのタイプ。 ingress(受信) かegress(送信) のいずれかになります。
allow_httpip_protocol必須tcp通信プロトコル。 tcp, udp, icmp, gre, all のいずれかになります。
allow_httpnic_type必須intranetネットワークタイプ。 internet か intranet のいずれかになります。
allow_httppolicy必須accept許可ポリシー。 acceptか drop のいずれかになります。
allow_httpport_range必須80⁄80通信プロトコルのポート範囲。値が「- 1/-1」の場合は無効になります。
allow_httppriority必須1許可ポリシーの優先順位。
allow_httpsecurity_group_id必須${alicloud_security_group.sg.id}アタッチするセキュリティグループのID
allow_httpcidr_ip任意0.0.0.0/0ターゲットとなるIPアドレス。デフォルトは「0.0.0.0/0」。値が「0.0.0.0/0」の場合は無制限状態となります。
allow_sshtype必須ingressセキュリティグループのタイプ。 ingress(受信) かegress(送信) のいずれかになります。
allow_sship_protocol必須tcp通信プロトコル。 tcp, udp, icmp, gre, all のいずれかになります。
allow_sshnic_type必須intranetネットワークタイプ。 internet か intranet のいずれかになります。
allow_sshpolicy必須accept許可ポリシー。 acceptか drop のいずれかになります。
allow_sshport_range必須22/22通信プロトコルのポート範囲。値が「- 1/-1」の場合は無効になります。
allow_sshpriority必須1許可ポリシーの優先順位。
allow_sshsecurity_group_id必須${alicloud_security_group.sg.id}アタッチするセキュリティグループのID
allow_sshcidr_ip任意0.0.0.0/0ターゲットとなるIPアドレス。デフォルトは「0.0.0.0/0」。値が「0.0.0.0/0」の場合は無制限状態となります。

ECSインスタンス構成:

リソースリソース名パラメータ必須設定値内容
alicloud_instanceECS_instanceinstance_name任意${var.project_name}-ECS-instanceECSインスタンスの名称。この例の場合、RDS-Sample-for-Terraform-ECS-instance として表示されます。
ECS_instancehost_name任意${var.project_name}-ECS-instanceECSインスタンスのHost名称。この例の場合、RDS-Sample-for-Terraform-ECS-instance として表示されます。
ECS_instanceinstance_type必須ecs.sn1.mediumECSインスタンスのタイプ。今回は ecs.sn1.mediumを選定します。
ECS_instanceimage_id必須centos_7_04_64_20G_alibase_201701015.vhdECSインスタンスのImageID。今回は centos_7_04_64_20G_alibase_201701015.vhd を選定します。
ECS_instancesystem_disk_category任意cloud_efficiencyECSインスタンスのディスクタイプ。デフォルトは cloud_efficiency です。
ECS_instancesecurity_groups必須”${alicloud_security_group.sg.id}”アタッチするセキュリティグループのID
ECS_instanceavailability_zone必須${var.zone}使用するアベイラビリティゾーン
ECS_instancevswitch_id必須${alicloud_vswitch.vsw.id}アタッチするVSwitchのID。
ECS_instancepassword任意"${var.ecs_password}"EC インスタンスのログインパスワード。
ECS_instanceinternet_max_bandwidth_out任意20パブリックネットワークへの最大帯域幅。デフォルトは0ですが、0より大きい値を入れるとパブリックIPアドレスがアタッチされます。
ECS_instanceuser_data任意"${file("provisioning.sh")}"ECSインスタンス起動後に実行するshell内容もしくはファイル名。今回はprovisioning.shにて記載しています。

SLB構成:

リソースリソース名パラメータ必須設定値内容
alicloud_slb_load_balancerdefaultload_balancer_name任意"${var.project_name}-slb"SLBの名称。この例の場合、RDS-Sample-for-Terraform-slb として表示されます。
defaultvswitch_id任意"${alicloud_vswitch.vsw.id}"アタッチするVSwitchのID。
defaultaddress_type必須internetSLB addressのインターネットタイプ。internetのインターネットにするか、intranetのイントラネットいずれかになります。
defaultinternet_charge_type必須paybytrafficインターネットチェンジタイプ。PayByBandwidth、PayByTrafficのいずれかになります。
defaultbandwidth任意5最大帯域幅。
defaultload_balancer_spec任意slb.s2.smallSLBのタイプ。今回は slb.s2.smallを選定します。
alicloud_slb_listenerhttpload_balancer_id必須"${alicloud_slb_load_balancer.slb.id}"新しいリスナーを起動するために使用されるロードバランサID。
httpbackend_port必須80Server Load Balancerインスタンスバックエンドが使用するポート。
httpfrontend_port必須80Server Load Balancerインスタンスフロントエンドが使用するポート。
httphealth_check_connect_port任意80ヘルスチェックが使用するポート。health_check_typeの代わりに使用することも可能です。
httpprotocol必須"http"使用するプロトコル。http、https、tcp、udpのいずれかになります。
httpbandwidth任意10Listenerの最大帯域幅。
httpsticky_session任意"on"セッション持続性を有効にするかどうか。on、offのいずれかになります。
httpsticky_session_type任意"insert"Cookieを処理するためのタイプ。insertかserverのいずれかになります。
httpcookie任意"slblistenercookie"サーバに設定されているクッキー。
httpcookie_timeout任意86400クッキーのタイムアウト時間。
alicloud_slb_attachmentslb_attachmentload_balancer_id必須"${alicloud_slb_load_balancer.slb.id}"ロードバランサID。
slb_attachmentinstance_ids必須"${alicloud_instance.ECS_instance.*.id}"アタッチするECSインスタンスID。

RDS構成:

リソースリソース名パラメータ必須設定値内容
alicloud_db_instancedb_instanceengine必須"MySQL"データベースタイプ。MySQL、SQLServer、PostgreSQL、PPASのいずれかになります。
db_instanceengine_version必須"5.7"データベースのバージョン。
db_instanceinstance_type必須"rds.mysql.t1.small"DBインスタンスタイプ。
db_instanceinstance_storage必須5DBインスタンスのストレージ領域。
db_instancevswitch_id必須"${alicloud_vswitch.vsw.id}"アタッチするVSwitchのID。
db_instancesecurity_ips任意["192.168.1.0/28"]インスタンスのすべてのデータベースにアクセスできるIPアドレスのリスト。今回は 192.168.1.0/28を選定します。
alicloud_db_databasedefaultname必須"${var.database_name}"RDSの名称。この例の場合、RDS-Sample-for-Terraform として表示されます。
defaultinstance_id必須"${alicloud_db_instance.db_instance.id}"データベースを実行するインスタンスのID。
defaultcharacter_set必須"utf8"文字セット。
alicloud_db_accountdefaultdb_instance_id必須"${alicloud_db_instance.db_instance.id}"データベースを実行するインスタンスのID。
defaultaccount_name必須"${var.db_user}"運用アカウント名。
defaultaccount_password必須"${var.db_password}"運用アカウント名に対するパスワード。
alicloud_db_account_privilegedefaultinstance_id必須"${alicloud_db_instance.db_instance.id}"データベースを実行するインスタンスのID。
defaultaccount_name必須"${alicloud_db_account.default.name}"運用アカウント名。
defaultdb_names必須"${alicloud_db_database.default.name}"データベース名。
defaultprivilege必須"ReadWrite"アクセス権限。ReadOnly、ReadWriteのいずれかになります。
alicloud_db_connectiondefaultinstance_id必須"${alicloud_db_instance.db_instance.id}"データベースを実行するインスタンスのID。
defaultconnection_prefix必須"rds-sample"インターネット接続プレフィックス。
defaultport任意"3306"インターネット接続ポート。

ソース

ソースは以下になります。

main.tf

provider "alicloud" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
resource "alicloud_vpc" "vpc" {
vpc_name = "${var.project_name}-vpc"
cidr_block = "192.168.1.0/24"
description = "Enable RDS Setting Sample vpc"
}
resource "alicloud_vswitch" "vsw" {
vswitch_name = "${var.project_name}-vswitch"
vpc_id = "${alicloud_vpc.vpc.id}"
cidr_block = "192.168.1.0/28"
zone_id = "${var.zone}"
description = "Enable RDS Setting Sample vswitch"
}
# DBを作成する
resource "alicloud_db_instance" "db_instance" {
engine = "MySQL"
engine_version = "5.7"
instance_type = "rds.mysql.t1.small"
instance_storage = 5
vswitch_id = "${alicloud_vswitch.vsw.id}"
security_ips = ["192.168.1.0/28"]
}
resource "alicloud_db_database" "default" {
name = "${var.database_name}"
instance_id = "${alicloud_db_instance.db_instance.id}"
character_set = "utf8"
}
resource "alicloud_db_account" "default" {
db_instance_id = "${alicloud_db_instance.db_instance.id}"
account_name = "${var.db_user}"
account_password = "${var.db_password}"
}
resource "alicloud_db_account_privilege" "default" {
instance_id = "${alicloud_db_instance.db_instance.id}"
account_name = "${alicloud_db_account.default.name}"
db_names = ["${alicloud_db_database.default.name}"]
privilege = "ReadWrite"
}
resource "alicloud_db_connection" "default" {
instance_id = "${alicloud_db_instance.db_instance.id}"
connection_prefix = "rds-sample"
port = "3306"
}
resource "alicloud_security_group" "sg" {
name = "${var.project_name}_security_group"
description = "Enable RDS Setting Sample security group"
vpc_id = "${alicloud_vpc.vpc.id}"
}
resource "alicloud_security_group_rule" "allow_ssh" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.sg.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_security_group_rule" "allow_http" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "80/80"
priority = 1
security_group_id = "${alicloud_security_group.sg.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_instance" "ECS_instance" {
instance_name = "${var.project_name}-ECS-instance"
host_name = "${var.project_name}-ECS-instance"
instance_type = "ecs.sn1.medium"
image_id = "centos_7_04_64_20G_alibase_201701015.vhd"
system_disk_category = "cloud_efficiency"
security_groups = ["${alicloud_security_group.sg.id}"]
availability_zone = "${var.zone}"
vswitch_id = "${alicloud_vswitch.vsw.id}"
password = "${var.ecs_password}"
internet_max_bandwidth_out = 20
user_data = "${file("provisioning.sh")}"
}
resource "alicloud_slb_load_balancer" "default" {
load_balancer_name = "${var.project_name}-slb"
vswitch_id = "${alicloud_vswitch.vsw.id}"
address_type = "internet"
internet_charge_type = "paybytraffic"
load_balancer_spec = "slb.s2.small"
bandwidth = 5
}
resource "alicloud_slb_listener" "http" {
load_balancer_id = "${alicloud_slb_load_balancer.default.id}"
backend_port = 80
frontend_port = 80
health_check_connect_port = 80
bandwidth = 10
protocol = "http"
sticky_session = "on"
sticky_session_type = "insert"
cookie = "slblistenercookie"
cookie_timeout = 86400
}
resource "alicloud_slb_attachment" "default" {
load_balancer_id = "${alicloud_slb_load_balancer.default.id}"
instance_ids = ["${alicloud_instance.ECS_instance.id}"]
}
data "template_file" "user_data" {
template = "${file("provisioning.sh")}"
vars = {
DB_HOST_IP = "${alicloud_db_instance.db_instance.connection_string}"
DB_NAME = "${var.database_name}"
DB_USER = "${var.db_user}"
DB_PASSWORD = "${var.db_password}"
}
}

variables.tf

variable "access_key" {}
variable "secret_key" {}
variable "region" {}
variable "zone" {}
variable "project_name" {}
variable "database_name" {}
variable "ecs_password" {}
variable "db_user" {}
variable "db_password" {}

output.tf

output "ECS_instance_ip" {
value = "${alicloud_instance.ECS_instance.*.public_ip}"
}
output "slb_ip" {
value = "${alicloud_slb_load_balancer.default.address}"
}
output "rds_host" {
value = "${alicloud_db_instance.db_instance.connection_string}"
}

confing.tfvars

access_key = "xxxxxxxxxxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxxxxxxxxxx"
region = "ap-northeast-1"
zone = "ap-northeast-1a"
project_name = "RDS-Setting-Sample-for-Terraform"
database_name = "rds_setting_sample"
ecs_password = "!Password2019"
db_user = "test_user"
db_password = "!Password2019"

provisioning.sh

#!/bin/sh
export MYSQL_HOST=${DB_HOST_IP}
export MYSQL_DATABASE=${DB_NAME}
export MYSQL_USER=${DB_USER}
export MYSQL_PASSWORD=${DB_PASSWORD}
sudo yum install -y yum-utils unzip mysql
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum makecache fast
sudo yum install docker-ce
curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
echo "version: '3'" >> docker-compose.yml
echo "services:" >> docker-compose.yml
echo " # MySQL" >> docker-compose.yml
echo " db:" >> docker-compose.yml
echo " image: mysql:5.7" >> docker-compose.yml
echo " container_name: mysql_host" >> docker-compose.yml
echo " environment:" >> docker-compose.yml
echo " - MYSQL_HOST=db_host" >> docker-compose.yml
echo " - MYSQL_DATABASE=db_name" >> docker-compose.yml
echo " - MYSQL_USER=db_user" >> docker-compose.yml
echo " - MYSQL_PASSWORD=db_password" >> docker-compose.yml
echo " - TZ='Asia/Tokyo'" >> docker-compose.yml
echo " command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci" >> docker-compose.yml
echo " volumes:" >> docker-compose.yml
echo " - ./docker/db/data:/var/lib/mysql" >> docker-compose.yml
echo " - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf" >> docker-compose.yml
echo " - ./docker/db/sql:/docker-entrypoint-initdb.d" >> docker-compose.yml
echo " ports:" >> docker-compose.yml
echo " - 3306:3306" >> docker-compose.yml
sed -i "s/=db_host/='$MYSQL_HOST'/g" docker-compose.yml
sed -i "s/=db_name/='$MYSQL_DATABASE'/g" docker-compose.yml
sed -i "s/=db_user/='$MYSQL_USER'/g" docker-compose.yml
sed -i "s/=db_password/='$MYSQL_PASSWORD'/g" docker-compose.yml
sudo service docker start
docker-compose up -d

実行

  ソースの準備ができたら実行します。

terraform init
terraform plan -var-file="confing.tfvars"
terraform apply -var-file="confing.tfvars"

これで完了です。問題なく実行できたら、ECSとSLBそれぞれのIP、DBのhostが表示されます。 DBのhostはECSから手動接続するにあたり必要なのでメモを残してください。

alicloud_db_account_privilege.default: Creation complete after 2m29s (ID: rm-e9b9hkm8u33h8cd3x:test_user:ReadWrite)
alicloud_db_connection.default: Creation complete after 2m32s (ID: rm-e9b9hkm8u33h8cd3x:rds-sample)
data.template_file.user_data: Refreshing state...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
Outputs:
ECS_instance_ip = [
47.74.52.124
]
rds_host = rm-e9b9hkm8u33h8cd3x.mysql.japan.rds.aliyuncs.com
slb_ip = 47.74.1.41
$

それではECSに入り、RDSへ接続してみます。先ほどのDB host名が必要になります。

$ ssh root@47.74.52.124
The authenticity of host '47.74.52.124 (47.74.52.124)' can't be established.
ECDSA key fingerprint is SHA256:XaQ96OPhtGZQPyQXlYin5qF+cqxS2Arle41wTqkOinE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '47.74.52.124' (ECDSA) to the list of known hosts.
root@47.74.52.124's password:
Welcome to Alibaba Cloud Elastic Compute Service !
[root@RDS-Setting-Sample-for-Terraform-ECS-instance ~]#
[root@RDS-Setting-Sample-for-Terraform-ECS-instance ~]# mysql --version
mysql Ver 15.1 Distrib 5.5.60-MariaDB, for Linux (x86_64) using readline 5.1
[root@RDS-Setting-Sample-for-Terraform-ECS-instance ~]#
[root@RDS-Setting-Sample-for-Terraform-ECS-instance ~]#
[root@RDS-Setting-Sample-for-Terraform-ECS-instance ~]# mysql -u test_user -p -h rm-e9b9hkm8u33h8cd3x.mysql.japan.rds.aliyuncs.com
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 51312248
Server version: 5.5.18.1 Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
MySQL [(none)]> exit;
Bye
[root@RDS-Setting-Sample-for-Terraform-ECS-instance ~]#

無事MySQLへ接続できたことを確認できました。

Close

Alibaba Cloudを始めてみましょう

ソフトバンクは、Alibaba Cloudのアカウント開設から、サービス展開までをお手伝いします。
Hatena