在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的场景。
Cloud Shell:阿里云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
预期结果:
依次执行以下命令,创建应用。
执行以下命令,部署应用。在执行过程中,根据提示输入
yes
并按下Enter键,等待命令执行完成,若出现以下信息,则表示授权完成。terraform apply
预期结果:
已成功创建绑定了SLB的应用
app-slb
,并输出了SLB的IP地址和端口。验证结果:
执行terraform show命令
您可以使用以下命令查询Terraform已创建的资源详细信息:
terraform show
浏览器访问截图
在浏览器中输入SLB的IP地址和端口,例如
http://121.43.XXX.XX:8000
,回车进入应用首页。
解绑SLB并删除应用
本示例以在华南1(深圳)地域下的应用app-slb
为例,介绍如何解绑SLB并删除应用。
在目标项目目录内执行以下命令,运行配置文件。
terraform destroy
预期结果:
已成功解绑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的身份认证信息,请参见静配置身份认证。