Skip to content

Commit c368a23

Browse files
committed
feat: 解决方案efficiently-build-app-on-the-cloud tf文件完成
1 parent fc59d9b commit c368a23

File tree

5 files changed

+376
-0
lines changed

5 files changed

+376
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Introduction
2+
<!-- DOCS_DESCRIPTION_CN -->
3+
本示例用于实现解决方案[高效构建移动 App](https://www.aliyun.com/solution/tech-solution/develop-apps),涉及专有网络(VPC)、交换机(VSwitch)、RDS数据库(RDS)、云服务器(ECS)等资源的部署。
4+
<!-- DOCS_DESCRIPTION_CN -->
5+
6+
<!-- DOCS_DESCRIPTION_EN -->
7+
This example is used to implement solution [Efficiently Build Apps On The Cloud](https://www.aliyun.com/solution/tech-solution/develop-apps), which involves the creation and deployment of resources such as Virtual Private Cloud (Vpc), Virtual Switch (VSwitch), RDS Database (Rds), Elastic Compute Service (Ecs).
8+
<!-- DOCS_DESCRIPTION_EN -->
9+
10+
<!-- BEGIN_TF_DOCS -->
11+
## Providers
12+
13+
| Name | Version |
14+
|------|---------|
15+
| <a name="provider_alicloud"></a> [alicloud](#provider\_alicloud) | n/a |
16+
17+
## Modules
18+
19+
No modules.
20+
21+
## Resources
22+
23+
| Name | Type |
24+
|------|------|
25+
| [alicloud_db_database.rds_database](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_database) | resource |
26+
| [alicloud_db_instance.rds_instance](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_instance) | resource |
27+
| [alicloud_dns_record.domain_record](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/dns_record) | resource |
28+
| [alicloud_ecs_command.install_java](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_command) | resource |
29+
| [alicloud_ecs_invocation.invoke_install_java](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_invocation) | resource |
30+
| [alicloud_instance.ecs_instance](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/instance) | resource |
31+
| [alicloud_rds_account.create_db_user](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/rds_account) | resource |
32+
| [alicloud_security_group.security_group](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group) | resource |
33+
| [alicloud_security_group_rule.security_group_ingress_3306](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
34+
| [alicloud_security_group_rule.security_group_ingress_443](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
35+
| [alicloud_security_group_rule.security_group_ingress_80](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
36+
| [alicloud_vpc.vpc](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vpc) | resource |
37+
| [alicloud_vswitch.ecs_vswitch1](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
38+
| [alicloud_vswitch.rds_vswitch2](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
39+
| [alicloud_db_instance_classes.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/db_instance_classes) | data source |
40+
| [alicloud_db_zones.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/db_zones) | data source |
41+
| [alicloud_images.instance_image](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/images) | data source |
42+
| [alicloud_instance_types.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/instance_types) | data source |
43+
| [alicloud_zones.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/zones) | data source |
44+
45+
## Inputs
46+
47+
| Name | Description | Type | Default | Required |
48+
|------|-------------|------|---------|:--------:|
49+
| <a name="input_common_name"></a> [common\_name](#input\_common\_name) | 名称 | `string` | `"app"` | no |
50+
| <a name="input_database_name"></a> [database\_name](#input\_database\_name) | 数据名称,由 2 到 32 个小写字母组成,支持小写字母、数字和下划线,以小写字母开头。 | `string` | `"app"` | no |
51+
| <a name="input_db_password"></a> [db\_password](#input\_db\_password) | 数据库账号密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)` | `string` | n/a | yes |
52+
| <a name="input_db_user_name"></a> [db\_user\_name](#input\_db\_user\_name) | 数据库用户名,由 2 到 32 个小写字母组成,支持小写字母、数字和下划线,以小写字母开头。 | `string` | `"app"` | no |
53+
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | 域名 | <pre>object({<br/> domain_prefix = string<br/> domain_name = string<br/> })</pre> | `null` | no |
54+
| <a name="input_ecs_instance_password"></a> [ecs\_instance\_password](#input\_ecs\_instance\_password) | 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.? 中的特殊符号)` | `string` | n/a | yes |
55+
| <a name="input_region"></a> [region](#input\_region) | 地域 | `string` | `"cn-hangzhou"` | no |
56+
<!-- END_TF_DOCS -->
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
data "alicloud_instance_types" "default" {
2+
instance_type_family = "ecs.g7"
3+
}
4+
5+
data "alicloud_zones" "default" {
6+
available_instance_type = data.alicloud_instance_types.default.ids.0
7+
}
8+
9+
data "alicloud_db_zones" "default" {
10+
engine = "MySQL"
11+
engine_version = "8.0"
12+
instance_charge_type = "PostPaid"
13+
category = "Basic"
14+
db_instance_storage_type = "cloud_essd"
15+
}
16+
17+
data "alicloud_db_instance_classes" "default" {
18+
zone_id = data.alicloud_db_zones.default.ids.0
19+
instance_charge_type = "PostPaid"
20+
engine = "MySQL"
21+
engine_version = "8.0"
22+
category = "Basic"
23+
db_instance_storage_type = "cloud_essd"
24+
}
25+
26+
data "alicloud_images" "instance_image" {
27+
name_regex = "^aliyun_3_9_x64_20G_*"
28+
most_recent = true
29+
owners = "system"
30+
instance_type = data.alicloud_instance_types.default.ids.0
31+
}
32+
33+
resource "alicloud_vpc" "vpc" {
34+
vpc_name = "${var.common_name}-vpc"
35+
cidr_block = "192.168.0.0/16"
36+
}
37+
38+
resource "alicloud_vswitch" "ecs_vswitch1" {
39+
vpc_id = alicloud_vpc.vpc.id
40+
cidr_block = "192.168.0.0/24"
41+
zone_id = data.alicloud_zones.default.ids.0
42+
vswitch_name = "${var.common_name}-vsw"
43+
}
44+
45+
resource "alicloud_vswitch" "rds_vswitch2" {
46+
vpc_id = alicloud_vpc.vpc.id
47+
cidr_block = "192.168.1.0/24"
48+
zone_id = data.alicloud_db_zones.default.ids.0
49+
vswitch_name = "${var.common_name}-vsw"
50+
}
51+
52+
resource "alicloud_security_group" "security_group" {
53+
security_group_name = "${var.common_name}-sg"
54+
vpc_id = alicloud_vpc.vpc.id
55+
}
56+
57+
resource "alicloud_security_group_rule" "security_group_ingress_443" {
58+
security_group_id = alicloud_security_group.security_group.id
59+
type = "ingress"
60+
ip_protocol = "tcp"
61+
port_range = "443/443"
62+
cidr_ip = "0.0.0.0/0"
63+
}
64+
65+
resource "alicloud_security_group_rule" "security_group_ingress_80" {
66+
security_group_id = alicloud_security_group.security_group.id
67+
type = "ingress"
68+
ip_protocol = "tcp"
69+
port_range = "80/80"
70+
cidr_ip = "0.0.0.0/0"
71+
}
72+
73+
resource "alicloud_security_group_rule" "security_group_ingress_3306" {
74+
security_group_id = alicloud_security_group.security_group.id
75+
type = "ingress"
76+
ip_protocol = "tcp"
77+
port_range = "3306/3306"
78+
cidr_ip = "0.0.0.0/0"
79+
}
80+
81+
resource "alicloud_instance" "ecs_instance" {
82+
instance_name = "${var.common_name}-ecs"
83+
image_id = data.alicloud_images.instance_image.images[0].id
84+
instance_type = data.alicloud_instance_types.default.ids.0
85+
security_groups = [alicloud_security_group.security_group.id]
86+
vswitch_id = alicloud_vswitch.ecs_vswitch1.id
87+
system_disk_category = "cloud_essd"
88+
internet_max_bandwidth_out = 100
89+
password = var.ecs_instance_password
90+
}
91+
92+
resource "alicloud_db_instance" "rds_instance" {
93+
engine = "MySQL"
94+
engine_version = "8.0"
95+
instance_type = data.alicloud_db_instance_classes.default.ids.0
96+
instance_storage = 40
97+
category = "Basic"
98+
db_instance_storage_type = "cloud_essd"
99+
vpc_id = alicloud_vpc.vpc.id
100+
vswitch_id = alicloud_vswitch.rds_vswitch2.id
101+
security_group_ids = [alicloud_security_group.security_group.id]
102+
security_ips = ["192.168.0.0/24"]
103+
}
104+
105+
resource "alicloud_rds_account" "create_db_user" {
106+
db_instance_id = alicloud_db_instance.rds_instance.id
107+
account_name = var.db_user_name
108+
account_password = var.db_password
109+
account_type = "Super"
110+
}
111+
112+
resource "alicloud_db_database" "rds_database" {
113+
name = var.database_name
114+
description = "${var.database_name} database"
115+
instance_id = alicloud_db_instance.rds_instance.id
116+
character_set = "utf8mb4"
117+
}
118+
119+
locals {
120+
install_java_script = <<-SHELL
121+
#!/bin/bash
122+
# 环境变量配置
123+
export PATH=/usr/local/bin:$PATH
124+
125+
echo "export APPLETS_RDS_ENDPOINT=${alicloud_db_instance.rds_instance.connection_string}" >> ~/.bashrc
126+
echo "export APPLETS_RDS_USER=${var.db_user_name}" >> ~/.bashrc
127+
echo "export APPLETS_RDS_PASSWORD=${var.db_password}" >> ~/.bashrc
128+
echo "export APPLETS_RDS_DB_NAME=${var.database_name}" >> ~/.bashrc
129+
source ~/.bashrc
130+
131+
# 网络检查地址
132+
NETWORK_CHECk_ADDR="help-static-aliyun-doc.aliyuncs.com"
133+
134+
function unsupported_system() {
135+
log_fatal 1 "Unsupported System: $1"
136+
}
137+
138+
function log_info() {
139+
printf "%s [INFO] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
140+
}
141+
142+
function log_error() {
143+
printf "%s [ERROR] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
144+
}
145+
146+
function log_fatal() {
147+
printf "\n========================================================================\n"
148+
printf "%s [FATAL] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$2"
149+
printf "\n========================================================================\n"
150+
exit $1
151+
}
152+
153+
function debug_exec(){
154+
local cmd="$@"
155+
log_info "$cmd"
156+
eval "$cmd"
157+
ret=$?
158+
echo ""
159+
log_info "$cmd, exit code: $ret"
160+
return $ret
161+
}
162+
163+
function check_network_available() {
164+
log_info "ping $NETWORK_CHECk_ADDR ..."
165+
if ! debug_exec ping -c 4 $NETWORK_CHECk_ADDR; then
166+
log_fatal 2 "Could not connect to https://$NETWORK_CHECk_ADDR"
167+
fi
168+
}
169+
170+
function install_java() {
171+
log_info "install java"
172+
yum upgrade & yum install java-1.8.0-openjdk-devel -y
173+
}
174+
175+
function init_database() {
176+
log_info "install mysql 1.20.1"
177+
yum install -y mysql
178+
mysql -h $APPLETS_RDS_ENDPOINT -u $APPLETS_RDS_USER -p$APPLETS_RDS_PASSWORD < /data/script.sql
179+
}
180+
181+
log_info "System Information:"
182+
if ! lsb_release -a; then
183+
unsupported_system
184+
fi;
185+
echo ""
186+
187+
check_network_available
188+
189+
mkdir -p /data
190+
cat <<"EOF" >> /data/script.sql
191+
-- script.sql
192+
USE ${var.database_name};
193+
CREATE TABLE `todo_list` (
194+
`id` bigint NOT NULL COMMENT 'id',
195+
`title` varchar(128) NOT NULL COMMENT 'title',
196+
`desc` text NOT NULL COMMENT 'description',
197+
`status` varchar(128) NOT NULL COMMENT 'status 未开始、进行中、已完成、已取消',
198+
`priority` varchar(128) NOT NULL COMMENT 'priority 高、中、低',
199+
`expect_time` datetime COMMENT 'expect time',
200+
`actual_completion_time` datetime COMMENT 'actual completion time',
201+
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',
202+
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'modified time',
203+
PRIMARY KEY (`id`)
204+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
205+
;
206+
INSERT INTO todo_list
207+
(id, title, `desc`, `status`, priority, expect_time)
208+
value(1, "创建一个小程序", "使用阿里云解决方案快速搭建一个App应用", "进行中", "高", "2024-04-01 00:00:00")
209+
210+
EOF
211+
212+
if ! debug_exec install_java; then
213+
log_fatal 3 "install java failed"
214+
fi
215+
216+
if ! debug_exec init_database; then
217+
log_fatal 4 "init database failed"
218+
fi
219+
SHELL
220+
}
221+
222+
resource "alicloud_ecs_command" "install_java" {
223+
depends_on = [alicloud_db_database.rds_database]
224+
name = "install-java-and-init-db"
225+
command_content = base64encode(local.install_java_script)
226+
description = "Install Java and Initialize Database"
227+
type = "RunShellScript"
228+
working_dir = "/root"
229+
}
230+
231+
resource "alicloud_ecs_invocation" "invoke_install_java" {
232+
instance_id = [alicloud_instance.ecs_instance.id]
233+
command_id = alicloud_ecs_command.install_java.id
234+
}
235+
236+
resource "alicloud_dns_record" "domain_record" {
237+
count = var.domain_name == null ? 0 : 1
238+
239+
# 解析 domain_name JSON 字符串,提取 domain_name 字段
240+
name = var.domain_name.domain_name
241+
242+
# 解析 domain_name JSON 字符串,提取 domain_prefix 字段
243+
host_record = var.domain_name.domain_prefix != "" && var.domain_name.domain_prefix != null ? var.domain_name.domain_prefix : "@"
244+
type = "A"
245+
value = alicloud_instance.ecs_instance.public_ip
246+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
output "database_name" {
2+
description = "The name of database."
3+
value = alicloud_db_database.rds_database.name
4+
}
5+
6+
output "database_user_name" {
7+
description = "The name of database user."
8+
value = alicloud_rds_account.create_db_user.account_name
9+
}
10+
11+
output "database_endpoint" {
12+
description = "The connection address of database."
13+
value = alicloud_db_instance.rds_instance.connection_string
14+
}
15+
16+
output "ecs_login_address" {
17+
description = "Ecs login address"
18+
value = "https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs&instanceId=${alicloud_instance.ecs_instance.id}"
19+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
provider "alicloud" {
2+
region = var.region
3+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
variable "region" {
2+
description = "地域"
3+
type = string
4+
default = "cn-hangzhou"
5+
}
6+
7+
variable "common_name" {
8+
description = "名称"
9+
type = string
10+
default = "app"
11+
}
12+
13+
variable "ecs_instance_password" {
14+
description = "服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.? 中的特殊符号)"
15+
type = string
16+
sensitive = true
17+
}
18+
19+
variable "db_user_name" {
20+
type = string
21+
description = "数据库用户名,由 2 到 32 个小写字母组成,支持小写字母、数字和下划线,以小写字母开头。"
22+
validation {
23+
condition = can(regex("^[a-z][a-z0-9_]{0,31}$", var.db_user_name))
24+
error_message = "由 2 到 32 个小写字母组成,支持小写字母、数字和下划线,以小写字母开头。"
25+
}
26+
default = "app"
27+
}
28+
29+
variable "db_password" {
30+
description = "数据库账号密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)"
31+
type = string
32+
sensitive = true
33+
}
34+
35+
variable "database_name" {
36+
type = string
37+
description = "数据名称,由 2 到 32 个小写字母组成,支持小写字母、数字和下划线,以小写字母开头。"
38+
validation {
39+
condition = can(regex("^[a-z][a-z0-9_]{0,31}$", var.database_name))
40+
error_message = "由 2 到 32 个小写字母组成,支持小写字母、数字和下划线,以小写字母开头。"
41+
}
42+
default = "app"
43+
}
44+
45+
variable "domain_name" {
46+
description = "域名"
47+
type = object({
48+
domain_prefix = string
49+
domain_name = string
50+
})
51+
default = null
52+
}

0 commit comments

Comments
 (0)