From 2c974a51deb1549417674ef301df51788090c752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=93=E6=BA=AA?= Date: Fri, 10 Oct 2025 11:36:32 +0800 Subject: [PATCH] rocketmq-data-consistency --- .../rocketmq-data-consistency/README.md | 71 ++++ .../rocketmq-data-consistency/main.tf | 310 ++++++++++++++++++ .../rocketmq-data-consistency/outputs.tf | 4 + .../rocketmq-data-consistency/variables.tf | 59 ++++ 4 files changed, 444 insertions(+) create mode 100644 solution/tech-solution/rocketmq-data-consistency/README.md create mode 100644 solution/tech-solution/rocketmq-data-consistency/main.tf create mode 100644 solution/tech-solution/rocketmq-data-consistency/outputs.tf create mode 100644 solution/tech-solution/rocketmq-data-consistency/variables.tf diff --git a/solution/tech-solution/rocketmq-data-consistency/README.md b/solution/tech-solution/rocketmq-data-consistency/README.md new file mode 100644 index 000000000..bc9cce357 --- /dev/null +++ b/solution/tech-solution/rocketmq-data-consistency/README.md @@ -0,0 +1,71 @@ +## Introduction + + +本示例用于实现解决方案[通过RocketMQ事务消息实现分布式事务](https://www.aliyun.com/solution/tech-solution/rocketmq-data-consistency), 涉及到专有网络(VPC)、交换机(VSwitch)、云服务器(ECS)、RAM 用户等资源的创建。 + + + +This example is used to implement solution [RocketMQ Data Consistency](https://www.aliyun.com/solution/tech-solution/rocketmq-data-consistency). It involves the creation, and deployment of resources such as Virtual Private Cloud (VPC), VSwitch, Elastic Compute Service (ECS), and RAM users. + + + +## Providers + +| Name | Version | +|------|---------| +| [alicloud](#provider\_alicloud) | n/a | +| [random](#provider\_random) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [alicloud_db_account_privilege.account_privilege](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/db_account_privilege) | resource | +| [alicloud_db_database.rds_database](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/db_database) | resource | +| [alicloud_db_instance.rds_instance](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/db_instance) | resource | +| [alicloud_ecs_command.run_command_consumer](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ecs_command) | resource | +| [alicloud_ecs_command.run_command_provider](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ecs_command) | resource | +| [alicloud_ecs_invocation.invoke_script_consumer](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ecs_invocation) | resource | +| [alicloud_ecs_invocation.invoke_script_provider](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ecs_invocation) | resource | +| [alicloud_instance.ecs_instance_consumer](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/instance) | resource | +| [alicloud_instance.ecs_instance_provider](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/instance) | resource | +| [alicloud_ram_access_key.ramak](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ram_access_key) | resource | +| [alicloud_ram_user.ram_user](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ram_user) | resource | +| [alicloud_ram_user_policy_attachment.attach_policy_to_user](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/ram_user_policy_attachment) | resource | +| [alicloud_rds_account.rds_account](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rds_account) | resource | +| [alicloud_rocketmq_account.default](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rocketmq_account) | resource | +| [alicloud_rocketmq_acl.consumer_group](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rocketmq_acl) | resource | +| [alicloud_rocketmq_acl.topic1](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rocketmq_acl) | resource | +| [alicloud_rocketmq_consumer_group.consumer_group](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rocketmq_consumer_group) | resource | +| [alicloud_rocketmq_instance.rocketmq](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rocketmq_instance) | resource | +| [alicloud_rocketmq_topic.topic1](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/rocketmq_topic) | resource | +| [alicloud_security_group.security_group](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/security_group) | resource | +| [alicloud_security_group_rule.allow_ssh](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/security_group_rule) | resource | +| [alicloud_security_group_rule.allow_web](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/security_group_rule) | resource | +| [alicloud_vpc.vpc](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/vpc) | resource | +| [alicloud_vswitch.ecs_vswitch](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/vswitch) | resource | +| [alicloud_vswitch.rds_vswitch](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/resources/vswitch) | resource | +| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | +| [alicloud_db_zones.rds_zones](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/data-sources/db_zones) | data source | +| [alicloud_images.default](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/data-sources/images) | data source | +| [alicloud_zones.ecs_zones](https://registry.terraform.io/providers/hashicorp/alicloud/latest/docs/data-sources/zones) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [app\_demo\_password](#input\_app\_demo\_password) | 请输入登录应用演示账户的密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()\_+-=)。 | `string` | n/a | yes | +| [app\_demo\_username](#input\_app\_demo\_username) | 请输入登录应用演示账户的用户名。用户名长度为4-16位,只能包含字母、数字和下划线。 | `string` | `"appuser"` | no | +| [db\_account\_name](#input\_db\_account\_name) | RDS数据库账号 | `string` | `"db_normal_account"` | no | +| [db\_instance\_type](#input\_db\_instance\_type) | RDS实例规格 | `string` | `"mysql.n2.medium.1"` | no | +| [db\_password](#input\_db\_password) | 请输入RDS数据库密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()\_+-=)。如果在本教程中重复配置,请确保 MySQL 数据库密码与模板首次执行时设置的密码完全相同,否则配置结果不可用。 | `string` | n/a | yes | +| [ecs\_instance\_password](#input\_ecs\_instance\_password) | 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)` | `string` | n/a | yes | +| [ecs\_instance\_type](#input\_ecs\_instance\_type) | ECS实例规格 | `string` | `"ecs.t6-c1m2.large"` | no | +| [region](#input\_region) | n/a | `string` | `"cn-hangzhou"` | no | +| [rocketmq\_password](#input\_rocketmq\_password) | 请输入RocketMQ密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()\_+-=)。 | `string` | n/a | yes | +| [rocketmq\_username](#input\_rocketmq\_username) | 请输入RocketMQ用户名。用户名长度为4-16位,只能包含字母、数字和下划线。 | `string` | `"rmquser"` | no | + \ No newline at end of file diff --git a/solution/tech-solution/rocketmq-data-consistency/main.tf b/solution/tech-solution/rocketmq-data-consistency/main.tf new file mode 100644 index 000000000..0791c10f6 --- /dev/null +++ b/solution/tech-solution/rocketmq-data-consistency/main.tf @@ -0,0 +1,310 @@ +provider "alicloud" { + region = var.region +} + +data "alicloud_zones" "ecs_zones" { + available_disk_category = "cloud_essd" + available_resource_creation = "VSwitch" + available_instance_type = var.ecs_instance_type +} + +data "alicloud_db_zones" "rds_zones" { + engine = "MySQL" + engine_version = "8.0" + instance_charge_type = "PostPaid" + category = "Basic" + db_instance_storage_type = "cloud_essd" +} + +resource "random_string" "suffix" { + length = 8 + lower = true + upper = false + numeric = false + special = false +} + +locals { + common_name = random_string.suffix.id +} + +resource "alicloud_vpc" "vpc" { + cidr_block = "192.168.0.0/16" + vpc_name = "vpc-${local.common_name}" +} + +resource "alicloud_vswitch" "ecs_vswitch" { + vpc_id = alicloud_vpc.vpc.id + cidr_block = "192.168.1.0/24" + zone_id = data.alicloud_zones.ecs_zones.zones[0].id + vswitch_name = "ecs-vswitch-${local.common_name}" +} + +resource "alicloud_vswitch" "rds_vswitch" { + vpc_id = alicloud_vpc.vpc.id + cidr_block = "192.168.2.0/24" + zone_id = data.alicloud_db_zones.rds_zones.zones[0].id + vswitch_name = "rds-vswitch-${local.common_name}" +} + +resource "alicloud_security_group" "security_group" { + vpc_id = alicloud_vpc.vpc.id + security_group_name = "sg-${local.common_name}" +} + +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.security_group.id + cidr_ip = "0.0.0.0/0" +} + +resource "alicloud_security_group_rule" "allow_web" { + type = "ingress" + ip_protocol = "tcp" + nic_type = "intranet" + policy = "accept" + port_range = "80/80" + priority = 1 + security_group_id = alicloud_security_group.security_group.id + cidr_ip = "0.0.0.0/0" +} + +data "alicloud_images" "default" { + name_regex = "^aliyun_3_x64_20G_alibase_.*" + most_recent = true + owners = "system" +} + +resource "alicloud_ram_user" "ram_user" { + name = "create_by_solution-${local.common_name}" +} + +resource "alicloud_ram_access_key" "ramak" { + user_name = alicloud_ram_user.ram_user.name +} + +resource "alicloud_ram_user_policy_attachment" "attach_policy_to_user" { + user_name = alicloud_ram_user.ram_user.name + policy_type = "System" + policy_name = "AliyunLogFullAccess" +} + +resource "alicloud_instance" "ecs_instance_provider" { + instance_name = "ecs-${local.common_name}" + image_id = data.alicloud_images.default.images[0].id + instance_type = var.ecs_instance_type + system_disk_category = "cloud_essd" + security_groups = [alicloud_security_group.security_group.id] + vswitch_id = alicloud_vswitch.ecs_vswitch.id + password = var.ecs_instance_password + internet_max_bandwidth_out = 5 +} + +resource "alicloud_ecs_command" "run_command_provider" { + name = "command-1-${local.common_name}" + command_content = base64encode(<> ~/.bash_profile +export MYSQL_HOST=${alicloud_db_instance.rds_instance.connection_string} +export MYSQL_DB=testrmq +export MYSQL_USER=${var.db_account_name} +export MYSQL_PASSWORD=${var.db_password} +export APP_DEMO_ROCKETMQ_ENDPOINT=${alicloud_rocketmq_instance.rocketmq.network_info[0].endpoints[0].endpoint_url} +export APP_DEMO_ROCKETMQ_USERNAME=${var.rocketmq_username} +export APP_DEMO_ROCKETMQ_PASSWORD=${var.rocketmq_password} +export APP_DEMO_USERNAME=${var.app_demo_username} +export APP_DEMO_PASSWORD=${var.app_demo_password} +export IS_CONSUMER=false + +EOT + +source ~/.bash_profile + +curl -fsSL https://help-static-aliyun-doc.aliyuncs.com/install-script/rocketmq-transaction/install.sh|bash +EOF + ) + working_dir = "/root" + type = "RunShellScript" + timeout = 3600 +} + +resource "alicloud_ecs_invocation" "invoke_script_provider" { + instance_id = [alicloud_instance.ecs_instance_provider.id] + command_id = alicloud_ecs_command.run_command_provider.id + timeouts { + create = "15m" + } + depends_on = [ + alicloud_db_instance.rds_instance, + alicloud_db_database.rds_database, + alicloud_rocketmq_instance.rocketmq, + alicloud_rocketmq_acl.topic1, + alicloud_rocketmq_acl.consumer_group, + ] +} + + +resource "alicloud_instance" "ecs_instance_consumer" { + instance_name = "ecs-${local.common_name}" + image_id = data.alicloud_images.default.images[0].id + instance_type = var.ecs_instance_type + system_disk_category = "cloud_essd" + security_groups = [alicloud_security_group.security_group.id] + vswitch_id = alicloud_vswitch.ecs_vswitch.id + password = var.ecs_instance_password + internet_max_bandwidth_out = 5 +} + +resource "alicloud_ecs_command" "run_command_consumer" { + name = "command-1-${local.common_name}" + command_content = base64encode(<> ~/.bash_profile +export MYSQL_HOST=${alicloud_db_instance.rds_instance.connection_string} +export MYSQL_DB=testrmq +export MYSQL_USER=${var.db_account_name} +export MYSQL_PASSWORD=${var.db_password} +export APP_DEMO_ROCKETMQ_ENDPOINT=${alicloud_rocketmq_instance.rocketmq.network_info[0].endpoints[0].endpoint_url} +export APP_DEMO_ROCKETMQ_USERNAME=${var.rocketmq_username} +export APP_DEMO_ROCKETMQ_PASSWORD=${var.rocketmq_password} +export APP_DEMO_USERNAME=${var.app_demo_username} +export APP_DEMO_PASSWORD=${var.app_demo_password} +export IS_CONSUMER=true + +EOT + +source ~/.bash_profile + +curl -fsSL https://help-static-aliyun-doc.aliyuncs.com/install-script/rocketmq-transaction/install.sh|bash +EOF + ) + working_dir = "/root" + type = "RunShellScript" + timeout = 3600 +} + +resource "alicloud_ecs_invocation" "invoke_script_consumer" { + instance_id = [alicloud_instance.ecs_instance_consumer.id] + command_id = alicloud_ecs_command.run_command_consumer.id + timeouts { + create = "15m" + } + depends_on = [ + alicloud_db_instance.rds_instance, + alicloud_db_database.rds_database, + alicloud_rocketmq_instance.rocketmq, + alicloud_rocketmq_acl.topic1, + alicloud_rocketmq_acl.consumer_group, + ] +} + +resource "alicloud_db_instance" "rds_instance" { + instance_type = var.db_instance_type + zone_id = data.alicloud_db_zones.rds_zones.zones[0].id + instance_storage = 50 + category = "Basic" + db_instance_storage_type = "cloud_essd" + vswitch_id = alicloud_vswitch.rds_vswitch.id + engine = "MySQL" + vpc_id = alicloud_vpc.vpc.id + engine_version = "8.0" + security_ips = ["192.168.0.0/16"] +} + +resource "alicloud_rds_account" "rds_account" { + db_instance_id = alicloud_db_instance.rds_instance.id + account_type = "Normal" + account_name = var.db_account_name + account_password = var.db_password +} + +resource "alicloud_db_database" "rds_database" { + character_set = "utf8" + instance_id = alicloud_db_instance.rds_instance.id + name = "testrmq" +} + +resource "alicloud_db_account_privilege" "account_privilege" { + privilege = "ReadWrite" + instance_id = alicloud_db_instance.rds_instance.id + account_name = alicloud_rds_account.rds_account.account_name + db_names = [alicloud_db_database.rds_database.name] +} + +resource "alicloud_rocketmq_instance" "rocketmq" { + product_info { + msg_process_spec = "rmq.s2.2xlarge" + message_retention_time = "70" + } + + sub_series_code = "cluster_ha" + series_code = "standard" + payment_type = "PayAsYouGo" + instance_name = "ROCKETMQ5-${local.common_name}" + service_code = "rmq" + + network_info { + vpc_info { + vpc_id = alicloud_vpc.vpc.id + vswitches { + vswitch_id = alicloud_vswitch.ecs_vswitch.id + } + } + internet_info { + internet_spec = "disable" + flow_out_type = "uninvolved" + } + } + acl_info { + acl_types = ["default", "apache_acl"] + default_vpc_auth_free = false + } + +} + +resource "alicloud_rocketmq_account" "default" { + account_status = "ENABLE" + instance_id = alicloud_rocketmq_instance.rocketmq.id + username = var.rocketmq_username + password = var.rocketmq_password +} + +resource "alicloud_rocketmq_topic" "topic1" { + instance_id = alicloud_rocketmq_instance.rocketmq.id + remark = "用于存储和传输订单相关的业务消息" + message_type = "TRANSACTION" + topic_name = "ROCKETMQ_ORDER_TOPIC" +} + +resource "alicloud_rocketmq_consumer_group" "consumer_group" { + consumer_group_id = "ROCKETMQ_LOGISTIC_CONSUMER_GROUP" + instance_id = alicloud_rocketmq_instance.rocketmq.id + delivery_order_type = "Concurrently" + consume_retry_policy { + retry_policy = "DefaultRetryPolicy" + max_retry_times = 5 + } +} + +resource "alicloud_rocketmq_acl" "topic1" { + actions = ["Pub", "Sub"] + instance_id = alicloud_rocketmq_instance.rocketmq.id + username = alicloud_rocketmq_account.default.username + resource_name = alicloud_rocketmq_topic.topic1.topic_name + resource_type = "Topic" + decision = "Allow" + ip_whitelists = ["192.168.0.0/16"] +} + +resource "alicloud_rocketmq_acl" "consumer_group" { + actions = ["Sub"] + instance_id = alicloud_rocketmq_instance.rocketmq.id + username = alicloud_rocketmq_account.default.username + resource_name = alicloud_rocketmq_consumer_group.consumer_group.consumer_group_id + resource_type = "Group" + decision = "Allow" + ip_whitelists = ["192.168.0.0/16"] +} diff --git a/solution/tech-solution/rocketmq-data-consistency/outputs.tf b/solution/tech-solution/rocketmq-data-consistency/outputs.tf new file mode 100644 index 000000000..0d47f896b --- /dev/null +++ b/solution/tech-solution/rocketmq-data-consistency/outputs.tf @@ -0,0 +1,4 @@ +output "web_url" { + description = "示例应用页面地址。(The address of the demo webpage.)" + value = "http://${alicloud_instance.ecs_instance_provider.public_ip}/login" +} diff --git a/solution/tech-solution/rocketmq-data-consistency/variables.tf b/solution/tech-solution/rocketmq-data-consistency/variables.tf new file mode 100644 index 000000000..bc9ea3419 --- /dev/null +++ b/solution/tech-solution/rocketmq-data-consistency/variables.tf @@ -0,0 +1,59 @@ +variable "region" { + type = string + default = "cn-hangzhou" +} + +variable "ecs_instance_type" { + type = string + default = "ecs.t6-c1m2.large" + description = "ECS实例规格" +} + +variable "ecs_instance_password" { + type = string + sensitive = true + description = "服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)" +} + +variable "db_instance_type" { + type = string + default = "mysql.n2.medium.1" + description = "RDS实例规格" +} + +variable "db_account_name" { + type = string + default = "db_normal_account" + description = "RDS数据库账号" +} + +variable "db_password" { + type = string + sensitive = true + description = "请输入RDS数据库密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()_+-=)。如果在本教程中重复配置,请确保 MySQL 数据库密码与模板首次执行时设置的密码完全相同,否则配置结果不可用。" +} + +variable "rocketmq_username" { + type = string + default = "rmquser" + description = "请输入RocketMQ用户名。用户名长度为4-16位,只能包含字母、数字和下划线。" +} + +variable "rocketmq_password" { + type = string + sensitive = true + description = "请输入RocketMQ密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()_+-=)。" +} + +variable "app_demo_username" { + type = string + default = "appuser" + description = "请输入登录应用演示账户的用户名。用户名长度为4-16位,只能包含字母、数字和下划线。" +} + +variable "app_demo_password" { + type = string + sensitive = true + default = "apppassword" + description = "请输入登录应用演示账户的密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()_+-=)。" +} \ No newline at end of file