在Serverless 应用引擎 SAE(Serverless App Engine)上部署应用后,可以通过添加公网SLB(Server Load Balancer,负载均衡)实现公网访问,也可以添加私网SLB实现同VPC内所有应用间互相访问。本文介绍如何通过Terraform为SAE应用绑定和解绑公网SLB。
本教程所含示例代码支持一键运行,您可以直接运行代码。一键运行
前提条件
-
由于阿里云账号(主账号)具有资源的所有权限,一旦发生泄露将面临重大风险。建议您使用RAM用户,并为该RAM用户创建AccessKey,具体操作方式请参见创建RAM用户和创建AccessKey。
-
为运行Terraform命令的RAM用户绑定以下最小权限策略,以获取管理本示例所涉及资源的权限。更多信息,请参见管理RAM用户的权限。
该自定义权限策略允许RAM用户对SLB的描述、创建、删除、配置及状态设置等操作的权限,同时允许对SAE应用执行绑定和解绑SLB的操作
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "slb:DescribeLoadBalancers", "slb:DescribeLoadBalancerAttribute", "slb:CreateLoadBalancer", "slb:DeleteLoadBalancer", "slb:ModifyLoadBalancerInternetSpec", "slb:CreateLoadBalancerTCPListener", "slb:CreateLoadBalancerHTTPListener", "slb:CreateLoadBalancerHTTPSListener", "slb:DeleteLoadBalancerListener", "slb:SetLoadBalancerStatus", "sae:BindSlb", "sae:UnbindSlb" ], "Resource": "*" } ] } -
准备Terraform运行环境,您可以选择以下任一方式来使用Terraform。
-
ROS提供了Terraform托管服务,因此您可以直接在ROS控制台部署Terraform模板。详细操作,请参见创建Terraform类型资源栈。
-
在Terraform Explorer中使用Terraform:阿里云提供了Terraform的在线运行环境,您无需安装Terraform,登录后即可在线使用和体验Terraform。适用于零成本、快速、便捷地体验和调试Terraform的场景。
-
使用Terraform快速创建资源:阿里云Cloud Shell中预装了Terraform的组件,并已配置好身份凭证,您可直接在Cloud Shell中运行Terraform的命令。适用于低成本、快速、便捷地访问和使用Terraform的场景。
-
在本地安装和配置Terraform:适用于网络连接较差或需要自定义开发环境的场景。
-
使用的资源
-
alicloud_sae_namespace用于创建和管理 SAE (Serverless Application Engine) 命名空间。
-
alicloud_security_group:用于创建和管理安全组。
-
alicloud_security_group_rule:用于创建和管理安全组规则
-
alicloud_sae_application:用于创建和管理 SAE 应用。
-
alicloud_slb_load_balancer:用于创建和管理 SLB (Server Load Balancer)。
-
alicloud_sae_load_balancer_internet:用于配置 SAE 应用的互联网负载均衡器。
创建应用并绑定SLB
本示例以在华南1(深圳)地域下为应用绑定SLB为例,介绍如何通过镜像方式自定义部署应用,并同时为应用绑定SLB。
-
创建一个用于存放Terraform资源的项目文件夹,命名为terraform。
-
执行以下命令,进入项目目录。
cd terraform -
创建名为main.tf的配置文件。
内容如下:
# 提供商配置 provider "alicloud" { region = var.region_id } # 变量定义 variable "region_id" { type = string default = "cn-shenzhen" } variable "app_name" { description = "应用名称" type = string default = "app-slb" } variable "image_url" { description = "镜像地址" type = string default = "registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9" } variable "namespace_id" { description = "命名空间ID" type = string default = "cn-shenzhen:demo" } variable "namespace_name" { description = "命名空间名称" type = string default = "demo" } # 命名空间 resource "alicloud_sae_namespace" "default" { namespace_description = var.namespace_description namespace_id = var.namespace_id namespace_name = var.namespace_name } # VPC resource "alicloud_vpc" "default" { vpc_name = var.name cidr_block = "10.4.0.0/16" } # VSwitch resource "alicloud_vswitch" "default" { vswitch_name = var.name cidr_block = "10.4.0.0/24" vpc_id = alicloud_vpc.default.id zone_id = var.zone_id } # 安全组 resource "alicloud_security_group" "sg" { name = var.name description = var.description vpc_id = alicloud_vpc.default.id } resource "alicloud_security_group_rule" "sg_rule" { type = "ingress" ip_protocol = "tcp" nic_type = "intranet" policy = "accept" port_range = var.port_range priority = 1 security_group_id = alicloud_security_group.sg.id cidr_ip = var.cidr_ip } # 应用配置 resource "alicloud_sae_application" "manual" { app_name = var.app_name app_description = var.app_description deploy = true image_url = var.image_url namespace_id = alicloud_sae_namespace.default.id vswitch_id = alicloud_vswitch.default.id vpc_id = alicloud_vpc.default.id security_group_id = alicloud_security_group.sg.id package_type = var.package_type timezone = "Asia/Beijing" replicas = var.replicas cpu = var.cpu memory = var.memory } # SLB配置 resource "alicloud_slb_load_balancer" "slb" { load_balancer_name = "prod" address_type = "internet" load_balancer_spec = "slb.s2.small" vswitch_id = alicloud_vswitch.default.id } resource "alicloud_sae_load_balancer_internet" "example" { app_id = alicloud_sae_application.manual.id internet_slb_id = alicloud_slb_load_balancer.slb.id internet { protocol = "HTTP" port = var.port target_port = 80 } } # 其他变量定义 variable "namespace_description" { description = "Namespace Description" default = "a namespace" } variable "name" { default = "tf" description = "The name of the security group rule" type = string } variable "description" { default = "The description of the security group rule" description = "The description of the security group rule" type = string } variable "port_range" { default = "1/65535" description = "The port range of the security group rule" type = string } variable "cidr_ip" { description = "cidr blocks used to create a new security group rule" type = string default = "0.0.0.0/0" } variable "zone_id" { description = "Availability Zone ID" type = string default = "cn-shenzhen-a" } variable "app_description" { default = "description created by Terraform" description = "The description of the application" type = string } variable "package_type" { default = "Image" description = "The package type of the application" type = string } variable "cpu" { default = "500" description = "The cpu of the application, in unit of millicore" type = string } variable "memory" { default = "1024" description = "The memory of the application, in unit of MB" type = string } variable "replicas" { default = "1" description = "The replicas of the application" type = string } variable "port" { description = "The port of SLB" type = string default = "8000" } # 输出 output "namespace_id" { value = var.namespace_id description = "Namespace ID" } output "app_id" { description = "The id of the application" value = alicloud_sae_application.manual.id } output "app_name" { description = "The name of the application" value = var.app_name } output "endpoint" { value = format("http://%s:%s", alicloud_slb_load_balancer.slb.address, var.port) } -
执行以下命令,初始化配置。
terraform init -
预期结果:
Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary. -
依次执行以下命令,创建应用。
-
执行以下命令,部署应用。在执行过程中,根据提示输入
yes并按下Enter键,等待命令执行完成,若出现以下信息,则表示授权完成。terraform apply预期结果:
Apply complete! Resources: 4 added, 0 changed, 0 destroyed. Outputs: app_id = "8abb794f-a47b-474b-b6f5-2xxx" app_name = "app-s1b" endpoint = "http://8.xxx.xxx:8000" namespace_id = "cn-shenzhen:demo"
已成功创建绑定了SLB的应用
app-slb,并输出了SLB的IP地址和端口。 -
-
验证结果:
执行terraform show命令
您可以使用以下命令查询Terraform已创建的资源详细信息:
terraform show# alicloud_sae_application.manual: resource "alicloud_sae_application" "manual" { app_description = "description created by Terraform" app_name = "app-slb" batch_wait_time = 10 command_args_v2 = [] config_map_mount_desc = jsonencode([]) cpu = 500 custom_host_alias = jsonencode([]) deploy = true enable_ahas = "false" enable_grey_tag_route = false envs = jsonencode([]) id = "8abb794f-a47b-474b-bxxx51" image_url = "registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9" memory = 1024 min_ready_instance_ratio = -1 min_ready_instances = -1 namespace_id = "cn-shenzhen:demo" package_type = "Image" package_version = "1732255950" replicas = 1 security_group_id = "sg-xxx" status = "RUNNING" termination_grace_period_seconds = 30 vpc_id = "vpc-xxx" vswitch_id = "vsw-xxx" } # alicloud_sae_load_balancer_internet.manual: resource "alicloud_sae_load_balancer_internet" "manual" { app_id = "8abb794f-a47b-474b-bxxx51" id = "8abb794f-a47b-474b-bxxx51" internet_ip = "8.xxx.xxx" internet_slb_id = "lb-xxx" internet { port = 8000 protocol = "TCP" target_port = 80 } } termination_grace_period_seconds = 30 timezone = "Asia/Beijing" vpc_id = "vpc-xxx" vswitch_id = "vsw-xxx" } # alicloud_sae_load_balancer_internet.example: resource "alicloud_sae_load_balancer_internet" "example" { app_id = "xxx" id = "xxx" internet_ip = "xxx" internet_slb_id = "lb-wz98ts8jnxxx" }浏览器访问截图
在浏览器中输入SLB的IP地址和端口,例如
http://121.43.XXX.XX:8000,回车进入应用首页。在浏览器中访问服务器的 8000 端口,页面显示 Nginx 默认欢迎页 Welcome to nginx!,表明 Nginx 已成功安装并正常运行。
解绑SLB并删除应用
本示例以在华南1(深圳)地域下的应用app-slb为例,介绍如何解绑SLB并删除应用。
-
在目标项目目录内执行以下命令,运行配置文件。
terraform destroy -
预期结果:
Destroy complete! Resources: 8 destroyed.已成功解绑SLB并删除应用
app-slb。
完整示例
当前示例代码支持一键运行,您可以直接运行代码。一键运行
# 提供商配置
provider "alicloud" {
region = var.region_id
}
# 变量定义
variable "region_id" {
type = string
default = "cn-shenzhen"
}
variable "app_name" {
description = "应用名称"
type = string
default = "app-slb"
}
variable "image_url" {
description = "镜像地址"
type = string
default = "registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9"
}
variable "namespace_id" {
description = "命名空间ID"
type = string
default = "cn-shenzhen:demo"
}
variable "namespace_name" {
description = "命名空间名称"
type = string
default = "demo"
}
# 命名空间
resource "alicloud_sae_namespace" "default" {
namespace_description = var.namespace_description
namespace_id = var.namespace_id
namespace_name = var.namespace_name
}
# VPC
resource "alicloud_vpc" "default" {
vpc_name = var.name
cidr_block = "10.4.0.0/16"
}
# VSwitch
resource "alicloud_vswitch" "default" {
vswitch_name = var.name
cidr_block = "10.4.0.0/24"
vpc_id = alicloud_vpc.default.id
zone_id = var.zone_id
}
# 安全组
resource "alicloud_security_group" "sg" {
name = var.name
description = var.description
vpc_id = alicloud_vpc.default.id
}
resource "alicloud_security_group_rule" "sg_rule" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = var.port_range
priority = 1
security_group_id = alicloud_security_group.sg.id
cidr_ip = var.cidr_ip
}
# 应用配置
resource "alicloud_sae_application" "manual" {
app_name = var.app_name
app_description = var.app_description
deploy = true
image_url = var.image_url
namespace_id = alicloud_sae_namespace.default.id
vswitch_id = alicloud_vswitch.default.id
vpc_id = alicloud_vpc.default.id
security_group_id = alicloud_security_group.sg.id
package_type = var.package_type
timezone = "Asia/Beijing"
replicas = var.replicas
cpu = var.cpu
memory = var.memory
}
# SLB配置
resource "alicloud_slb_load_balancer" "slb" {
load_balancer_name = "prod"
address_type = "internet"
load_balancer_spec = "slb.s2.small"
vswitch_id = alicloud_vswitch.default.id
}
resource "alicloud_sae_load_balancer_internet" "example" {
app_id = alicloud_sae_application.manual.id
internet_slb_id = alicloud_slb_load_balancer.slb.id
internet {
protocol = "HTTP"
port = var.port
target_port = 80
}
}
# 其他变量定义
variable "namespace_description" {
description = "Namespace Description"
default = "a namespace"
}
variable "name" {
default = "tf"
description = "The name of the security group rule"
type = string
}
variable "description" {
default = "The description of the security group rule"
description = "The description of the security group rule"
type = string
}
variable "port_range" {
default = "1/65535"
description = "The port range of the security group rule"
type = string
}
variable "cidr_ip" {
description = "cidr blocks used to create a new security group rule"
type = string
default = "0.0.0.0/0"
}
variable "zone_id" {
description = "Availability Zone ID"
type = string
default = "cn-shenzhen-a"
}
variable "app_description" {
default = "description created by Terraform"
description = "The description of the application"
type = string
}
variable "package_type" {
default = "Image"
description = "The package type of the application"
type = string
}
variable "cpu" {
default = "500"
description = "The cpu of the application, in unit of millicore"
type = string
}
variable "memory" {
default = "1024"
description = "The memory of the application, in unit of MB"
type = string
}
variable "replicas" {
default = "1"
description = "The replicas of the application"
type = string
}
variable "port" {
description = "The port of SLB"
type = string
default = "8000"
}
# 输出
output "namespace_id" {
value = var.namespace_id
description = "Namespace ID"
}
output "app_id" {
description = "The id of the application"
value = alicloud_sae_application.manual.id
}
output "app_name" {
description = "The name of the application"
value = var.app_name
}
output "endpoint" {
value = format("http://%s:%s", alicloud_slb_load_balancer.slb.address, var.port)
}
相关文档
-
Terrafrom介绍,请参见了解阿里云Terraform。
-
当您遇到由于网络延迟等原因造成的 terraform init 超时,导致无法正常下载 Provider 等情况时,请参见Terraform Init 加速方案配置。
-
关于如何配置Terraform的身份认证信息,请参见静配置身份认证。