Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions solution/tech-solution/serverless-ha/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## Introduction
<!-- DOCS_DESCRIPTION_CN -->
本示例用于实现解决方案[极简运维,Serverless 高可用架构](https://www.aliyun.com/solution/tech-solution/serverless-ha), 涉及到专有网络(VPC)、交换机(VSwitch)、云原生数据库PolarDB MySQL版、应用型负载均衡(ALB)等资源的部署。
<!-- DOCS_DESCRIPTION_CN -->

<!-- DOCS_DESCRIPTION_EN -->
This example is used to implement solution [Minimal Operations, Serverless High Availability Architecture](https://www.aliyun.com/solution/tech-solution/serverless-ha), which involves the creation and deployment of resources such as Virtual Private Cloud (VPC), VSwitch, PolarDB for MySQL, Application Load Balancer (ALB).
<!-- DOCS_DESCRIPTION_EN -->

<!-- BEGIN_TF_DOCS -->
## Providers

| Name | Version |
|------|---------|
| <a name="provider_alicloud"></a> [alicloud](#provider\_alicloud) | n/a |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_time"></a> [time](#provider\_time) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [alicloud_alb_load_balancer.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/alb_load_balancer) | resource |
| [alicloud_polardb_account.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/polardb_account) | resource |
| [alicloud_polardb_account_privilege.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/polardb_account_privilege) | resource |
| [alicloud_polardb_cluster.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/polardb_cluster) | resource |
| [alicloud_polardb_database.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/polardb_database) | resource |
| [alicloud_sae_application.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/sae_application) | resource |
| [alicloud_sae_ingress.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/sae_ingress) | resource |
| [alicloud_sae_namespace.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/sae_namespace) | resource |
| [alicloud_security_group.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group) | resource |
| [alicloud_security_group_rule.allow_http](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
| [alicloud_security_group_rule.allow_https](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
| [alicloud_security_group_rule.allow_mysql](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
| [alicloud_vpc.main](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vpc) | resource |
| [alicloud_vswitch.db_01](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [alicloud_vswitch.pub_01](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [alicloud_vswitch.pub_02](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [alicloud_vswitch.web_01](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [alicloud_vswitch.web_02](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [time_sleep.wait_app](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
| [alicloud_polardb_node_classes.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/polardb_node_classes) | data source |
| [alicloud_regions.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/regions) | data source |
| [alicloud_zones.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/zones) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_common_name"></a> [common\_name](#input\_common\_name) | 通用名称前缀 | `string` | `"serverless"` | no |
| <a name="input_db_password"></a> [db\_password](#input\_db\_password) | MySQL数据库密码,长度8-30,必须包含三项(大写字母、小写字母、数字、特殊符号) | `string` | n/a | yes |
| <a name="input_db_user_name"></a> [db\_user\_name](#input\_db\_user\_name) | MySQL数据库账号 | `string` | `"applets"` | no |
| <a name="input_region"></a> [region](#input\_region) | 地域 | `string` | `"cn-hangzhou"` | no |
<!-- END_TF_DOCS -->
318 changes: 318 additions & 0 deletions solution/tech-solution/serverless-ha/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@

locals {
zone_id_1 = data.alicloud_polardb_node_classes.default.classes[0].zone_id
zone_id_2 = data.alicloud_zones.default.zones.0.id
}
# 生成随机后缀用于资源命名
resource "random_string" "suffix" {
length = 5
special = false
upper = false
}

data "alicloud_regions" "default" {
current = true
}
data "alicloud_polardb_node_classes" "default" {
db_type = "MySQL"
db_version = "8.0"
category = "Normal"
pay_type = "PostPaid"
db_node_class = "polar.mysql.sl.small"
}

data "alicloud_zones" "default" {
available_resource_creation = "VSwitch"
}

# 创建VPC
resource "alicloud_vpc" "main" {
vpc_name = "${var.common_name}-vpc"
cidr_block = "192.168.0.0/16"

tags = {
Name = "${var.common_name}-vpc"
}
}

# 创建交换机1 (Web层 - 可用区1)
resource "alicloud_vswitch" "web_01" {
vpc_id = alicloud_vpc.main.id
cidr_block = "192.168.1.0/24"
zone_id = local.zone_id_1
vswitch_name = "${var.common_name}-web-01"

tags = {
Name = "${var.common_name}-web-01"
}
}

# 创建交换机2 (Web层 - 可用区2)
resource "alicloud_vswitch" "web_02" {
vpc_id = alicloud_vpc.main.id
cidr_block = "192.168.2.0/24"
zone_id = local.zone_id_2
vswitch_name = "${var.common_name}-web-02"

tags = {
Name = "${var.common_name}-web-02"
}
}

# 创建交换机3 (数据库层 - 可用区1)
resource "alicloud_vswitch" "db_01" {
vpc_id = alicloud_vpc.main.id
cidr_block = "192.168.3.0/24"
zone_id = local.zone_id_1
vswitch_name = "${var.common_name}-db-01"

tags = {
Name = "${var.common_name}-db-01"
}
}

# 创建交换机4 (公网层 - 可用区1)
resource "alicloud_vswitch" "pub_01" {
vpc_id = alicloud_vpc.main.id
cidr_block = "192.168.4.0/24"
zone_id = local.zone_id_1
vswitch_name = "${var.common_name}-pub-01"

tags = {
Name = "${var.common_name}-pub-01"
}
}

# 创建交换机5 (公网层 - 可用区2)
resource "alicloud_vswitch" "pub_02" {
vpc_id = alicloud_vpc.main.id
cidr_block = "192.168.5.0/24"
zone_id = local.zone_id_2
vswitch_name = "${var.common_name}-pub-02"

tags = {
Name = "${var.common_name}-pub-02"
}
}

# 创建安全组
resource "alicloud_security_group" "main" {
security_group_name = "${var.common_name}-sg"
vpc_id = alicloud_vpc.main.id
description = "Serverless高可用架构安全组"

tags = {
Name = "${var.common_name}-sg"
}
}

# 安全组规则 - 允许HTTPS访问
resource "alicloud_security_group_rule" "allow_https" {
type = "ingress"
ip_protocol = "tcp"
port_range = "443/443"
security_group_id = alicloud_security_group.main.id
cidr_ip = "0.0.0.0/0"
}

# 安全组规则 - 允许HTTP访问
resource "alicloud_security_group_rule" "allow_http" {
type = "ingress"
ip_protocol = "tcp"
port_range = "80/80"
security_group_id = alicloud_security_group.main.id
cidr_ip = "0.0.0.0/0"
}

# 安全组规则 - 允许MySQL访问
resource "alicloud_security_group_rule" "allow_mysql" {
type = "ingress"
ip_protocol = "tcp"
port_range = "3306/3306"
security_group_id = alicloud_security_group.main.id
cidr_ip = "0.0.0.0/0"
}

# 创建PolarDB集群
resource "alicloud_polardb_cluster" "main" {
db_type = "MySQL"
db_version = "8.0"
db_node_class = data.alicloud_polardb_node_classes.default.classes.0.supported_engines.0.available_resources.0.db_node_class
pay_type = "PostPaid"
vswitch_id = alicloud_vswitch.db_01.id
zone_id = local.zone_id_1
security_group_ids = [alicloud_security_group.main.id]

# Serverless配置
serverless_type = "AgileServerless"
scale_min = 1
scale_max = 16
scale_ro_num_min = 1
scale_ro_num_max = 4

description = "Serverless高可用架构PolarDB集群"

tags = {
Name = "${var.common_name}-polardb"
}
}

# 创建数据库
resource "alicloud_polardb_database" "main" {
db_cluster_id = alicloud_polardb_cluster.main.id
db_name = "applets"
character_set_name = "utf8mb4"
db_description = "serverless demo"
}

# 创建数据库账号
resource "alicloud_polardb_account" "main" {
db_cluster_id = alicloud_polardb_cluster.main.id
account_name = var.db_user_name
account_password = var.db_password
account_type = "Normal"
}

# 为账号授权数据库
resource "alicloud_polardb_account_privilege" "main" {
db_cluster_id = alicloud_polardb_cluster.main.id
account_name = alicloud_polardb_account.main.account_name
db_names = [alicloud_polardb_database.main.db_name]
account_privilege = "ReadWrite"
}

# 创建应用负载均衡器(ALB)
resource "alicloud_alb_load_balancer" "main" {
load_balancer_name = "${var.common_name}-alb"
load_balancer_edition = "Basic"
vpc_id = alicloud_vpc.main.id
address_type = "Internet"
address_allocated_mode = "Fixed"

load_balancer_billing_config {
pay_type = "PayAsYouGo"
}

zone_mappings {
zone_id = local.zone_id_1
vswitch_id = alicloud_vswitch.web_01.id
}

zone_mappings {
zone_id = local.zone_id_2
vswitch_id = alicloud_vswitch.web_02.id
}

tags = {
Name = "${var.common_name}-alb"
}
}

# 创建SAE命名空间
resource "alicloud_sae_namespace" "main" {
namespace_name = "serverless-demo"
namespace_id = "${data.alicloud_regions.default.regions.0.id}:serverless${random_string.suffix.result}"
}

# 创建SAE应用
resource "alicloud_sae_application" "main" {
app_name = "serverless-demo-${random_string.suffix.result}"
app_description = "serverless-demo"
namespace_id = alicloud_sae_namespace.main.id

package_type = "FatJar"
package_version = "1718956564756"
package_url = "https://help-static-aliyun-doc.aliyuncs.com/tech-solution/sae-demo-0.0.3.jar"

vpc_id = alicloud_vpc.main.id
security_group_id = alicloud_security_group.main.id
vswitch_id = "${alicloud_vswitch.pub_01.id},${alicloud_vswitch.pub_02.id}"

cpu = 2000
memory = 4096
replicas = 2

jdk = "Open JDK 8"
timezone = "Asia/Shanghai"

jar_start_args = "$JAVA_HOME/bin/java $Options -jar $CATALINA_OPTS \"$package_path\" $args"
jar_start_options = "-XX:+UseContainerSupport -XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=70.0 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/admin/nas/gc-$${POD_IP}-$(date '+%s').log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nas/dump-$${POD_IP}-$(date '+%s').hprof"

envs = jsonencode([
{
name = "APPLETS_MYSQL_ENDPOINT"
value = alicloud_polardb_cluster.main.connection_string
},
{
name = "APPLETS_MYSQL_USER"
value = var.db_user_name
},
{
name = "APPLETS_MYSQL_PASSWORD"
value = var.db_password
},
{
name = "APPLETS_MYSQL_DB_NAME"
value = "applets"
},
{
name = "APP_MANUAL_DEPLOY"
value = "false"
}
])

readiness_v2 {
exec {
command = ["sleep", "6s"]
}
initial_delay_seconds = 15
timeout_seconds = 12
}

liveness_v2 {
http_get {
path = "/"
port = 80
scheme = "HTTP"
}
initial_delay_seconds = 10
timeout_seconds = 10
period_seconds = 10
}

tags = {
Name = "serverless-demo-${random_string.suffix.result}"
}
}

# 等待应用部署完成
resource "time_sleep" "wait_app" {
depends_on = [alicloud_sae_application.main]
create_duration = "180s"
}

# 创建SAE Ingress规则
resource "alicloud_sae_ingress" "main" {
depends_on = [time_sleep.wait_app]
namespace_id = alicloud_sae_namespace.main.id
slb_id = alicloud_alb_load_balancer.main.id
description = "serverless-demo-router"

load_balance_type = "alb"
listener_protocol = "HTTP"
listener_port = 80

rules {
app_name = alicloud_sae_application.main.app_name
app_id = alicloud_sae_application.main.id
container_port = 80
domain = "example.com"
path = "/"
}

default_rule {
app_name = alicloud_sae_application.main.app_name
app_id = alicloud_sae_application.main.id
container_port = 80
}
}
Loading
Loading