全部产品
Search
文档中心

资源编排:使用伸缩组管理多台云服务器ECS

更新时间:Sep 15, 2026

本文以使用伸缩组管理多台云服务器ECS为例,由简入难地向您介绍如何编辑ROS模板。

方案概述

本方案使用阿里云资源编排服务(ROS)通过 YAML 模板,一次性创建 VPC 网络、多台 ECS 实例和弹性伸缩组(ESS),并将 ECS 实例纳入伸缩组管理,实现根据业务负载自动扩容或缩容。适用于需要弹性管理服务器集群的 Web 应用、微服务等场景。

业务场景

在阿里云专有网络(VPC)中批量创建 ECS 实例并加入伸缩组,配置伸缩规则后,伸缩组可根据业务负载自动增减 ECS 实例数量,实现服务器集群的弹性管理。

创建的资源清单

序号

资源名称

ROS 资源类型

用途说明

1

专有网络 VPC

ALIYUN::ECS::VPC

提供隔离的网络环境。

2

交换机 VSwitch

ALIYUN::ECS::VSwitch

在 VPC 中划分子网网段,指定可用区。

3

安全组 SecurityGroup

ALIYUN::ECS::SecurityGroup

控制 ECS 的网络访问规则(入站/出站)。

4

ECS 实例组 InstanceGroup

ALIYUN::ECS::InstanceGroup

批量创建多台 ECS 云服务器(初始节点)。

5

伸缩组 ScalingGroup

ALIYUN::ESS::ScalingGroup

管理 ECS 实例的弹性伸缩策略(最小/最大实例数)。

6

伸缩配置 ScalingConfiguration

ALIYUN::ESS::ScalingConfiguration

定义伸缩组扩容时新建 ECS 的规格模板。

7

伸缩组启用 ScalingGroupEnable

ALIYUN::ESS::ScalingGroupEnable

启用伸缩组并将已有 ECS 实例加入伸缩组。

部署完成后获得的结果

模板成功执行后,将获得:

  • 一个完整的 VPC 网络环境(包含 VPC、交换机、安全组)。

  • 一组 ECS 云服务器实例(数量由参数 ECSInstanceGroupCount 指定,默认 3 台)。

  • 一个已激活的弹性伸缩组,包含伸缩配置,可根据负载自动扩容至最大实例数。

  • 所有 ECS 实例已自动加入伸缩组统一管理。

架构图

image

前提条件

在使用本模板前,请确认以下条件:

  1. 账号权限:阿里云账号需具有以下产品的创建权限:ECS、ESS(弹性伸缩)、VPC。

  2. 基础知识:了解 ROS 模板的基本语法和结构,请参见模板快速入门。

模板编写教程

本教程分两个阶段演示模板编写过程:

  • 阶段一(基础版):使用固定参数值,专注于理解资源定义和依赖关系。

  • 阶段二(进阶版):参数化所有可变配置,添加动态参数筛选和参数分组。

阶段一:基础模板——定义资源及其依赖关系

Step 1:定义基础网络资源(VPC + VSwitch + 安全组)

网络资源是所有其他资源的基础,需要最先创建。

Resources:
  # ============================================================
  # 基础网络层:VPC → VSwitch → SecurityGroup
  # ============================================================

  Vpc:
    Type: ALIYUN::ECS::VPC  # 创建专有网络
    Properties:
      CidrBlock: 192.168.0.0/16  # VPC地址段,可容纳65534个内网IP
      VpcName:
        Ref: ALIYUN::StackName  # 伪参数:使用资源栈名称作为VPC名称

  VSwitch:
    Type: ALIYUN::ECS::VSwitch  # 在VPC中创建交换机(子网)
    Properties:
      VSwitchName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc  # Ref引用资源:返回Vpc的VpcId(隐式依赖,ROS会先创建Vpc)
      ZoneId: cn-beijing-h # 此场景以北京H可用区为示例
      CidrBlock: 192.168.0.0/24  # 子网地址段,必须是VPC地址段的子集

  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup  # 创建安全组
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc  # 安全组绑定到同一VPC
      # 入站规则:为简化示例开放所有入站流量,生产环境请按需收紧端口
      SecurityGroupIngress:
        - PortRange: '-1/-1'
          Priority: 1
          IpProtocol: all
          SourceCidrIp: 0.0.0.0/0
          NicType: intranet

关键知识点:

  • 类似 VpcName、VSwitchName、SecurityGroupName 这类自定义配置可以使用伪参数进行配置,这样可以在部署资源后快速找到属于该资源栈部署的相关资源。

  • SecurityGroup 的访问规则可以根据业务需求自定义配置,例如:

    • 需要在外部访问 Web 服务,可配置开启安全组入方向的 HTTP 80 或 8080 端口访问。

    • 需要 SSH 登录服务器,可配置开启安全组入方向的 22 端口访问。

Step 2:定义 ECS 实例组资源

使用 ALIYUN::ECS::InstanceGroup 可以一次创建多台相同配置的 ECS 实例,比多次使用 ALIYUN::ECS::Instance 更高效。

Resources:
  # ============================================================
  # 计算层:批量创建ECS实例
  # ============================================================

  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup  # 批量创建ECS实例
    Properties:
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      VSwitchId:
        Ref: VSwitch
      ImageId: centos_7_9_x64_20G_alibase_20220727.vhd  # CentOS 7.9镜像
      AllocatePublicIP: false  # 不分配公网IP
      InstanceType: ecs.c5.large  # 实例规格:2vCPU 4GiB
      SystemDiskSize: 200  # 系统盘200GiB
      SystemDiskCategory: cloud_essd  # ESSD云盘
      MaxAmount: 3  # 创建3台ECS实例
      Password: <YourPassword>  # 部署时请替换为实际密码(需含大小写字母+数字+特殊字符)
      InstanceName:  # 实例名称:使用栈名+序号,如 mystack-0001
        Fn::Sub:
           - ${StackName}-[1,4]
           - StackName:
               Ref: ALIYUN::StackName

关键知识点与思考:

  • ALIYUN::ECS::InstanceGroup 通过 MaxAmount 属性指定创建的 ECS 实例数量。

  • Fn::Sub 函数用于字符串拼接,[1,4] 是 ROS 特有的序号占位符,表示 4 位数字从 1 递增(如 0001、0002...)。

  • 该资源的输出属性 InstanceIds 是一个 ECS 实例 ID 列表,可被伸缩组引用。

Step 3:定义伸缩组资源(伸缩组 + 伸缩配置 + 启用伸缩配置)

伸缩组由三个资源协同工作:ScalingGroup 定义伸缩策略,ScalingConfiguration 定义扩容时的 ECS 模板,ScalingGroupEnable 启用伸缩组并加入已有实例。

Resources:
  # ============================================================
  # 弹性伸缩层:伸缩组 + 伸缩配置 + 启用伸缩组
  # ============================================================

  EssInstanceScalingGroup:
    Type: ALIYUN::ESS::ScalingGroup  # 创建伸缩组
    Properties:
      ScalingGroupName:
        Ref: ALIYUN::StackName
      RemovalPolicys:
        - NewestInstance  # 缩容策略:优先移除最新创建的实例
      MinSize: 3  # 伸缩组最少保持3台实例
      MaxSize: 50  # 伸缩组最多可扩容至50台实例
      VSwitchId:
        Ref: VSwitch  # 伸缩组绑定交换机(决定扩容实例的网络位置)
      DefaultCooldown: 300  # 冷却时间300秒,避免频繁触发伸缩

  EssInstanceScalingConfiguration:
    Type: ALIYUN::ESS::ScalingConfiguration  # 伸缩配置(扩容时的ECS模板)
    Properties:
      SecurityGroupId:
        Ref: EcsSecurityGroup
      ScalingGroupId:
        Ref: EssInstanceScalingGroup  # 关联到上方的伸缩组
      ScalingConfigurationName:
        Fn::Sub: sc-${ALIYUN::StackName}  # Fn::Sub直接替换伪参数变量
      InstanceType: ecs.c5.large  # 扩容时创建的ECS规格(应与初始ECS一致)
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 200
      ImageId: centos_7_9_x64_20G_alibase_20220727.vhd  # 扩容时使用的镜像(应与初始ECS一致)

  EssInstanceScalingGroupEnable:
    Type: ALIYUN::ESS::ScalingGroupEnable  # 启用伸缩组
    Properties:
      ScalingRuleArisExecuteVersion: '1'
      ScalingConfigurationId:
        Ref: EssInstanceScalingConfiguration  # 指定生效的伸缩配置
      InstanceIds:
        # 将Step 2中创建的ECS实例加入伸缩组
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds  # 获取InstanceGroup的所有实例ID列表
      ScalingGroupId:
        Ref: EssInstanceScalingGroup

关键知识点与思考:

  • 伸缩组的 MinSize 建议与 ECSInstanceGroupCount(初始创建的实例数)保持一致,避免启用后立即触发缩容。

  • 可以为伸缩组添加伸缩规则(ALIYUN::ESS::ScalingRule)和报警触发器(ALIYUN::ESS::AlarmTask),实现基于 CPU/内存等指标的自动伸缩。

  • Ref 和 Fn::GetAtt 的区别:

    • Ref 返回资源的主标识符(如 VPC 的 VpcId)。

    • Fn::GetAtt 返回资源的相关属性(如 EcsInstanceGroup 的 InstanceIds)。

基础版完整模板

以下是将上述三个步骤合并后的完整可用模板:

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: 创建VPC网络环境,批量部署ECS实例并加入伸缩组,实现弹性扩缩容管理
  en: Create VPC network, deploy ECS instance group and manage them with ESS scaling group

Resources:
  # === 基础网络层 ===
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
      VpcName:
        Ref: ALIYUN::StackName

  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      VSwitchName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      ZoneId: cn-beijing-h
      CidrBlock: 192.168.0.0/24

  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      # 入站规则:为简化示例开放所有入站流量,生产环境请按需收紧端口
      SecurityGroupIngress:
        - PortRange: '-1/-1'
          Priority: 1
          IpProtocol: all
          SourceCidrIp: 0.0.0.0/0
          NicType: intranet

  # === 计算层 ===
  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      VSwitchId:
        Ref: VSwitch
      ImageId: centos_7_9_x64_20G_alibase_20220727.vhd
      AllocatePublicIP: false
      InstanceType: ecs.c5.large
      SystemDiskSize: 200
      SystemDiskCategory: cloud_essd
      MaxAmount: 3
      Password: <YourPassword>  # 部署时请替换为实际密码
      InstanceName:
        Fn::Sub:
           - ${StackName}-[1,4]
           - StackName:
               Ref: ALIYUN::StackName

  # === 弹性伸缩层 ===
  EssInstanceScalingGroup:
    Type: ALIYUN::ESS::ScalingGroup
    Properties:
      ScalingGroupName:
        Ref: ALIYUN::StackName
      RemovalPolicys:
        - NewestInstance
      MinSize: 3
      MaxSize: 50
      VSwitchId:
        Ref: VSwitch
      DefaultCooldown: 300

  EssInstanceScalingConfiguration:
    Type: ALIYUN::ESS::ScalingConfiguration
    Properties:
      SecurityGroupId:
        Ref: EcsSecurityGroup
      ScalingGroupId:
        Ref: EssInstanceScalingGroup
      ScalingConfigurationName:
        Fn::Sub: sc-${ALIYUN::StackName}
      InstanceType: ecs.c5.large
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 200
      ImageId: centos_7_9_x64_20G_alibase_20220727.vhd

  EssInstanceScalingGroupEnable:
    Type: ALIYUN::ESS::ScalingGroupEnable
    Properties:
      ScalingRuleArisExecuteVersion: '1'
      ScalingConfigurationId:
        Ref: EssInstanceScalingConfiguration
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      ScalingGroupId:
        Ref: EssInstanceScalingGroup

Outputs:
  ECSInstanceIds:
    Label: ECS 实例 ID 列表
    Value:
      Fn::GetAtt:
        - EcsInstanceGroup
        - InstanceIds

关键知识点与思考:

  • 模板创建完资源后,可以通过模板的 Outputs 信息直接查询对应资源的内部属性信息,例如 ECS 实例 ID 列表。

阶段二:进阶模板——参数化与动态配置

基础版模板中 ECS 的 InstanceType、SystemDiskCategory、ImageId 和伸缩组的 MaxSize 等属性使用了固定值。当需要在不同地域或不同规格下复用模板时,需要多次修改模板内容。而模板中多个参数之间往往存在依赖关系。例如:ECS 实例规格受限于可用区(不同可用区有不同规格库存),系统盘类型又同时受限于可用区和实例规格。如果手动填写这些参数,很容易选到不可用的组合,导致部署失败。

通过以下优化,可以大幅提高模板的灵活性和可复用性:

  1. 参数化(Parameters):将可变配置抽取为参数,部署时动态填写。

  2. 动态参数筛选(AssociationProperty):让 ROS 控制台根据已选参数自动过滤可用选项。

  3. 参数分组(Metadata):在控制台上按逻辑分组展示参数,提升填写体验。

参数依赖关系图

以下以 ECS 实例规格、系统盘类型为例,展示参数之间的依赖链路:

VSwitchZoneId(可用区)  ← 基础参数,无前置依赖
    ├──→ ECSInstanceType(ECS实例规格)
    │             依赖:ZoneId
    │
    └──→ ECSDiskCategory(系统盘类型)
                  依赖:ZoneId + InstanceType

核心思路:先选可用区,再据此筛选 ECS 规格,最后根据可用区 + ECS 规格筛选磁盘类型。每一步都只展示当前条件下可用的选项,避免无效组合。

参数 AssociationProperty 原理详解

1. VSwitchZoneId — 可用区(基础参数)

定义 AssociationProperty 为 ALIYUN::ECS::ZoneId 列出当前地域下所有可用区。示例:

VSwitchZoneId:
    Type: String
    Label:
      zh-cn: 交换机可用区
      en: VSwitch Availability Zone
    Description:
      zh-cn: 选择交换机所在的可用区,ECS和伸缩组将部署在此可用区
      en: Select the availability zone for VSwitch, ECS and scaling group will be deployed here
    AssociationProperty: ALIYUN::ECS::ZoneId

此参数是后续所有参数的筛选基础,选择特定可用区后,其他参数的选项列表会随之更新。

2. ECSInstanceType — ECS 实例规格

定义 AssociationProperty 为 ALIYUN::ECS::Instance::InstanceType 列出可用的 ECS 实例规格,并通过关联 ${VSwitchZoneId} 筛选对应可用区下可用的实例规格。示例:

ECSInstanceType:
    Type: String
    Label:
      zh-cn: ECS实例规格
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${VSwitchZoneId}

不同可用区的实例规格库存不同。如果不过滤,可能选到该可用区无货的规格,导致创建失败。

3. ECSDiskCategory — 系统盘类型

定义 AssociationProperty 为 ALIYUN::ECS::Disk::SystemDiskCategory 列出可选的系统盘类型,并通过关联 ${VSwitchZoneId} 和 ${ECSInstanceType} 筛选对应可用区与 ECS 实例规格支持使用的 ECS 系统盘类型。示例:

ECSDiskCategory:
    Type: String
    Description:
      zh-cn: 选择系统盘类型。可选值:cloud_essd(ESSD云盘)、cloud_ssd(SSD云盘)、cloud_efficiency(高效云盘)
      en: "System disk type. Options: cloud_essd, cloud_ssd, cloud_efficiency"
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${VSwitchZoneId}
      InstanceType: ${ECSInstanceType}
    Label:
      en: System Disk Type
      zh-cn: 系统盘类型

系统盘类型的可用性同时取决于可用区(某些可用区不支持 ESSD)和实例规格(某些规格仅支持特定磁盘类型)。

动态参数筛选示例

以动态获取 ECS 实例规格与磁盘类型为例,配置 AssociationProperty 后的效果:

Parameters:
  VSwitchZoneId:
    Type: String
    Label:
      zh-cn: 交换机可用区
      en: VSwitch Availability Zone
    Description:
      zh-cn: 选择交换机所在的可用区,ECS和伸缩组将部署在此可用区
      en: Select the availability zone for VSwitch, ECS and scaling group will be deployed here
    AssociationProperty: ALIYUN::ECS::ZoneId
  ECSInstanceType:
    Type: String
    Label:
      zh-cn: ECS实例规格
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${VSwitchZoneId}
  ECSDiskCategory:
    Type: String
    Label:
      zh-cn: 系统盘类型
      en: System Disk Category
    Description:
      zh-cn: 选择系统盘类型。可选值:cloud_essd(ESSD云盘)、cloud_ssd(SSD云盘)、cloud_efficiency(高效云盘)
      en: "System disk type. Options: cloud_essd, cloud_ssd, cloud_efficiency"
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${VSwitchZoneId}
      InstanceType: ${ECSInstanceType}

参数 AssociationProperty 工作原理总结

用户在 ROS 控制台创建资源栈时,参数的选择过程是级联触发的:

  1. 选择可用区(VSwitchZoneId)。

  2. ECS 实例规格下拉框自动刷新,仅显示该可用区有库存的规格。

  3. 选择 ECS 实例规格后,系统盘类型下拉框自动刷新,仅显示该可用区与该规格共同支持的磁盘类型。

这样,每一步选择都只展示当前条件下可用的选项,从源头避免因参数组合无效导致的部署失败。

Metadata 参数分组

通过 Metadata 中的 ALIYUN::ROS::Interface 配置,可以将参数按逻辑分成多个组,每组带一个标题,控制台上会分组展示,填写体验大幅提升。

Metadata 语法结构
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:           # 参数分组列表(必填)
      - Parameters:            # 该组包含的参数名列表(必填)
          - 参数名1
          - 参数名2
        Label:                 # 分组标题(必填)
          default:
            zh-cn: 中文标题
            en: English Title

Metadata 语法规则:

  • ParameterGroups、Parameters、Label 都是必填项。

  • Parameters 中列出的参数名必须与模板 Parameters 段中定义的参数名完全一致。

  • 未出现在任何分组中的参数,会在控制台显示在未分组区域。

本场景的分组设计

本模板将 9 个参数按资源类型分成 3 个组:

┌─────────────────────────────────────────────┐
│  基础网络配置                                │
│  ├── 交换机可用区 (VSwitchZoneId)            │
│  ├── VPC网段 (VpcCidrBlock)                 │
│  └── 交换机网段 (VSwitchCidrBlock)           │
├─────────────────────────────────────────────┤
│  ECS实例配置                                 │
│  ├── ECS实例规格 (ECSInstanceType)           │
│  ├── ECS镜像ID (ECSImageId)                 │
│  ├── 系统盘类型 (ECSDiskCategory)            │
│  ├── ECS实例密码 (EcsInstancePassword)       │
│  └── ECS实例组数量 (ECSInstanceGroupCount)   │
├─────────────────────────────────────────────┤
│  ESS伸缩组配置                               │
│  └── 伸缩组最大实例数 (ESSGroupMaxSize)       │
└─────────────────────────────────────────────┘
Metadata 分组模板示例
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - VSwitchZoneId
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: 基础网络配置
            en: Network Configuration
      - Parameters:
          - ECSInstanceType
          - ECSDiskCategory
          - ECSImageId
          - EcsInstancePassword
          - ECSInstanceGroupCount
        Label:
          default:
            zh-cn: ECS实例配置
            en: ECS Instance Configuration
      - Parameters:
          - ESSGroupMaxSize
        Label:
          default:
            zh-cn: ESS伸缩组配置
            en: Scaling Group Configuration

进阶版完整模板

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: >-
    参数化模板:批量创建ECS实例并通过弹性伸缩组管理,支持自动扩缩容。
    支持动态选择可用区、实例规格、磁盘类型和镜像,适用于多地域复用。
  en: >-
    Parameterized template: Create ECS instance group managed by ESS scaling group.
    Supports dynamic selection of zone, instance type, disk category and image.

Parameters:
  # ─── 基础网络参数 ───
  VSwitchZoneId:
    Type: String
    Label:
      zh-cn: 交换机可用区
      en: VSwitch Availability Zone
    Description:
      zh-cn: 选择交换机所在的可用区,ECS和伸缩组将部署在此可用区
      en: Select the availability zone for VSwitch, ECS and scaling group will be deployed here
    AssociationProperty: ALIYUN::ECS::ZoneId

  VpcCidrBlock:
    Type: String
    Label:
      zh-cn: VPC网段
      en: VPC CIDR Block
    Description:
      zh-cn: VPC的IP地址段范围。推荐使用 10.0.0.0/8、172.16.0.0/12 或 192.168.0.0/16
      en: VPC IP address range. Recommended 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16
    Default: 192.168.0.0/16

  VSwitchCidrBlock:
    Type: String
    Label:
      zh-cn: 交换机网段
      en: VSwitch CIDR Block
    Description:
      zh-cn: 必须是VPC网段的子网段,且不能与同VPC下其他交换机网段重叠
      en: Must be a subnet of VPC CIDR and not overlap with other VSwitches
    Default: 192.168.0.0/24

  # ─── ECS实例参数 ───
  ECSInstanceType:
    Type: String
    Label:
      zh-cn: ECS实例规格
      en: ECS Instance Type
    Description:
      zh-cn: 选择ECS实例规格。列表已根据可用区自动过滤可用规格。
      en: Select ECS instance type. List is filtered by selected availability zone.
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${VSwitchZoneId}

  ECSDiskCategory:
    Type: String
    Label:
      zh-cn: 系统盘类型
      en: System Disk Category
    Description:
      zh-cn: 选择系统盘类型。可选值:cloud_essd(ESSD云盘)、cloud_ssd(SSD云盘)、cloud_efficiency(高效云盘)
      en: "System disk type. Options: cloud_essd, cloud_ssd, cloud_efficiency"
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${VSwitchZoneId}
      InstanceType: ${ECSInstanceType}

  ECSImageId:
    Type: String
    Label:
      zh-cn: ECS镜像ID
      en: Image ID
    Description:
      zh-cn: 选择ECS实例使用的操作系统镜像
      en: Select the OS image for ECS instances
    AssociationProperty: ALIYUN::ECS::Image::ImageId

  ECSInstanceGroupCount:
    Type: Number
    Label:
      zh-cn: ECS初始实例数量
      en: Initial Instance Count
    Description:
      zh-cn: 初始创建的ECS实例数量,这些实例将加入伸缩组管理
      en: Number of ECS instances to create initially, they will be added to scaling group
    Default: 3

  EcsInstancePassword:
    Type: String
    NoEcho: true
    Label:
      zh-cn: ECS实例密码
      en: ECS Instance Password
    Description:
      zh-cn: 长度8-30位,需包含大写字母、小写字母、数字、特殊字符中的至少三种
      en: Length 8-30, must contain at least three of uppercase, lowercase, digits, special characters
    MinLength: 8
    MaxLength: 30
    AssociationProperty: ALIYUN::ECS::Instance::Password

  # ─── 伸缩组参数 ───
  ESSGroupMaxSize:
    Type: Number
    Label:
      zh-cn: 伸缩组最大实例数
      en: Scaling Group Max Size
    Description:
      zh-cn: 伸缩组内ECS实例的最大数量,达到此上限后不再自动扩容
      en: Maximum number of ECS instances in scaling group
    Default: 50

Resources:
  # === 基础网络层 ===
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock:
        Ref: VpcCidrBlock
      VpcName:
        Ref: ALIYUN::StackName

  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      VSwitchName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      ZoneId:
        Ref: VSwitchZoneId
      CidrBlock:
        Ref: VSwitchCidrBlock

  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      # 入站规则:仅开放8080端口(Web应用),生产环境请根据业务需求调整
      SecurityGroupIngress:
        - PortRange: 8080/8080
          Priority: 1
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
          NicType: internet
      SecurityGroupEgress:
        - PortRange: '-1/-1'
          Priority: 1
          IpProtocol: all
          DestCidrIp: 0.0.0.0/0
          NicType: internet
        - PortRange: '-1/-1'
          Priority: 1
          IpProtocol: all
          DestCidrIp: 0.0.0.0/0
          NicType: intranet

  # === 计算层 ===
  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      InstanceName:
        Fn::Sub:
           - ${StackName}-[1,4]
           - StackName:
               Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: EcsSecurityGroup
      SystemDiskCategory:
        Ref: ECSDiskCategory
      SystemDiskSize: 200
      MaxAmount:
        Ref: ECSInstanceGroupCount
      ImageId:
        Ref: ECSImageId
      InstanceType:
        Ref: ECSInstanceType
      Password:
        Ref: EcsInstancePassword
      AllocatePublicIP: false

  # === 弹性伸缩层 ===
  EssInstanceScalingGroup:
    Type: ALIYUN::ESS::ScalingGroup
    Properties:
      ScalingGroupName:
        Ref: ALIYUN::StackName
      RemovalPolicys:
        - NewestInstance
      MinSize:
        Ref: ECSInstanceGroupCount
      MaxSize:
        Ref: ESSGroupMaxSize
      VSwitchId:
        Ref: VSwitch
      DefaultCooldown: 300

  EssInstanceScalingConfiguration:
    Type: ALIYUN::ESS::ScalingConfiguration
    Properties:
      SecurityGroupId:
        Ref: EcsSecurityGroup
      ScalingGroupId:
        Ref: EssInstanceScalingGroup
      ScalingConfigurationName:
        Fn::Sub: sc-${ALIYUN::StackName}
      InstanceType:
        Ref: ECSInstanceType
      SystemDiskCategory:
        Ref: ECSDiskCategory
      SystemDiskSize: 200
      ImageId:
        Ref: ECSImageId
      InstanceName:
        Fn::Sub:
           - ${StackName}-[index,1,4]
           - StackName:
               Ref: ALIYUN::StackName

  EssInstanceScalingGroupEnable:
    Type: ALIYUN::ESS::ScalingGroupEnable
    Properties:
      ScalingRuleArisExecuteVersion: '1'
      ScalingConfigurationId:
        Ref: EssInstanceScalingConfiguration
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      ScalingGroupId:
        Ref: EssInstanceScalingGroup

Outputs:
  ECSInstanceIds:
    Label: ECS 实例 ID 列表
    Value:
      Fn::GetAtt:
        - EcsInstanceGroup
        - InstanceIds

# === 元数据:控制台参数分组配置 ===
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - VSwitchZoneId
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: 基础网络配置
            en: Network Configuration
      - Parameters:
          - ECSInstanceType
          - ECSDiskCategory
          - ECSImageId
          - EcsInstancePassword
          - ECSInstanceGroupCount
        Label:
          default:
            zh-cn: ECS实例配置
            en: ECS Instance Configuration
      - Parameters:
          - ESSGroupMaxSize
        Label:
          default:
            zh-cn: 伸缩组配置
            en: Scaling Group Configuration

本模板使用的 ROS 内置函数速查

函数

语法示例

本模板中的用途

详细说明

Ref

Ref: MyVpc

引用参数值或资源主标识符。

引用 Parameter 返回参数值;引用 Resource 返回其主标识符。

Fn::GetAtt

Fn::GetAtt: [EcsInstanceGroup, InstanceIds]

获取 ECS 实例组的实例 ID 列表。

获取资源创建后的输出属性(非主标识符)。

Fn::Sub

Fn::Sub: sc-${ALIYUN::StackName}

拼接伸缩配置名称。

模板字符串中用 ${Var} 引用变量或伪参数。

部署环节

部署参数

必需输入参数(部署时需填写)

参数名

说明

约束

VSwitchZoneId

可用区 ID。

控制台动态选择。

ECSInstanceType

ECS 实例规格。

根据可用区自动过滤可用规格。

ECSDiskCategory

ECS 系统盘类型。

根据可用区与规格自动过滤。

ECSImageId

ECS 镜像 ID。

控制台动态选择。

可选配置参数(有默认值,可不填)

参数名

默认值

说明

VpcCidrBlock

192.168.0.0/16

VPC 网段地址范围。

VSwitchCidrBlock

192.168.0.0/24

交换机子网网段。

ECSInstanceGroupCount

3

初始创建的 ECS 实例数量。

ESSGroupMaxSize

50

ESS 伸缩组最大实例数。

EcsInstancePassword

无

ECS 实例登录密码,长度 8-30,需含大小写、数字、特殊字符中至少三种。

部署方式

方式一:通过 ROS 控制台部署

  1. 登录资源编排控制台。

  2. 在左侧导航栏选择资源栈 > 创建资源栈。

  3. 选择选择已有模板 > 输入模板,将完整模板粘贴到编辑器中。

  4. 单击下一步,按参数分组填写各项配置参数。

  5. 确认配置后单击创建,等待资源栈状态变为 CREATE_COMPLETE。

方式二:通过 ROS IaC Code 部署

IaC Code 是面向云基础设施的 AI 基础设施即代码助手,通过自然语言提示词生成、部署和管理基础设施模板。架构设计面向多云工作流。以下为本方案的参考提示词:

# Prompt
帮我部署一组ECS实例并使用弹性伸缩组进行管理,要求:
1.使用新建的VPC和VSwitch
2.初始创建3台ECS实例加入伸缩组
3.伸缩组最大实例数50,最小实例数3
4.缩容策略为优先移除最新实例
5.安全组开放入方向8080端口
6.VSwitchZoneId、ECSInstanceType、ECSDiskCategory、ECSImageId都需要使用AssociationProperty配置成控制台动态筛选方式

常见问题

Q1:部署失败,报错 "The specified InstanceType is not available in the zone"

原因:所选 ECS 实例规格在指定可用区中没有库存。

解决方案:

  • 在进阶版模板中,AssociationProperty 会自动过滤可用规格,避免此问题。

  • 如果使用基础版模板,请前往 云服务器ECS定价确认目标可用区的规格库存,或更换可用区。

Q2:伸缩组启用后立即触发缩容

原因:MinSize 设置值大于实际加入的实例数量,或实例加入失败。

解决方案:

  1. 确保 ECSInstanceGroupCount 的值大于等于伸缩组的 MinSize。

  2. 检查 ECS 实例是否正常 Running 状态。

  3. 确认实例与伸缩组在同一 VPC 或 VSwitch 中。

Q3:扩容时新建的 ECS 实例配置与预期不符

原因:ScalingConfiguration 中的配置(InstanceType、ImageId 等)与初始 ECS 实例的配置不一致。

解决方案:

  • 在进阶版模板中,ScalingConfiguration 的参数(如 InstanceType、ImageId)已引用与 EcsInstanceGroup 相同的参数,确保扩容配置一致。

  • 如需不同配置的扩容,可创建多个 ScalingConfiguration,通过权重控制比例。

Q4:如何实现基于 CPU 使用率的自动伸缩?

方案:在模板中添加伸缩规则和报警任务:

# 扩容规则:每次增加2台实例
ScaleOutRule:
  Type: ALIYUN::ESS::ScalingRule
  Properties:
    ScalingGroupId:
      Ref: EssInstanceScalingGroup
    ScalingRuleName: scale-out-2
    ScalingRuleType: SimpleScalingRule
    AdjustmentType: QuantityChangeInCapacity  # 按数量调整
    AdjustmentValue: 2  # 每次增加2台

# 报警触发器:CPU > 80% 时触发扩容
CpuAlarm:
  Type: ALIYUN::ESS::AlarmTask
  Properties:
    AlarmTaskName: cpu-high-alarm
    ScalingGroupId:
      Ref: EssInstanceScalingGroup
    MetricName: CpuUtilization
    Threshold: 80
    ComparisonOperator: '>='
    EvaluationCount: 3  # 连续3次采样超阈值才触发
    AlarmActions:
      - Fn::GetAtt:
          - ScaleOutRule
          - ScalingRuleAri

Q5:如何使用已有 VPC 而非新建?

方案:将 VPC 和 VSwitch 从 Resources 中移除,改为 Parameters传入:

Parameters:
  ExistingVpcId:
    Type: String
    Label:
      zh-cn: 已有VPC ID
    AssociationProperty: ALIYUN::ECS::VPC::VPCId
  ExistingVSwitchId:
    Type: String
    Label:
      zh-cn: 已有交换机ID
    AssociationProperty: ALIYUN::VPC::VSwitch::VSwitchId
    AssociationPropertyMetadata:
      VpcId: ${ExistingVpcId}

Q6:如何为伸缩组挂载 SLB 实现流量分发?

方案:在 ScalingGroup 的 Properties 中添加 LoadBalancerIds:

EssInstanceScalingGroup:
  Type: ALIYUN::ESS::ScalingGroup
  Properties:
    ScalingGroupName:
      Ref: ALIYUN::StackName
    RemovalPolicys:
      - NewestInstance
    MinSize:
      Ref: ECSInstanceGroupCount
    MaxSize:
      Ref: ESSGroupMaxSize
    VSwitchId:
      Ref: VSwitch
    DefaultCooldown: 300
    LoadBalancerIds:
      - Ref: MyLoadBalancer  # 引用已创建的SLB实例

伸缩组新增或移除实例时,会自动将实例添加到或移出 SLB 后端服务器组。

想要了解更多资源部署问题,可以查询常见问题合集。