diff --git a/solution/tech-solution/mysql-rds/README.md b/solution/tech-solution/mysql-rds/README.md new file mode 100644 index 0000000000..e89938c767 --- /dev/null +++ b/solution/tech-solution/mysql-rds/README.md @@ -0,0 +1,49 @@ +## Introduction + +本示例用于实现解决方案[自建数据库迁移到云数据库](https://www.aliyun.com/solution/tech-solution/mysql-rds), 涉及到专有网络(VPC)、交换机(VSwitch)、云服务器(ECS)、云数据库(RDS)MySQL版等资源的部署。 + + + +This example is used to implement solution [Migrate Self-Built Database to Cloud Database](https://www.aliyun.com/solution/tech-solution/mysql-rds), which involves the creation and deployment of resources such as Virtual Private Cloud (VPC), VSwitch, Elastic Compute Service (ECS), ApsaraDB RDS. + + + +## Providers + +| Name | Version | +|------|---------| +| [alicloud](#provider\_alicloud) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [alicloud_db_database.wordpress_db](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_database) | resource | +| [alicloud_db_instance.database](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_instance) | resource | +| [alicloud_ecs_command.wordpress_install_command](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_command) | resource | +| [alicloud_ecs_invocation.wordpress_install_invocation](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_invocation) | resource | +| [alicloud_instance.web_server](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/instance) | resource | +| [alicloud_rds_account.db_user](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/rds_account) | resource | +| [alicloud_security_group.security_group](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group) | resource | +| [alicloud_security_group_rule.security_group_ingress](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource | +| [alicloud_vpc.vpc](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vpc) | resource | +| [alicloud_vswitch.vswitch](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource | +| [alicloud_db_instance_classes.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/db_instance_classes) | data source | +| [alicloud_db_zones.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/db_zones) | data source | +| [alicloud_images.instance_image](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/images) | data source | +| [alicloud_instance_types.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/instance_types) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [db\_instance\_engine\_and\_version](#input\_db\_instance\_engine\_and\_version) | 引擎类型及版本,数据库引擎类型及版本,默认为MySQL 8.0。 | `string` | `"MySQL 8.0"` | no | +| [db\_password](#input\_db\_password) | RDS数据库密码,长度8-30,必须包含三项(大写字母、小写字母、数字、特殊符号)。 | `string` | n/a | yes | +| [db\_user\_name](#input\_db\_user\_name) | RDS数据库账号,由2到16个小写字母组成,下划线。必须以字母开头,以字母数字字符结尾。 | `string` | `"dbuser"` | no | +| [ecs\_instance\_password](#input\_ecs\_instance\_password) | 实例密码,服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、特殊符号)。 | `string` | n/a | yes | +| [region](#input\_region) | 地域 | `string` | `"cn-hangzhou"` | no | + \ No newline at end of file diff --git a/solution/tech-solution/mysql-rds/main.tf b/solution/tech-solution/mysql-rds/main.tf new file mode 100644 index 0000000000..dbaaf599de --- /dev/null +++ b/solution/tech-solution/mysql-rds/main.tf @@ -0,0 +1,172 @@ +data "alicloud_db_zones" "default" { + engine = "MySQL" + engine_version = "8.0" + instance_charge_type = "PostPaid" + category = "Basic" + db_instance_storage_type = "cloud_essd" +} + +# 查询实例实例规格 +data "alicloud_instance_types" "default" { + availability_zone = data.alicloud_db_zones.default.zones.0.id + system_disk_category = "cloud_essd" +} + +data "alicloud_db_instance_classes" "default" { + zone_id = data.alicloud_db_zones.default.zones.0.id + engine = "MySQL" + engine_version = "8.0" + category = "Basic" + instance_charge_type = "PostPaid" + db_instance_storage_type = "cloud_essd" +} + + +# VPC +resource "alicloud_vpc" "vpc" { + vpc_name = "database-migration-test" + cidr_block = "192.168.0.0/16" +} + +# VSwitch +resource "alicloud_vswitch" "vswitch" { + vpc_id = alicloud_vpc.vpc.id + cidr_block = "192.168.0.0/24" + zone_id = data.alicloud_db_zones.default.zones.0.id + vswitch_name = "database-migration-vswitch" +} + +# Security Group +resource "alicloud_security_group" "security_group" { + security_group_name = "SG-DTS-GROUP-20220101" + vpc_id = alicloud_vpc.vpc.id +} + +# Security Group Rule - Allow all traffic +resource "alicloud_security_group_rule" "security_group_ingress" { + security_group_id = alicloud_security_group.security_group.id + type = "ingress" + ip_protocol = "all" + port_range = "-1/-1" + cidr_ip = "0.0.0.0/0" +} + +# Data source for ECS image +data "alicloud_images" "instance_image" { + name_regex = "^aliyun_3_x64_20G_alibase_*" + most_recent = true + owners = "system" + instance_type = data.alicloud_instance_types.default.instance_types[0].id +} + +# ECS Instance (WebServer) +resource "alicloud_instance" "web_server" { + instance_name = "database-migration-webserver" + image_id = data.alicloud_images.instance_image.images[0].id + instance_type = data.alicloud_instance_types.default.instance_types[0].id + security_groups = [alicloud_security_group.security_group.id] + vswitch_id = alicloud_vswitch.vswitch.id + system_disk_category = "cloud_essd" + internet_max_bandwidth_out = 80 + password = var.ecs_instance_password + instance_charge_type = "PostPaid" +} + +# RDS Instance (Database) +resource "alicloud_db_instance" "database" { + engine = "MySQL" + engine_version = "8.0" + instance_type = data.alicloud_db_instance_classes.default.instance_classes.0.instance_class + instance_storage = 20 + vpc_id = alicloud_vpc.vpc.id + vswitch_id = alicloud_vswitch.vswitch.id + security_group_ids = [alicloud_security_group.security_group.id] + security_ips = [alicloud_instance.web_server.private_ip] + zone_id = data.alicloud_db_zones.default.zones.0.id + instance_charge_type = "Postpaid" + category = "Basic" +} + +# RDS Database +resource "alicloud_db_database" "wordpress_db" { + instance_id = alicloud_db_instance.database.id + name = "wordpressdb" + character_set = "utf8mb4" + description = "WordPress database for migration test" +} + +# RDS Account +resource "alicloud_rds_account" "db_user" { + db_instance_id = alicloud_db_instance.database.id + account_name = var.db_user_name + account_password = var.db_password + account_type = "Super" + account_description = "Database user for WordPress" +} + +# Local script for WordPress installation +locals { + wordpress_install_script = <<-SHELL +#!/bin/sh +DatabaseUser='wordpressuser' +DatabasePwd='password' +DatabaseName='wordpressdb' +DatabaseHost='localhost' +yum update -y +yum install -y unzip zip +yum install -y mysql-server +systemctl start mysqld +systemctl enable mysqld +mysql -e "CREATE DATABASE wordpressdb;" +mysql -e "CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'password';" +mysql -e "GRANT ALL PRIVILEGES ON wordpressdb.* TO 'wordpressuser'@'localhost';" +mysql -e "FLUSH PRIVILEGES;" +mysql -e "CREATE USER dtssync1 IDENTIFIED BY 'P@ssw0rd';" +mysql -e "GRANT ALL ON *.* TO 'dtssync1'@'%';" +mysql -e "FLUSH PRIVILEGES;" +mysql -e "SET GLOBAL binlog_format = 'ROW';" +yum install -y nginx +systemctl start nginx +systemctl enable nginx +yum install -y php php-fpm php-mysqlnd +systemctl start php-fpm +systemctl enable php-fpm +cd /usr/share/nginx/html +wget https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20240726/hhvpuw/wordpress-6.6.1.tar +tar -xvf wordpress-6.6.1.tar +cp -R wordpress/* . +rm -R wordpress +cp wp-config-sample.php wp-config.php +sed -i "s/database_name_here/$DatabaseName/" wp-config.php +sed -i "s/username_here/$DatabaseUser/" wp-config.php +sed -i "s/password_here/$DatabasePwd/" wp-config.php +sed -i "s/localhost/$DatabaseHost/" wp-config.php +systemctl restart nginx +systemctl restart php-fpm +SHELL +} + +# ECS Command for WordPress installation +resource "alicloud_ecs_command" "wordpress_install_command" { + name = "wordpress-install-command" + description = "Install WordPress and MySQL on ECS instance" + enable_parameter = false + type = "RunShellScript" + command_content = base64encode(local.wordpress_install_script) + timeout = 3600 + working_dir = "/root" +} + +# Execute command on ECS instance +resource "alicloud_ecs_invocation" "wordpress_install_invocation" { + instance_id = [alicloud_instance.web_server.id] + command_id = alicloud_ecs_command.wordpress_install_command.id + + depends_on = [ + alicloud_security_group_rule.security_group_ingress + ] + + timeouts { + create = "60m" + } +} \ No newline at end of file diff --git a/solution/tech-solution/mysql-rds/outputs.tf b/solution/tech-solution/mysql-rds/outputs.tf new file mode 100644 index 0000000000..0f07ceef8e --- /dev/null +++ b/solution/tech-solution/mysql-rds/outputs.tf @@ -0,0 +1,39 @@ +# ECS Instance Login Information +output "ecs_instance_user" { + description = "Username and password for logging in to ECS instance" + value = "USERNAME: root ; PASSWORD: ${var.ecs_instance_password}" + sensitive = true +} + +# WordPress URL +output "ecs_word_press_url" { + description = "WordPress default address" + value = "http://${alicloud_instance.web_server.public_ip}" +} + +# RDS Internal Connection Address +output "rds_internal_address" { + description = "RDS internal network address" + value = alicloud_db_instance.database.connection_string +} + +# RDS User Information for DTS +output "rds_user_dts" { + description = "RDS username and password for connecting to DTS" + value = "USERNAME: ${var.db_user_name} PASSWORD: ${var.db_password}" + sensitive = true +} + +# WordPress Database User for DTS +output "wp_user_for_dts" { + description = "ECS-hosted database username and password for connecting to DTS" + value = "USERNAME: dtssync1 ; PASSWORD: P@ssw0rd" + sensitive = true +} + +# WordPress Database User for SQL +output "wp_user_for_sql" { + description = "ECS-hosted database username and password for executing SQL" + value = "USERNAME: wordpressuser ; PASSWORD: password" + sensitive = true +} \ No newline at end of file diff --git a/solution/tech-solution/mysql-rds/provider.tf b/solution/tech-solution/mysql-rds/provider.tf new file mode 100644 index 0000000000..5e236864d5 --- /dev/null +++ b/solution/tech-solution/mysql-rds/provider.tf @@ -0,0 +1,3 @@ +provider "alicloud" { + region = var.region +} \ No newline at end of file diff --git a/solution/tech-solution/mysql-rds/variables.tf b/solution/tech-solution/mysql-rds/variables.tf new file mode 100644 index 0000000000..e5af7b0920 --- /dev/null +++ b/solution/tech-solution/mysql-rds/variables.tf @@ -0,0 +1,46 @@ +variable "region" { + description = "地域" + type = string + default = "cn-hangzhou" +} + + +variable "db_instance_engine_and_version" { + type = string + description = "引擎类型及版本,数据库引擎类型及版本,默认为MySQL 8.0。" + validation { + condition = contains(["MySQL 8.0"], var.db_instance_engine_and_version) + error_message = "数据库引擎类型及版本必须为MySQL 8.0。" + } + default = "MySQL 8.0" +} + +variable "db_password" { + type = string + description = "RDS数据库密码,长度8-30,必须包含三项(大写字母、小写字母、数字、特殊符号)。" + sensitive = true + validation { + condition = length(var.db_password) >= 8 && length(var.db_password) <= 30 + error_message = "密码长度必须在8-30之间。" + } +} + +variable "db_user_name" { + type = string + description = "RDS数据库账号,由2到16个小写字母组成,下划线。必须以字母开头,以字母数字字符结尾。" + validation { + condition = can(regex("^[a-z][a-z0-9_]{0,14}[a-z0-9]$", var.db_user_name)) && length(var.db_user_name) >= 2 && length(var.db_user_name) <= 16 + error_message = "由2到16个小写字母组成,下划线。必须以字母开头,以字母数字字符结尾。" + } + default = "dbuser" +} + +variable "ecs_instance_password" { + type = string + description = "实例密码,服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、特殊符号)。" + sensitive = true + validation { + condition = length(var.ecs_instance_password) >= 8 && length(var.ecs_instance_password) <= 30 + error_message = "密码长度必须在8-30之间。" + } +}