使用Terraform实现SAE应用自动弹性

更新时间:2025-03-06 02:44:54

在分布式应用管理中,弹性伸缩是很重要的运维能力,它能够根据实例状态自动增加或减少实例数量,即扩容或缩容,从而提高资源利用率、降低资源成本。本文介绍如何通过TerraformSAE应用启停弹性策略。

背景信息

SAE自动弹性伸缩策略包括定时弹性伸缩策略、监控指标弹性伸缩策略和混合弹性伸缩策略。通过TerraformSAE应用启用弹性策略的实质,是在创建应用时配置alicloud_sae_application_scaling_rule资源。如需停用弹性策略,您需要同时删除弹性策略和应用。关于如何设置时间周期,请参见使用Crontab表达式

适用场景

  • 定时弹性策略:适用于资源使用率有周期性规律的应用场景,多用于证券、医疗、政府和教育等行业。

  • 监控指标弹性策略:适用于突发流量和典型周期性流量的应用场景,多用于互联网、游戏和社交平台等行业。

  • 混合弹性策略:适用于兼备资源使用率有周期性规律和有突发流量、典型周期性流量的应用场景,多用于互联网、教育和餐饮等行业。

更多信息,请参见配置弹性伸缩策略

说明

当前示例代码支持一键运行,您可以直接运行代码。一键运行

前提条件

  • 由于阿里云账号(主账号)具有资源的所有权限,一旦发生泄露将面临重大风险。建议您使用RAM用户,并为该RAM用户创建AccessKey,具体操作方式请参见创建RAM用户创建AccessKey

  • 为运行Terraform命令的RAM用户绑定以下最小权限策略,以获取管理本示例所涉及资源的权限。更多信息,请参见通过脚本编辑模式创建自定义权限策略

    该自定义权限策略允许RAM用户或角色对Serverless Application Engine (SAE) 应用程序进行全生命周期管理,包括创建、更新、删除、启动、停止、部署、回滚以及管理自动伸缩规则。

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sae:CreateApplication",
            "sae:UpdateApplication",
            "sae:DeleteApplication",
            "sae:GetApplication",
            "sae:ListApplications",
            "sae:CreateScalingRule",
            "sae:UpdateScalingRule",
            "sae:DeleteScalingRule",
            "sae:GetScalingRule",
            "sae:ListScalingRules",
            "sae:StartApplication",
            "sae:StopApplication",
            "sae:DeployApplication",
            "sae:RollbackApplication"
          ],
          "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:适用于网络连接较差或需要自定义开发环境的场景。

使用的资源

启用定时弹性策略

本示例以在华南1(深圳)地域下创建应用为例,介绍如何通过自定义配置,以镜像方式部署应用并为应用配置一条定时弹性策略。

弹性策略内容如下:周期设为每天,第一段触发点的开始时间为19:35,目标实例数为5个;第二段触发点的开始时间为20:35,目标实例数为2个。则在19:3520:35之间,SAE依据所设的规则,将该应用的实例数保持为5个,在20:35至次日19:35之间,应用实例数保持为2个。

  1. 创建一个用于存放Terraform资源的项目文件夹,命名为terraform
  2. 执行以下命令,进入项目目录。

    cd terraform
  3. 创建名为main.tf的配置文件。

    # 提供商配置
    provider "alicloud" {
      region = var.region_id
    }
    
    # 变量定义
    variable "region_id" {
      type    = string
      default = "cn-shenzhen"
    }
    
    variable "app_name" {
      description = "应用名称"
      type        = string
      default     = "app-scaling"
    }
    
    variable "image_url" {
      description = "镜像地址"
      type        = string
      default     = "registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9"
    }
    
    variable "namespace_name" {
      description = "命名空间名称"
      type        = string
      default     = "demo"
    }
    
    variable "namespace_id" {
      description = "命名空间ID"
      type        = string
      default     = "cn-shenzhen: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.0.0.0/16"
    }
    
    # VSwitch
    resource "alicloud_vswitch" "default" {
      vswitch_name = var.name
      cidr_block   = "10.0.1.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" "default" {
      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
    }
    
    # 弹性伸缩策略
    resource "alicloud_sae_application_scaling_rule" "metrics" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "metric-dev"
      scaling_rule_enable = true
      scaling_rule_type   = "mix"
    
      scaling_rule_timer {
        begin_date = "2024-11-26"
        end_date   = "2024-11-30"
        period     = "* * *"
        schedules {
          at_time      = "19:45"
          max_replicas = 50
          min_replicas = 10
        }
        schedules {
          at_time      = "20:45"
          max_replicas = 40
          min_replicas = 3
        }
      }
    
      scaling_rule_metric {
        max_replicas = 40
        min_replicas = 3
        metrics {
          metric_type                       = "CPU"
          metric_target_average_utilization = 1
        }
        scale_up_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 0
        }
        scale_down_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 10
        }
      }
    }
    
    # 其他变量定义
    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-e"
    }
    
    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 = alicloud_sae_namespace.default.id
      description = "Namespace ID"
    }
    
    output "app_id" {
      description = "The id of the application"
      value       = alicloud_sae_application.default.id
    }
    
    output "app_name" {
      description = "The name of the application"
      value       = var.app_name
    }
    
  4. 执行以下命令,初始化配置。

terraform init

预期结果:image

  1. 依次执行以下命令,创建应用。

  2. 执行以下命令,部署应用。在执行过程中,根据提示输入yes并按下Enter键,等待命令执行完成,若出现以下信息,则表示授权完成。

terraform apply

预期结果:image

  1. 结果验证

执行terraform show命令
Serverless应用引擎SAE控制台

您可以使用以下命令查询Terraform已创建的资源详细信息:

terraform show

image

已成功创建启用了弹性定时策略的应用app-scaling。您可以登录SAE控制台,在目标应用基本信息页面的实例部署信息页签查看弹性策略与应用实例的运行状态。

image

启用监控指标弹性策略

本示例基于配置了定时弹性策略的main.tf文件,仅将资源alicloud_sae_application_scaling_rule的内容从定时弹性策略替换为监控指标弹性策略,其余内容保持不变。具体操作,请参见启用定时弹性策略

# 弹性伸缩策略
resource "alicloud_sae_application_scaling_rule" "metrics" {
  app_id              = alicloud_sae_application.default.id
  scaling_rule_name   = "metric-dev"
  scaling_rule_enable = true
  scaling_rule_type   = "metric"
  scaling_rule_metric {
    max_replicas = 50
    min_replicas = 3
    metrics {
      metric_type                       = "CPU"
      metric_target_average_utilization = 1
    }
    scale_up_rules {
      step                         = 10
      disabled                     = false
      stabilization_window_seconds = 0
    }
    scale_down_rules {
      step                         = 10
      disabled                     = false
      stabilization_window_seconds = 10
    }
  }
}

本示例的弹性策略内容如下:当CPU使用率超过1%时扩容,应用最大实例数为50个;当CPU使用率低于1%时缩容,应用最小实例数为3个。

说明

示例代码为显示测试效果,设置了较低的CPU使用率,您在实际操作过程中可以按需设置合理的参数值。

  1. 执行以下命令,初始化配置。

terraform init

预期结果:image

  1. 依次执行以下命令,创建应用。

  2. 执行以下命令,部署应用。在执行过程中,根据提示输入yes并按下Enter键,等待命令执行完成,若出现以下信息,则表示授权完成。

terraform apply

预期结果:image

  1. 结果验证

执行terraform show命令
Serverless应用引擎SAE控制台

您可以使用以下命令查询Terraform已创建的资源详细信息:

terraform show

image

已成功创建启用了弹性定时策略的应用app-scaling。您可以登录SAE控制台,在目标应用基本信息页面的实例部署信息页签查看弹性策略与应用实例的运行状态。

image

启用混合弹性策略

本示例基于配置了定时弹性策略的main.tf文件,仅将资源alicloud_sae_application_scaling_rule的内容从定时弹性策略替换为混合弹性策略,其余内容保持不变。具体操作,请参见启用定时弹性策略

示例代码如下:

resource "alicloud_sae_application_scaling_rule" "metrics" {
  app_id              = alicloud_sae_application.default.id
  scaling_rule_name   = "metric-dev"
  scaling_rule_enable = true
  scaling_rule_type   = "mix"

  scaling_rule_timer {
    begin_date = "2022-04-20"
    end_date   = "2022-05-31"
    period     = "* * *"
    schedules {
      at_time      = "19:45"
      max_replicas = 50
      min_replicas = 10
    }
    schedules {
      at_time      = "20:45"
      max_replicas = 40
      min_replicas = 3
    }

  }
  scaling_rule_metric {
    max_replicas = 40
    min_replicas = 3
    metrics {
      metric_type                       = "CPU"
      metric_target_average_utilization = 1
    }
    scale_up_rules {
      step                         = 10
      disabled                     = false
      stabilization_window_seconds = 0
    }
    scale_down_rules {
      step                         = 10
      disabled                     = false
      stabilization_window_seconds = 10
    }
  }
}

本示例的弹性策略内容如下:

  • 一般时间段:当CPU使用率超过1%时扩容,应用最大实例数为40个;当CPU使用率低于1%时缩容,应用最小实例数为3个。

  • 特殊时间段:基于CPU阈值,在20241126日至20221130日执行定时弹性伸缩策略。

    • 19:4520:45之间,应用最小实例数为10个,应用最大实例数为50个。

    • 20:45至次日20:45之间,应用最小实例数为3个,应用最大实例数为40个。

说明

示例代码为显示测试效果,设置了较低的CPU使用率,您在实际操作过程中可以按需设置合理的参数值。

  1. 执行以下命令,初始化配置。

terraform init

预期结果:image

  1. 依次执行以下命令,创建应用。

  2. 执行以下命令,部署应用。在执行过程中,根据提示输入yes并按下Enter键,等待命令执行完成,若出现以下信息,则表示授权完成。

terraform apply

预期结果:image

  1. 结果验证

执行terraform show命令
Serverless应用引擎SAE控制台

您可以使用以下命令查询Terraform已创建的资源详细信息:

terraform show

image

已成功创建启用了弹性定时策略的应用app-scaling。您可以登录SAE控制台,在目标应用基本信息页面的实例部署信息页签查看弹性策略与应用实例的运行状态。

image

删除弹性策略和应用

本示例以在华东1(杭州)地域下的应用app-scaling为例,介绍如何停用弹性策略并删除应用。

  1. 在目标项目目录内执行以下命令,运行配置文件。
    terraform destroy
  2. 预期结果:image

    已成功停用弹性策略并删除应用app-scaling

    完整代码

    说明

    当前示例代码支持一键运行,您可以直接运行代码。一键运行

    # 提供商配置
    provider "alicloud" {
      region = var.region_id
    }
    
    # 变量定义
    variable "region_id" {
      type    = string
      default = "cn-shenzhen"
    }
    
    variable "app_name" {
      description = "应用名称"
      type        = string
      default     = "app-scaling"
    }
    
    variable "image_url" {
      description = "镜像地址"
      type        = string
      default     = "registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9"
    }
    
    variable "namespace_name" {
      description = "命名空间名称"
      type        = string
      default     = "demo"
    }
    
    variable "namespace_id" {
      description = "命名空间ID"
      type        = string
      default     = "cn-shenzhen: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.0.0.0/16"
    }
    
    # VSwitch
    resource "alicloud_vswitch" "default" {
      vswitch_name = var.name
      cidr_block   = "10.0.1.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" "default" {
      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
    }
    
    # 弹性伸缩策略
    resource "alicloud_sae_application_scaling_rule" "metrics" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "metric-dev"
      scaling_rule_enable = true
      scaling_rule_type   = "mix"
    
      scaling_rule_timer {
        begin_date = "2024-11-26"
        end_date   = "2024-11-30"
        period     = "* * *"
        schedules {
          at_time      = "19:45"
          max_replicas = 50
          min_replicas = 10
        }
        schedules {
          at_time      = "20:45"
          max_replicas = 40
          min_replicas = 3
        }
      }
    
      scaling_rule_metric {
        max_replicas = 40
        min_replicas = 3
        metrics {
          metric_type                       = "CPU"
          metric_target_average_utilization = 1
        }
        scale_up_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 0
        }
        scale_down_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 10
        }
      }
    }
    
    # 其他变量定义
    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-e"
    }
    
    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 = alicloud_sae_namespace.default.id
      description = "Namespace ID"
    }
    
    output "app_id" {
      description = "The id of the application"
      value       = alicloud_sae_application.default.id
    }
    
    output "app_name" {
      description = "The name of the application"
      value       = var.app_name
    }
    

    相关文档

  • 本页导读 (1)
  • 背景信息
  • 适用场景
  • 前提条件
  • 使用的资源
  • 启用定时弹性策略
  • 启用监控指标弹性策略
  • 启用混合弹性策略
  • 删除弹性策略和应用
  • 完整代码
  • 相关文档
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等