使用Terraform为SAE应用绑定SLB

Serverless 应用引擎 SAE(Serverless App Engine)上部署应用后,可以通过添加公网SLB(Server Load Balancer,负载均衡)实现公网访问,也可以添加私网SLB实现同VPC内所有应用间互相访问。本文介绍如何通过Terraform为SAE应用绑定和解绑公网SLB。

前提条件

  • 安装Terraform。支持Terraform 0.13及以上版本。
  • 配置阿里云账号信息。

    选择一种阿里云认证方式,为Terraform的执行提供认证信息。本文以环境变量认证方式为例:

    export ALICLOUD_ACCESS_KEY="************"
    export ALICLOUD_SECRET_KEY="************"
    export ALICLOUD_REGION="cn-hangzhou"
    说明 为保障数据安全性,建议您按需为RAM用户授予SAE资源的操作权限。具体操作,请参见为RAM用户授权

背景信息

通过Terraform为SAE应用绑定SLB的实质,是在创建应用时配置alicloud_sae_load_balancer_internet资源。如果您想解绑SLB,需同时删除SLB和应用。Terraform的alicloud_sae_load_balancer_internet资源提供了以下参数:
  • 必需:app_id:需要绑定SLB的应用ID。
  • 可选:internet_slb_id:公网SLB ID。
  • 必需:internet:绑定公网SLB。参数说明如下:
    • protocol:网络协议。取值为TCPHTTPHTTPS
    • https_cert_id:SSL证书。当您选择HTTPS协议时必填。
    • target_port:容器端口,即进程监听端口,由程序定义。例如:Web服务默认使用8080端口。
    • port:SLB端口。取值范围[1,65535]。

更多信息,请参见alicloud_sae_load_balancer_internet

创建应用并绑定SLB

本示例以在华东1(杭州)地域下为应用绑定SLB为例,介绍如何通过镜像方式自定义部署应用,并同时为应用绑定SLB。

  1. 创建一个用于存放Terraform资源的项目文件夹,命名为terraform
  2. 执行以下命令,进入项目目录。
    cd terraform
  3. 创建名为main.tf的配置文件。
    内容如下:
    terraform {
      required_providers {
        alicloud = {
          source  = "hashicorp/alicloud"
          version = "~> 1.164.0"
        }
      }
    }
    
    # 命名空间
    resource "alicloud_sae_namespace" "default" {
      namespace_description = var.namespace_description
      namespace_id          = var.namespace_id
      namespace_name        = var.namespace_name
    }
    
    # 安全组
    resource "alicloud_security_group" "sg" {
      name        = var.name
      description = var.description
      vpc_id      = module.vpc.VPC_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
    }
    
    module "vpc" {
      source  = "git::github.com/kubevela-contrib/terraform-modules.git//alibaba/vswitch"
      zone_id = var.zone_id
    }
    
    
    # 应用配置
    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        = module.vpc.VSWITCH_ID
      vpc_id            = module.vpc.VPC_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         = module.vpc.VSWITCH_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 "namespace_name" {
      description = "Namespace Name"
      type = string
    }
    
    # 命名空间ID
    variable "namespace_id" {
      description = "Namespace ID"
      type = string
    }
    
    output "namespace_id" {
      value = var.namespace_id
      description = "Namespace ID"
    }
    
    # 安全组名称
    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
    }
    
    # CIDR地址
    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-hongkong-b"
    }
    
    
    # 应用名称
    variable "app_name" {
      description = "The name of the application"
      type        = string
    }
    # 应用描述
    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
    }
    # 实例CPU规格
    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
    }
    
    # SLB端口
    variable "port" {
      description = "The port of SLB"
      type        = string
      default = "8000"
    }
    
    # 镜像地址
    variable "image_url" {
      description = "The image url of the application, like `registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9`"
      type        = string
    }
    
    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)
    }
  4. 执行以下命令,初始化配置。
    terraform init
  5. 依次执行以下命令,创建应用。
    1. 执行以下命令,部署应用。
      terraform apply
    2. 根据提示依次输入应用的各项信息。
      • app-name:应用名称。输入app-slb
      • image_url:镜像地址。输入registry.cn-hangzhou.aliyuncs.com/****/****:01
        您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面查看镜像地址。格式如下:
        registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>
      • namespace_id:命名空间ID。输入cn-hangzhou:demo
      • namespace_name:命名空间名称。输入demo
      预期输出:
      ...
      
      Plan: 8 to add, 0 to change, 0 to destroy.
      
      Changes to Outputs:
        + app_id       = (known after apply)
        + app_name     = "app-slb"
        + endpoint     = (known after apply)
        + namespace_id = "cn-hangzhou:demo"
      alicloud_sae_namespace.default: Creating...
      module.vpc.alicloud_vpc.vpc[0]: Creating...
      module.vpc.alicloud_vpc.vpc[0]: Creation complete after 8s [id=vpc-bp1pe1dto1fxfecs6****]
      ...
      alicloud_sae_load_balancer_internet.example: Still creating... [50s elapsed]
      alicloud_sae_load_balancer_internet.example: Creation complete after 57s [id=807b04fb-7c91-4129-8315-0d01****]
      
      Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
      
      Outputs:
      
      app_id = "422e0338-04f4-442d-bfbe-b826895d****"
      app_name = "app-slb"
      endpoint = "http://121.43.XXX.XX:8000"
      namespace_id = "cn-hangzhou:demo"
    已成功创建绑定了SLB的应用app-slb,并输出了SLB的IP地址和端口。
  6. 验证结果。
    在浏览器中输入SLB的IP地址和端口,例如http://121.43.XXX.XX:8000,回车进入应用首页。sc_terraform_slb_test

解绑SLB并删除应用

本示例以在华东1(杭州)地域下的应用app-slb为例,介绍如何解绑SLB并删除应用。

  1. 在目标项目目录内执行以下命令,运行配置文件。
    terraform destroy
  2. 根据提示依次输入应用的各项信息,删除应用。
    • app_name:输入app-slb
    • image_url:输入registry.cn-hangzhou.aliyuncs.com/****/****:01
      镜像地址格式如下:
      registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>

      您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面查看镜像地址。

    • namespace_id:命名空间ID。输入cn-hangzhou:demo
    • namespace_name:命名空间名称。输入demo
    预期输出:
    ...
    
    alicloud_sae_namespace.default: Refreshing state... [id=cn-hangzhou:demo]
    module.vpc.alicloud_vpc.vpc[0]: Refreshing state... [id=vpc-bp1dmztolc522gckb****]
    ...
    alicloud_sae_load_balancer_internet.example: Refreshing state... [id=422e0338-04f4-442d-bfbe-b826895d****]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      - destroy
    
    ...
    
    Plan: 0 to add, 0 to change, 8 to destroy.
    
    Changes to Outputs:
      - app_id       = "422e0338-04f4-442d-bfbe-b826895d****" -> null
      - app_name     = "app-slb" -> null
      - endpoint     = "http://121.43.XXX.XX:8000" -> null
      - namespace_id = "cn-hangzhou:demo" -> null
    alicloud_security_group_rule.sg_rule: Destroying... [id=sg-bp1bmslkl1itv94n****:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]
    ...
    module.vpc.alicloud_vpc.vpc[0]: Destroying... [id=vpc-bp1dmztolc522gckb****]
    module.vpc.alicloud_vpc.vpc[0]: Destruction complete after 6s
    
    Destroy complete! Resources: 8 destroyed.
    已成功解绑SLB并删除应用app-slb