Todos los productos
Search
Centro de documentos

Resource Orchestration Service:Crear un grupo de instancias ECS y vincularlo a una instancia CLB

Última actualización: Sep 04, 2026

Esta solución muestra cómo utilizar Alibaba Cloud Resource Orchestration Service (ROS) para crear un clúster de servicios web completo con una sola plantilla YAML. La plantilla aprovisiona una VPC, un grupo de instancias ECS con Nginx instalado, un Classic Load Balancer (CLB) y una dirección IP elástica (EIP) en una única creación de pila. Esta solución es ideal para escenarios que requieren un despliegue rápido de clústeres de servicios web de alta disponibilidad (HA).

Descripción general de la solución

Escenario empresarial

Dentro de una virtual private cloud (VPC) de Alibaba Cloud, cree instancias ECS de forma masiva. Utilice ECS Cloud Assistant para instalar e iniciar Nginx automáticamente. Después de la inicialización, vincule las instancias ECS a una instancia CLB para la distribución del tráfico y exponga el endpoint de acceso HTTP mediante una EIP.

Recursos creados

N.º

Recurso

Tipo de recurso ROS

Propósito

1

VPC

ALIYUN::ECS::VPC

Proporciona un entorno de red aislado.

2

vSwitch

ALIYUN::ECS::VSwitch

Divide subredes dentro de la VPC y especifica zonas.

3

Security Group

ALIYUN::ECS::SecurityGroup

Abre el puerto HTTP de entrada 80 y permite todo el tráfico de salida.

4

Grupo de instancias ECS

ALIYUN::ECS::InstanceGroup

Crea varias instancias ECS y despliega Nginx automáticamente mediante CommandContent.

5

Instancia CLB

ALIYUN::SLB::LoadBalancer

Instancia de Classic Load Balancer que distribuye el tráfico a las instancias ECS del backend.

6

Listener CLB

ALIYUN::SLB::Listener

Configura el puerto del listener TCP/HTTP del CLB y las comprobaciones de estado.

7

Vinculación de servidor backend

ALIYUN::SLB::BackendServerAttachment

Vincula el grupo de instancias ECS al CLB como servidores backend.

8

EIP

ALIYUN::VPC::EIP

Proporciona un punto de entrada de acceso a la red pública.

9

Asociación de EIP

ALIYUN::VPC::EIPAssociation

Asocia la EIP con la instancia CLB.

Resultados esperados tras el despliegue

Una vez que la plantilla se despliega correctamente, obtendrá lo siguiente:

  • Un entorno de red VPC completo (que incluye VPC, vSwitch y security group con el puerto 80 abierto).

  • Un grupo de instancias ECS (2 instancias de forma predeterminada) con montaje de disco de datos y Nginx desplegado automáticamente.

  • Una instancia CLB configurada con un listener en el puerto TCP 80 y comprobaciones de estado.

  • Todas las instancias ECS vinculadas al grupo de servidores backend del CLB, con distribución de tráfico por peso.

  • Una EIP asociada al CLB, accesible mediante http://<EIP address>.

Diagrama de arquitectura

创建ECS实例组并挂载到CLB实例

Requisitos previos

Antes de utilizar esta plantilla, confirme lo siguiente:

  1. Permisos de la cuenta: Su cuenta de Alibaba Cloud debe tener permisos de creación para ECS, CLB, VPC y EIP.

  2. Conocimientos básicos: Familiaridad con la sintaxis y estructura básicas de las plantillas ROS. Para obtener más información, consulte ROS Template Getting Started.

Tutorial de escritura de plantillas

Este tutorial demuestra el proceso de escritura de plantillas en dos fases:

  • Fase 1 (Plantilla básica): Utiliza valores de parámetros fijos para centrarse en comprender las definiciones de recursos y las relaciones de vinculación del CLB.

  • Fase 2 (Plantilla avanzada): Parametriza todas las configuraciones variables y añade filtrado dinámico de parámetros, visualización condicional para el tipo de facturación y agrupación de parámetros.

Fase 1: Plantilla básica — Definir recursos y dependencias

Paso 1: Definir recursos de red básicos (VPC + vSwitch + security group)

Los recursos de red son la base para todos los demás recursos y deben crearse primero. El security group debe abrir el puerto HTTP de entrada 80 para permitir el acceso externo a Nginx.

Resources:
  # ============================================================
  # Network Layer: VPC → vSwitch → SecurityGroup
  # ============================================================

  Vpc:
    Type: ALIYUN::ECS::VPC  # Create a VPC
    Properties:
      CidrBlock: 192.168.0.0/16
      VpcName:
        Ref: ALIYUN::StackName  # Pseudo parameter: use the stack name as the VPC name

  VSwitch:
    Type: ALIYUN::ECS::VSwitch  # Create a vSwitch (subnet) within the VPC
    Properties:
      VSwitchName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc  # Implicit dependency: ROS creates Vpc first
      ZoneId: cn-beijing-h  # This example uses Beijing zone H
      CidrBlock: 192.168.0.0/24

  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup  # Create a security group
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      SecurityGroupIngress:  # Inbound rule: open HTTP port 80 for Nginx
        - PortRange: 80/80
          Priority: 1
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
          NicType: internet

Conceptos clave

  • Para nombres personalizados como VpcName, VSwitchName y SecurityGroupName, utilice pseudoparámetros para que, después del despliegue, pueda localizar rápidamente los recursos pertenecientes a esta pila.

  • Las reglas del security group se pueden personalizar según sus requisitos:

    • Para permitir el acceso externo a un servicio web, abra el puerto HTTP de entrada 80 u 8080.

    • Para permitir el inicio de sesión SSH, abra el puerto de entrada 22.

  • En entornos de producción, restrinja SourceCidrIp a rangos de IP conocidos en lugar de 0.0.0.0/0.

Paso 2: Definir recursos CLB y EIP

La instancia CLB distribuye el tráfico entrante a varias instancias ECS del backend. La EIP proporciona el punto de entrada público.

Resources:
  # ============================================================
  # Load Balancing Layer: CLB + Listener + EIP
  # ============================================================

  Slb:
    Type: ALIYUN::SLB::LoadBalancer  # Create a Classic Load Balancer instance
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      LoadBalancerName:
        Fn::Sub: slb-${ALIYUN::StackName}  # Fn::Sub concatenates strings
      AddressType: intranet  # Internal network CLB (public access via EIP)
      LoadBalancerSpec: slb.s1.small
      AutoPay: true

  SlbListener:
    Type: ALIYUN::SLB::Listener  # Configure CLB listener
    DependsOn:
      - Slb  # Explicit dependency: CLB must be created before adding a listener
    Properties:
      LoadBalancerId:
        Ref: Slb
      ListenerPort: 80          # Frontend listener port
      BackendServerPort: 80     # Backend server port (Nginx default: 80)
      Protocol: tcp             # Layer 4 TCP forwarding
      Bandwidth: -1             # -1 = unlimited; adjust based on CLB spec
      Persistence:              # Session persistence configuration
        StickySession: 'on'
        StickySessionType: insert  # Cookie insertion
        CookieTimeout: 60
        PersistenceTimeout: 180
      HealthCheck:              # Health check configuration
        HealthCheckType: tcp    # TCP port probe
        Port: 80
        Interval: 2             # Check interval: 2 seconds
        HealthyThreshold: 3     # 3 successes = healthy
        UnhealthyThreshold: 3   # 3 failures = unhealthy
        Timeout: 5              # Probe timeout: 5 seconds

  EipSlbAddress:
    Type: ALIYUN::VPC::EIP  # Create an EIP
    Properties:
      Name:
        Ref: ALIYUN::StackName
      InternetChargeType: PayByTraffic  # Pay by traffic
      Bandwidth: 10             # Bandwidth cap: 10 Mbps

  EipSlbAddressAssociation:
    Type: ALIYUN::VPC::EIPAssociation  # Associate EIP with CLB
    Properties:
      InstanceId:
        Ref: Slb                # Target: CLB instance
      AllocationId:
        Ref: EipSlbAddress      # EIP resource ID

Conceptos clave:

  • Dependencias implícitas frente a explícitas:

    • Cuando hace referencia a un recurso mediante Ref o Fn::GetAtt, ROS determina automáticamente la dependencia (implícita).

    • Utilice DependsOn solo cuando no exista una referencia directa entre dos recursos, pero la lógica empresarial requiera un orden de creación específico.

  • El CLB utiliza AddressType: intranet (red interna) y se vincula a una EIP mediante ALIYUN::VPC::EIPAssociation para proporcionar acceso público. Este es el patrón de arquitectura recomendado.

Paso 3: Definir ECS instance group y usar Cloud Assistant para instalar Nginx

Las instancias ECS ejecutan un script de inicialización a través de Cloud Assistant para montar el disco de datos e instalar Nginx.

Resources:
  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      VSwitchId:
        Ref: VSwitch
      ZoneId: cn-beijing-h
      ImageId: centos_7
      InstanceType: ecs.c5.large
      MaxAmount: 2       # Create 2 ECS instances
      AllocatePublicIP: false  # No public IP (access via CLB + EIP)
      IoOptimized: optimized
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 40
      DiskMappings:      # Data disk configuration
        - Category: cloud_essd
          Size: 100
      Password: <YourPassword>  # Replace with actual password during deployment

  RunSetup:
    Type: ALIYUN::ECS::RunCommand
    DependsOn: EcsInstanceGroup
    Properties:
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 300
      ContentEncoding: PlainText
      CommandContent: |
        #!/bin/bash
        # === Data disk initialization: partition, format, mount to /disk1 ===
        cat >> /root/InitDataDisk.sh << 'EOF'
        #!/bin/bash
        echo "p
        n
        p
        w
        " |  fdisk -u /dev/vdb
        EOF
        /bin/bash /root/InitDataDisk.sh
        rm -f /root/InitDataDisk.sh
        mkfs -t ext4 /dev/vdb1
        cp /etc/fstab /etc/fstab.bak
        mkdir /disk1
        echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab
        mount -a

        # === Install and start Nginx ===
        yum install -y nginx
        systemctl start nginx.service

Conceptos clave

  • Ref frente a Fn::GetAtt:

    • Ref → devuelve el identificador principal del recurso (por ejemplo, el VpcId de una VPC).

    • Fn::GetAtt → devuelve otros atributos del recurso (por ejemplo, los InstanceIds de un grupo de instancias ECS).

Paso 4: Definir backend server attachment del CLB — Conectar instancias ECS al CLB

Utilice ALIYUN::SLB::BackendServerAttachment para vincular el grupo de instancias ECS al backend del CLB.

Resources:
  # ============================================================
  # Binding Layer: Attach ECS instance group to CLB backend servers
  # ============================================================

  SlbBackendServerAttachment:
    Type: ALIYUN::SLB::BackendServerAttachment
    DependsOn:
      - EcsInstanceGroup  # Explicit dependency: wait for ECS creation
    Properties:
      LoadBalancerId:
        Ref: Slb
      BackendServerList:
        # Get all instance IDs from the ECS instance group
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      BackendServerWeightList:  # Backend server weight list
        - 100  # ECS instance 1: weight 100
        - 100  # ECS instance 2: weight 100

Conceptos clave: BackendServerWeightList Reglas

  • Los valores de peso oscilan entre 0 y 100. Se asignará más tráfico a la instancia con mayor peso.

  • Si BackendServerWeightList tiene menos entradas que BackendServerList, las instancias ECS restantes utilizan el último valor de peso de la lista.

Plantilla básica completa

A continuación se presenta la plantilla completa y lista para desplegar que combina todos los pasos anteriores:

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: Create VPC, deploy ECS with Nginx, attach to CLB, expose via EIP
  en: Create VPC, deploy ECS group with Nginx, attach to CLB, expose via EIP

Resources:
  # === Network Layer ===
  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: 80/80
          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

  # === Compute Layer ===
  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      VSwitchId:
        Ref: VSwitch
      ImageId: centos_7
      InstanceType: ecs.c5.large
      MaxAmount: 2
      AllocatePublicIP: false
      IoOptimized: optimized
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 40
      DiskMappings:
        - Category: cloud_essd
          Size: 100
      Password: <YourPassword>  # Replace with actual password during deployment
  RunSetup:
    Type: ALIYUN::ECS::RunCommand
    DependsOn: EcsInstanceGroup
    Properties:
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 300
      ContentEncoding: PlainText
      CommandContent: |
        #!/bin/bash
        # === Data disk initialization: partition, format, mount to /disk1 ===
        cat >> /root/InitDataDisk.sh << 'EOF'
        #!/bin/bash
        echo "p
        n
        p
        w
        " |  fdisk -u /dev/vdb
        EOF
        /bin/bash /root/InitDataDisk.sh
        rm -f /root/InitDataDisk.sh
        mkfs -t ext4 /dev/vdb1
        cp /etc/fstab /etc/fstab.bak
        mkdir /disk1
        echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab
        mount -a

        # === Install and start Nginx ===
        yum install -y nginx
        systemctl start nginx.service

  # === Load Balancing Layer ===
  Slb:
    Type: ALIYUN::SLB::LoadBalancer
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      LoadBalancerName:
        Fn::Sub: slb-${ALIYUN::StackName}
      AddressType: intranet
      LoadBalancerSpec: slb.s1.small
      AutoPay: true
  SlbListener:
    DependsOn:
      - Slb
    Type: ALIYUN::SLB::Listener
    Properties:
      LoadBalancerId:
        Ref: Slb
      ListenerPort: 80
      BackendServerPort: 80
      Protocol: tcp
      Bandwidth: -1
      Persistence:
        StickySession: 'on'
        StickySessionType: insert
        CookieTimeout: 60
        PersistenceTimeout: 180
      HealthCheck:
        HealthCheckType: tcp
        Port: 80
        Interval: 2
        HealthyThreshold: 3
        UnhealthyThreshold: 3
        Timeout: 5
  EipSlbAddress:
    Type: ALIYUN::VPC::EIP
    Properties:
      Name:
        Ref: ALIYUN::StackName
      InternetChargeType: PayByTraffic
      Bandwidth: 10
  EipSlbAddressAssociation:
    Type: ALIYUN::VPC::EIPAssociation
    Properties:
      InstanceId:
        Ref: Slb
      AllocationId:
        Ref: EipSlbAddress

  # === Binding Layer ===
  SlbBackendServerAttachment:
    DependsOn:
      - EcsInstanceGroup
    Type: ALIYUN::SLB::BackendServerAttachment
    Properties:
      BackendServerList:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      LoadBalancerId:
        Ref: Slb
      BackendServerWeightList:
        - 100
        - 100

Outputs:
  Endpoint:
    Description:
      zh-cn: Public HTTP endpoint
      en: Public HTTP endpoint
    Value:
      Fn::Sub:
        - http://${ServerAddress}
        - ServerAddress:
            Fn::GetAtt:
              - EipSlbAddress
              - EipAddress

Conceptos clave:

Después de que la plantilla cree los recursos, utilice la sección Outputs para consultar atributos de recursos como la dirección EIP vinculada al CLB.

Fase 2: Plantilla avanzada — Parametrización y configuración dinámica

La plantilla básica utiliza valores fijos para InstanceType de ECS, SystemDiskCategory y LoadBalancerSpec del CLB. Parametrizar estos valores mejora significativamente la flexibilidad de la plantilla.

Esta plantilla introduce las siguientes funciones avanzadas:

  1. Parametrización (Parameters) : Extrae configuraciones variables como parámetros que se completan dinámicamente durante el despliegue.

  2. Filtrado dinámico de parámetros (AssociationProperty): Permite que la consola ROS filtre automáticamente las opciones disponibles según los parámetros seleccionados.

  3. Agrupación de parámetros (Metadata): Agrupa los parámetros por categoría lógica en la consola para mejorar la experiencia de configuración.

Diagrama de dependencia de parámetros

A continuación se muestra la cadena de dependencias entre el tipo de instancia ECS, el tipo de disco del sistema y la especificación de la instancia CLB:

ZoneId (zone — core filter parameter)
  ├── EcsInstanceType (filtered by zone + billing type)
  │     ├── SystemDiskCategory (filtered by zone + instance type)
  │     └── DataDiskCategory (filtered by zone + instance type)
  └── LoadBalancerSpec (filtered by zone)

PayType (billing type)
  ├── PayPeriodUnit (shown only when PrePaid)
  ├── PayPeriod (shown only when PrePaid)
  └── EcsInstanceType (filtered by zone + billing type)

Lógica central: Seleccione primero la zona y el tipo de facturación de ECS, luego filtre los tipos de instancia ECS y las especificaciones del CLB en consecuencia. Cuando se selecciona la facturación por suscripción, proporcione la unidad y la duración del periodo de facturación. Finalmente, filtre los tipos de disco según la zona y el tipo de instancia ECS. Cada paso muestra solo las opciones válidas bajo las condiciones actuales, lo que evita combinaciones de parámetros no válidas.

Explicación de AssociationProperty

1. ZoneId — Zona de disponibilidad (Parámetro base)

Establezca AssociationProperty en ALIYUN::ECS::ZoneId para listar todas las zonas en la región actual:

ZoneId:
    Type: String
    Label:
      zh-cn: VSwitch Zone
      en: VSwitch Availability Zone
    Description:
      zh-cn: Select zone for VSwitch, ECS and CLB
      en: Select the availability zone for VSwitch, ECS and CLB will be deployed here
    AssociationProperty: ALIYUN::ECS::ZoneId

Este parámetro es la base de filtrado para todos los parámetros posteriores. Una vez seleccionada una zona, las listas de opciones para todos los demás parámetros se actualizan automáticamente.

2. PayType — Tipo de facturación de ECS

Defina el parámetro PayType y utilice AssociationPropertyMetadata.Visible.Condition para mostrar los parámetros de duración de facturación solo cuando se seleccione Subscription (PrePaid):

Parameters:
  PayType:
    Type: String
    Label:
      zh-cn: 付费类型
      en: Charge Type
    Default: PostPaid
    AllowedValues:
      - PostPaid
      - PrePaid
    AssociationProperty: ChargeType
    AssociationPropertyMetadata:
      LocaleKey: InstanceChargeType
  PayPeriodUnit:
    Type: String
    Default: Month
    AssociationProperty: PayPeriodUnit
    AssociationPropertyMetadata:
      Visible:  # Conditional display: show only when PayType is not PostPaid
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid
  PayPeriod:
    Type: Number
    Label:
      zh-cn: 购买资源时长
      en: Period
    Default: 1
    AllowedValues:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
      - 9
    AssociationProperty: PayPeriod
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid

Cuando se selecciona Subscription (PostPaid) en la consola ROS, los parámetros de duración de facturación se ocultan automáticamente. Aparecen solo cuando el usuario selecciona Subscription (PrePaid).

3. EcsInstanceType — Tipo de instancia ECS

Establezca AssociationProperty en ALIYUN::ECS::Instance::InstanceType para listar los tipos de instancia ECS disponibles, filtrados por ${ZoneId} y ${PayType}:

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

La disponibilidad del tipo de instancia varía según la zona. Sin filtrado, los usuarios podrían seleccionar un tipo de instancia sin inventario disponible en la zona seleccionada, lo que provocaría un error en la creación de la pila.

4. SystemDiskCategory — Tipo de disco del sistema

Establezca AssociationProperty en ALIYUN::ECS::Disk::SystemDiskCategory para listar los tipos de disco del sistema disponibles, filtrados por ${ZoneId} y ${EcsInstanceType}:

SystemDiskCategory:
    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: ${ZoneId}
      InstanceType: ${EcsInstanceType}

La disponibilidad del tipo de disco del sistema depende tanto de la zona (algunas zonas no admiten ESSD) como del tipo de instancia (algunos tipos de instancia solo admiten tipos de disco específicos).

5. LoadBalancerSpec — Especificación de instancia CLB

Establezca AssociationProperty en ALIYUN::SLB::Instance::InstanceType para listar las especificaciones CLB disponibles, filtradas por ${ZoneId}:

LoadBalancerSpec:
    Type: String
    Label:
      zh-cn: CLB实例规格
      en: CLB Instance Spec
    Description:
      zh-cn: 选择CLB实例规格,根据可用区自动过滤
      en: Select CLB instance specification
    AssociationProperty: ALIYUN::SLB::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}

Plantilla de filtrado dinámico de parámetros

Parameters:
  ZoneId:
    Type: String
    Label:
      zh-cn: 交换机可用区
      en: VSwitch Availability Zone
    Description:
      zh-cn: 选择交换机所在的可用区,ECS和CLB将部署在此可用区
      en: Select the availability zone for deployment
    AssociationProperty: ALIYUN::ECS::ZoneId
  PayType:
    Type: String
    Label:
      zh-cn: 付费类型
      en: Charge Type
    Default: PostPaid
    AllowedValues:
      - PostPaid
      - PrePaid
    AssociationProperty: ChargeType
    AssociationPropertyMetadata:
      LocaleKey: InstanceChargeType
  PayPeriodUnit:
    Type: String
    Default: Month
    AssociationProperty: PayPeriodUnit
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid
  PayPeriod:
    Type: Number
    Label:
      zh-cn: 购买资源时长
      en: Period
    Default: 1
    AllowedValues:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
      - 9
    AssociationProperty: PayPeriod
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid
  EcsInstanceType:
    Type: String
    Label:
      zh-cn: ECS实例规格
      en: ECS Instance Type
    Description:
      zh-cn: 选择ECS实例规格。列表已根据可用区和付费类型自动过滤。
      en: Select ECS instance type, filtered by zone and charge type.
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceChargeType: ${PayType}
  SystemDiskCategory:
    Type: String
    Label:
      zh-cn: 系统盘类型
      en: System Disk Category
    Description:
      zh-cn: 选择系统盘类型。可选值:cloud_essd(ESSD云盘)、cloud_ssd(SSD云盘)、cloud_efficiency(高效云盘)
      en: System disk type
    AssociationProperty: ALIYUN::ECS::Disk::SystemDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceType: ${EcsInstanceType}
  DataDiskCategory:
    Type: String
    Label:
      zh-cn: 数据盘类型
      en: Data Disk Category
    Description:
      zh-cn: 选择数据盘类型。可选值:cloud_essd、cloud_ssd、cloud_efficiency
      en: Data disk type
    AssociationProperty: ALIYUN::ECS::Disk::DataDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceType: ${EcsInstanceType}
  LoadBalancerSpec:
    Type: String
    Label:
      zh-cn: CLB实例规格
      en: CLB Instance Spec
    Description:
      zh-cn: 选择CLB实例规格,根据可用区自动过滤
      en: Select CLB instance specification
    AssociationProperty: ALIYUN::SLB::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}

Cómo funciona AssociationProperty

Cuando un usuario crea una pila en la consola ROS, la selección de parámetros se activa en cascada:

  1. Se selecciona una zona (ZoneId).

  2. Se selecciona el tipo de facturación de ECS (PayType).

  3. El menú desplegable de tipo de instancia ECS se actualiza automáticamente y muestra solo los tipos con inventario disponible en la zona seleccionada que admiten el tipo de facturación elegido.

  4. El menú desplegable de especificación de instancia CLB se actualiza automáticamente y muestra solo las especificaciones compatibles con la zona seleccionada.

  5. Después de seleccionar un tipo de instancia ECS, los menús desplegables de tipo de disco del sistema y tipo de disco de datos se actualizan automáticamente, mostrando solo los tipos compatibles tanto con la zona como con el tipo de instancia seleccionados.

Este enfoque garantiza que cada selección muestre solo opciones válidas bajo las condiciones actuales, evitando fallos de despliegue por combinaciones de parámetros no válidas desde el origen.

Agrupación de parámetros con Metadata

Al utilizar ALIYUN::ROS::Interface en Metadata, puede organizar los parámetros en grupos lógicos con etiquetas. La consola ROS muestra los parámetros en grupos, lo que mejora significativamente la experiencia de configuración.

Sintaxis de Metadata

Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:           # Parameter group list (required)
      - Parameters:            # List of parameter names in this group (required)
          - paramName1
          - paramName2
        Label:                 # Group label (required)
          default:
            zh-cn: Chinese label
            en: English label

Reglas de sintaxis de Metadata:

  • ParameterGroups, Parameters y Label son obligatorios.

  • Los nombres de parámetros listados en Metadata.ALIYUN::ROS::Interface.ParameterGroups.Parameters deben coincidir exactamente con los nombres definidos en la sección Parameters de la plantilla.

  • Los parámetros no incluidos en ningún grupo se muestran en el área sin agrupar de la consola.

Diseño de grupos de parámetros para esta plantilla

Esta plantilla organiza 14 parámetros en 4 grupos:

┌─────────────────────────────────────────────────┐
│  Network Configuration                          │
│  ├── VSwitch Availability Zone (ZoneId)         │
│  ├── VPC CIDR Block (VpcCidrBlock)              │
│  └── vSwitch CIDR Block (VSwitchCidrBlock)      │
├─────────────────────────────────────────────────┤
│  Billing Configuration                          │
│  ├── Charge Type (PayType)                      │
│  ├── Pay Period Unit (PayPeriodUnit)             │
│  └── Period (PayPeriod)                         │
├─────────────────────────────────────────────────┤
│  ECS Instance Configuration                     │
│  ├── ECS Instance Type (EcsInstanceType)        │
│  ├── System Disk Category (SystemDiskCategory)  │
│  ├── System Disk Size (SystemDiskSize)          │
│  ├── Data Disk Category (DataDiskCategory)      │
│  ├── Data Disk Size (DataDiskSize)              │
│  └── ECS Instance Password (InstancePassword)  │
├─────────────────────────────────────────────────┤
│  CLB Configuration                              │
│  ├── CLB Instance Spec (LoadBalancerSpec)       │
│  └── EIP Bandwidth (Bandwidth)                  │
└─────────────────────────────────────────────────┘

Plantilla de grupo de parámetros de Metadata

Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - ZoneId
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: Network Configuration
            en: Network Configuration
      - Parameters:
          - PayType
          - PayPeriodUnit
          - PayPeriod
        Label:
          default:
            zh-cn: Charge Type
            en: Billing Configuration
      - Parameters:
          - EcsInstanceType
          - SystemDiskCategory
          - SystemDiskSize
          - DataDiskCategory
          - DataDiskSize
          - InstancePassword
        Label:
          default:
            zh-cn: ECS Instance Configuration
            en: ECS Instance Configuration
      - Parameters:
          - LoadBalancerSpec
          - Bandwidth
        Label:
          default:
            zh-cn: CLB Configuration
            en: CLB Configuration

Plantilla avanzada completa

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: >-
    参数化模板:创建ECS实例组部署Nginx服务,挂载到CLB负载均衡器,通过EIP对外提供HTTP服务。
    支持动态选择可用区、实例规格、磁盘类型和CLB规格,支持按量/包年包月付费模式切换。
  en: >-
    Parameterized template: Create ECS group with Nginx, attach to CLB, expose via EIP.
    Supports dynamic selection and PayAsYouGo/Subscription billing switch.

Parameters:
  # ─── 基础网络参数 ───
  ZoneId:
    Type: String
    Label:
      zh-cn: 交换机可用区
      en: VSwitch Availability Zone
    Description:
      zh-cn: 选择交换机所在的可用区,ECS和CLB将部署在此可用区
      en: Select the availability zone for deployment
    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
    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
    Default: 192.168.0.0/24

  # ─── 付费类型参数 ───
  PayType:
    Type: String
    Label:
      zh-cn: 付费类型
      en: Charge Type
    Default: PostPaid
    AllowedValues:
      - PostPaid
      - PrePaid
    AssociationProperty: ChargeType
    AssociationPropertyMetadata:
      LocaleKey: InstanceChargeType

  PayPeriodUnit:
    Type: String
    Label:
      zh-cn: 购买资源时长周期
      en: Pay Period Unit
    Description:
      zh-cn: 包年包月的周期单位。Month为月,Year为年。仅包年包月时有效。
      en: Subscription period unit. Only valid for PrePaid.
    Default: Month
    AllowedValues:
      - Month
      - Year
    AssociationProperty: PayPeriodUnit
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid

  PayPeriod:
    Type: Number
    Label:
      zh-cn: 购买资源时长
      en: Period
    Default: 1
    AllowedValues:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
      - 9
    AssociationProperty: PayPeriod
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid

  # ─── ECS实例参数 ───
  EcsInstanceType:
    Type: String
    Label:
      zh-cn: ECS实例规格
      en: ECS Instance Type
    Description:
      zh-cn: 选择ECS实例规格。列表已根据可用区和付费类型自动过滤。
      en: Select ECS instance type, filtered by zone and charge type.
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceChargeType: ${PayType}

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

  SystemDiskSize:
    Type: Number
    Label:
      zh-cn: 系统盘大小(GB)
      en: System Disk Size (GB)
    Description:
      zh-cn: 系统盘大小,取值范围40~500 GB
      en: System disk size, range 40-500 GB
    Default: 40
    MinValue: 40
    MaxValue: 500

  DataDiskCategory:
    Type: String
    Label:
      zh-cn: 数据盘类型
      en: Data Disk Category
    Description:
      zh-cn: 选择数据盘类型。可选值:cloud_essd、cloud_ssd、cloud_efficiency
      en: Data disk type
    AssociationProperty: ALIYUN::ECS::Disk::DataDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceType: ${EcsInstanceType}

  DataDiskSize:
    Type: Number
    Label:
      zh-cn: 数据盘大小(GB)
      en: Data Disk Size (GB)
    Description:
      zh-cn: ECS数据盘大小,取值范围20~32768 GB
      en: Data disk size, range 20-32768 GB
    Default: 100
    MinValue: 20
    MaxValue: 32768

  InstancePassword:
    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 character types
    MinLength: 8
    MaxLength: 30
    AssociationProperty: ALIYUN::ECS::Instance::Password

  # ─── 负载均衡参数 ───
  LoadBalancerSpec:
    Type: String
    Label:
      zh-cn: CLB实例规格
      en: CLB Instance Spec
    Description:
      zh-cn: 选择CLB实例规格,根据可用区自动过滤
      en: Select CLB instance specification
    AssociationProperty: ALIYUN::SLB::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}

  Bandwidth:
    Type: Number
    Label:
      zh-cn: EIP带宽(Mbps)
      en: EIP Bandwidth (Mbps)
    Description:
      zh-cn: 弹性公网IP的带宽上限,取值范围1~1000 Mbps
      en: EIP bandwidth cap, range 1-1000 Mbps
    Default: 10
    MinValue: 1
    MaxValue: 1000

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: ZoneId
      CidrBlock:
        Ref: VSwitchCidrBlock
  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      SecurityGroupIngress:
        - PortRange: 80/80
          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:
      InstanceChargeType:
        Ref: PayType
      PeriodUnit:
        Ref: PayPeriodUnit
      Period:
        Ref: PayPeriod
      IoOptimized: optimized
      SystemDiskCategory:
        Ref: SystemDiskCategory
      SystemDiskSize:
        Ref: SystemDiskSize
      DiskMappings:
        - Category:
            Ref: DataDiskCategory
          Size:
            Ref: DataDiskSize
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      VSwitchId:
        Ref: VSwitch
      MaxAmount: 2
      ImageId: centos_7
      InstanceType:
        Ref: EcsInstanceType
      Password:
        Ref: InstancePassword
      AllocatePublicIP: false
  RunSetup:
    Type: ALIYUN::ECS::RunCommand
    DependsOn: EcsInstanceGroup
    Properties:
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 300
      ContentEncoding: PlainText
      CommandContent: |
        #!/bin/bash
        # === 数据盘初始化:分区、格式化、挂载到/disk1 ===
        cat >> /root/InitDataDisk.sh << 'EOF'
        #!/bin/bash
        echo "p
        n
        p
        w
        " |  fdisk -u /dev/vdb
        EOF
        /bin/bash /root/InitDataDisk.sh
        rm -f /root/InitDataDisk.sh
        mkfs -t ext4 /dev/vdb1
        cp /etc/fstab /etc/fstab.bak
        mkdir /disk1
        echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab
        mount -a

        # === 安装并启动Nginx ===
        yum install -y nginx
        systemctl start nginx.service

  # === 负载均衡层 ===
  Slb:
    Type: ALIYUN::SLB::LoadBalancer
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      LoadBalancerName:
        Fn::Sub: slb-${ALIYUN::StackName}
      PayType:
        Ref: PayType
      PricingCycle:
        Ref: PayPeriodUnit
      Duration:
        Ref: PayPeriod
      AddressType: intranet
      LoadBalancerSpec:
        Ref: LoadBalancerSpec
      AutoPay: true
  EipSlbAddress:
    Type: ALIYUN::VPC::EIP
    Properties:
      Name:
        Ref: ALIYUN::StackName
      InternetChargeType: PayByTraffic
      Bandwidth:
        Ref: Bandwidth
  EipSlbAddressAssociation:
    Type: ALIYUN::VPC::EIPAssociation
    Properties:
      InstanceId:
        Ref: Slb
      AllocationId:
        Ref: EipSlbAddress
  SlbBackendServerAttachment:
    DependsOn:
      - EcsInstanceGroup
    Type: ALIYUN::SLB::BackendServerAttachment
    Properties:
      BackendServerList:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      LoadBalancerId:
        Ref: Slb
      BackendServerWeightList:
        - 100
        - 100
  SlbListener:
    DependsOn:
      - Slb
    Type: ALIYUN::SLB::Listener
    Properties:
      LoadBalancerId:
        Ref: Slb
      ListenerPort: 80
      BackendServerPort: 80
      Protocol: tcp
      Bandwidth: -1
      Persistence:
        StickySession: 'on'
        StickySessionType: insert
        CookieTimeout: 60
        PersistenceTimeout: 180
      HealthCheck:
        HealthCheckType: tcp
        Port: 80
        Interval: 2
        HealthyThreshold: 3
        UnhealthyThreshold: 3
        Timeout: 5

Outputs:
  Endpoint:
    Description:
      zh-cn: 对外暴露的公网访问地址
      en: Public HTTP endpoint
    Value:
      Fn::Sub:
        - http://${ServerAddress}
        - ServerAddress:
            Fn::GetAtt:
              - EipSlbAddress
              - EipAddress

# === 元数据:控制台参数分组配置 ===
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - ZoneId
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: 基础网络配置
            en: Network Configuration
      - Parameters:
          - PayType
          - PayPeriodUnit
          - PayPeriod
        Label:
          default:
            zh-cn: 付费类型
            en: Billing Configuration
      - Parameters:
          - EcsInstanceType
          - SystemDiskCategory
          - SystemDiskSize
          - DataDiskCategory
          - DataDiskSize
          - InstancePassword
        Label:ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: >-
    参数化模板:创建ECS实例组部署Nginx服务,挂载到CLB负载均衡器,通过EIP对外提供HTTP服务。
    支持动态选择可用区、实例规格、磁盘类型和CLB规格,支持按量/包年包月付费模式切换。
  en: >-
    Parameterized template: Create ECS group with Nginx, attach to CLB, expose via EIP.
    Supports dynamic selection and PayAsYouGo/Subscription billing switch.

Parameters:
  # ─── Basic network parameters ───
  ZoneId:
    Type: String
    Label:
      zh-cn: 交换机可用区
      en: VSwitch Availability Zone
    Description:
      zh-cn: 选择交换机所在的可用区,ECS和CLB将部署在此可用区
      en: Select the availability zone for deployment
    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
    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
    Default: 192.168.0.0/24

  # ─── Paytype Paramters ───
  PayType:
    Type: String
    Label:
      zh-cn: 付费类型
      en: Charge Type
    Default: PostPaid
    AllowedValues:
      - PostPaid
      - PrePaid
    AssociationProperty: ChargeType
    AssociationPropertyMetadata:
      LocaleKey: InstanceChargeType

  PayPeriodUnit:
    Type: String
    Label:
      zh-cn: 购买资源时长周期
      en: Pay Period Unit
    Description:
      zh-cn: 包年包月的周期单位。Month为月,Year为年。仅包年包月时有效。
      en: Subscription period unit. Only valid for PrePaid.
    Default: Month
    AllowedValues:
      - Month
      - Year
    AssociationProperty: PayPeriodUnit
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid

  PayPeriod:
    Type: Number
    Label:
      zh-cn: 购买资源时长
      en: Period
    Default: 1
    AllowedValues:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
      - 9
    AssociationProperty: PayPeriod
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid

  # ─── ECS instance parameters ───
  EcsInstanceType:
    Type: String
    Label:
      zh-cn: ECS实例规格
      en: ECS Instance Type
    Description:
      zh-cn: 选择ECS实例规格。列表已根据可用区和付费类型自动过滤。
      en: Select ECS instance type, filtered by zone and charge type.
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceChargeType: ${PayType}

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

  SystemDiskSize:
    Type: Number
    Label:
      zh-cn: 系统盘大小(GB)
      en: System Disk Size (GB)
    Description:
      zh-cn: 系统盘大小,取值范围40~500 GB
      en: System disk size, range 40-500 GB
    Default: 40
    MinValue: 40
    MaxValue: 500

  DataDiskCategory:
    Type: String
    Label:
      zh-cn: 数据盘类型
      en: Data Disk Category
    Description:
      zh-cn: 选择数据盘类型。可选值:cloud_essd、cloud_ssd、cloud_efficiency
      en: Data disk type
    AssociationProperty: ALIYUN::ECS::Disk::DataDiskCategory
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceType: ${EcsInstanceType}

  DataDiskSize:
    Type: Number
    Label:
      zh-cn: 数据盘大小(GB)
      en: Data Disk Size (GB)
    Description:
      zh-cn: ECS数据盘大小,取值范围20~32768 GB
      en: Data disk size, range 20-32768 GB
    Default: 100
    MinValue: 20
    MaxValue: 32768

  InstancePassword:
    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 character types
    MinLength: 8
    MaxLength: 30
    AssociationProperty: ALIYUN::ECS::Instance::Password

  # ─── CLB paramters ───
  LoadBalancerSpec:
    Type: String
    Label:
      zh-cn: CLB实例规格
      en: CLB Instance Spec
    Description:
      zh-cn: 选择CLB实例规格,根据可用区自动过滤
      en: Select CLB instance specification
    AssociationProperty: ALIYUN::SLB::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}

  Bandwidth:
    Type: Number
    Label:
      zh-cn: EIP带宽(Mbps)
      en: EIP Bandwidth (Mbps)
    Description:
      zh-cn: 弹性公网IP的带宽上限,取值范围1~1000 Mbps
      en: EIP bandwidth cap, range 1-1000 Mbps
    Default: 10
    MinValue: 1
    MaxValue: 1000

Resources:
  # === Network Layer ===
  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: ZoneId
      CidrBlock:
        Ref: VSwitchCidrBlock
  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: Vpc
      SecurityGroupIngress:
        - PortRange: 80/80
          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

  # === Computing layer ===
  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      InstanceChargeType:
        Ref: PayType
      PeriodUnit:
        Ref: PayPeriodUnit
      Period:
        Ref: PayPeriod
      IoOptimized: optimized
      SystemDiskCategory:
        Ref: SystemDiskCategory
      SystemDiskSize:
        Ref: SystemDiskSize
      DiskMappings:
        - Category:
            Ref: DataDiskCategory
          Size:
            Ref: DataDiskSize
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      VSwitchId:
        Ref: VSwitch
      MaxAmount: 2
      ImageId: centos_7
      InstanceType:
        Ref: EcsInstanceType
      Password:
        Ref: InstancePassword
      AllocatePublicIP: false
  RunSetup:
    Type: ALIYUN::ECS::RunCommand
    DependsOn: EcsInstanceGroup
    Properties:
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      Type: RunShellScript
      Sync: true
      Timeout: 300
      ContentEncoding: PlainText
      CommandContent: |
        #!/bin/bash
        # === 数据盘初始化:分区、格式化、挂载到/disk1 ===
        cat >> /root/InitDataDisk.sh << 'EOF'
        #!/bin/bash
        echo "p
        n
        p
        w
        " |  fdisk -u /dev/vdb
        EOF
        /bin/bash /root/InitDataDisk.sh
        rm -f /root/InitDataDisk.sh
        mkfs -t ext4 /dev/vdb1
        cp /etc/fstab /etc/fstab.bak
        mkdir /disk1
        echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab
        mount -a

        # === install and start Nginx ===
        yum install -y nginx
        systemctl start nginx.service

  # === CLB layer ===
  Slb:
    Type: ALIYUN::SLB::LoadBalancer
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      LoadBalancerName:
        Fn::Sub: slb-${ALIYUN::StackName}
      PayType:
        Ref: PayType
      PricingCycle:
        Ref: PayPeriodUnit
      Duration:
        Ref: PayPeriod
      AddressType: intranet
      LoadBalancerSpec:
        Ref: LoadBalancerSpec
      AutoPay: true
  EipSlbAddress:
    Type: ALIYUN::VPC::EIP
    Properties:
      Name:
        Ref: ALIYUN::StackName
      InternetChargeType: PayByTraffic
      Bandwidth:
        Ref: Bandwidth
  EipSlbAddressAssociation:
    Type: ALIYUN::VPC::EIPAssociation
    Properties:
      InstanceId:
        Ref: Slb
      AllocationId:
        Ref: EipSlbAddress
  SlbBackendServerAttachment:
    DependsOn:
      - EcsInstanceGroup
    Type: ALIYUN::SLB::BackendServerAttachment
    Properties:
      BackendServerList:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      LoadBalancerId:
        Ref: Slb
      BackendServerWeightList:
        - 100
        - 100
  SlbListener:
    DependsOn:
      - Slb
    Type: ALIYUN::SLB::Listener
    Properties:
      LoadBalancerId:
        Ref: Slb
      ListenerPort: 80
      BackendServerPort: 80
      Protocol: tcp
      Bandwidth: -1
      Persistence:
        StickySession: 'on'
        StickySessionType: insert
        CookieTimeout: 60
        PersistenceTimeout: 180
      HealthCheck:
        HealthCheckType: tcp
        Port: 80
        Interval: 2
        HealthyThreshold: 3
        UnhealthyThreshold: 3
        Timeout: 5

Outputs:
  Endpoint:
    Description:
      zh-cn: 对外暴露的公网访问地址
      en: Public HTTP endpoint
    Value:
      Fn::Sub:
        - http://${ServerAddress}
        - ServerAddress:
            Fn::GetAtt:
              - EipSlbAddress
              - EipAddress

# === Metadata ===
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - ZoneId
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: 基础网络配置
            en: Network Configuration
      - Parameters:
          - PayType
          - PayPeriodUnit
          - PayPeriod
        Label:
          default:
            zh-cn: 付费类型
            en: Billing Configuration
      - Parameters:
          - EcsInstanceType
          - SystemDiskCategory
          - SystemDiskSize
          - DataDiskCategory
          - DataDiskSize
          - InstancePassword
        Label:
          default:
            zh-cn: ECS实例配置
            en: ECS Instance Configuration
      - Parameters:
          - LoadBalancerSpec
          - Bandwidth
        Label:
          default:
            zh-cn: 负载均衡配置
            en: CLB Configuration
          default:
            zh-cn: ECS实例配置
            en: ECS Instance Configuration
      - Parameters:
          - LoadBalancerSpec
          - Bandwidth
        Label:
          default:
            zh-cn: 负载均衡配置
            en: CLB Configuration

Referencia rápida de funciones integradas de ROS

Función

Ejemplo de sintaxis

Propósito en esta plantilla

Notas

Ref

Ref: MyVpc

Hace referencia a valores de parámetros o identificadores principales de recursos.

Devuelve el valor del parámetro cuando se hace referencia a un parámetro; devuelve el ID principal al hacer referencia a un recurso.

Fn::GetAtt

Fn::GetAtt: [EcsInstanceGroup, InstanceIds]

Obtiene la lista de IDs de instancia del grupo de instancias ECS.

Devuelve atributos de salida del recurso (identificadores no principales) después de la creación.

Fn::Sub

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

Concatena el nombre del CLB.

Hace referencia a variables con ${Var} en una cadena de plantilla.

Fn::Not + Fn::Equals

Fn::Not: Fn::Equals: [${PayType}, PostPaid]

Visualización condicional de los parámetros de duración de facturación.

Negación lógica + comparación de igualdad, utilizada para condiciones de visibilidad (Visible).

Despliegue

Parámetros de despliegue

Parámetros obligatorios (deben especificarse durante el despliegue)

Parámetro

Tipo

Descripción

Restricciones

ZoneId

String

ID de zona.

Se selecciona dinámicamente en la consola.

EcsInstanceType

String

Tipo de instancia ECS.

Se filtra automáticamente por zona y tipo de facturación.

SystemDiskCategory

String

Tipo de disco del sistema.

Se filtra automáticamente por zona y tipo de instancia.

DataDiskCategory

String

Tipo de disco de datos.

Se filtra automáticamente por zona y tipo de instancia.

LoadBalancerSpec

String

Especificación de la instancia CLB.

Se filtra automáticamente por zona.

Parámetros opcionales (tienen valores predeterminados y pueden dejarse vacíos)

Parámetro

Valor predeterminado

Descripción

VpcCidrBlock

192.168.0.0/16

Bloque CIDR de la VPC.

VSwitchCidrBlock

192.168.0.0/24

Bloque CIDR de subred del vSwitch.

PayType

PostPaid

Tipo de facturación (pay-as-you-go / suscripción).

PayPeriodUnit

Month

Unidad del periodo de facturación (se muestra solo cuando es PrePaid).

PayPeriod

1

Duración de la facturación (se muestra solo cuando es PrePaid).

SystemDiskSize

40

Tamaño del disco del sistema (GB), rango: 40–500.

DataDiskSize

100

Tamaño del disco de datos (GB), rango: 20–32768.

Bandwidth

10

Límite de ancho de banda de EIP (Mbps), rango: 1–1000.

InstancePassword

—

Contraseña de inicio de sesión de la instancia ECS. Longitud de 8 a 30 caracteres; debe contener como mínimo tres tipos de caracteres: letras mayúsculas, letras minúsculas, dígitos y caracteres especiales.

Métodos de despliegue

Método 1: Desplegar mediante la consola de ROS

  1. Inicie sesión en la consola de ROS.

  2. En el panel de navegación izquierdo, seleccione Stacks > Create Stack.

  3. Seleccione Select an Existing Template > Enter Template Content y pegue la plantilla completa en el editor.

  4. Haga clic en Next y configure los parámetros por grupo.

  5. Tras confirmar la configuración, haga clic en Create y espere a que el estado de la pila cambie a CREATE_COMPLETE.

Método 2: Desplegar mediante código IaC de ROS

IaC Code es un asistente de infraestructura como código basado en IA para infraestructura en la nube. Ayuda a los usuarios de recursos en la nube y a los ingenieros de O&M a generar, desplegar y gestionar plantillas de infraestructura mediante un flujo de trabajo de terminal.

# Prompt
Help me deploy a group of ECS instances and attach them to a CLB load balancer with the following requirements:
1. Use a newly created VPC and vSwitch
2. Create 2 ECS instances and install and start Nginx via CommandContent
3. Use WaitCondition to wait for Nginx installation to complete before attaching to CLB
4. Configure CLB with TCP port 80 listener and health checks
5. Create an EIP and associate it with the CLB to provide HTTP access
6. Open inbound port 80 in the security group
7. Configure ECS with a 100 GB data disk and auto-partition and mount it in CommandContent
8. Configure ZoneId, EcsInstanceType, SystemDiskCategory, DataDiskCategory, LoadBalancerSpec with AssociationProperty for dynamic console filtering
9. Support switching between pay-as-you-go and subscription billing, with subscription parameters using conditional display

Preguntas frecuentes

P1: La comprobación de estado del CLB falla continuamente y las instancias ECS backend muestran "Unhealthy"

Causa: El servicio Nginx en la instancia ECS no se ejecuta correctamente o el security group no tiene abierto el puerto 80.

Pasos de solución de problemas:

  1. Log on the ECS instances y ejecute systemctl status nginx para confirmar que Nginx está en ejecución.

  2. Compruebe que la regla de entrada del security group tenga abierto el puerto 80 (PortRange: 80/80).

  3. Verifique que el Port en la configuración de comprobación de estado del CLB coincida con el puerto de escucha de Nginx.

  4. Aumente HealthyThreshold (umbral de estado correcto) e Interval (intervalo de comprobación) según corresponda.

P2: ¿Cómo ajusto la proporción de distribución de tráfico entre los servidores backend?

Solución: Modifique BackendServerWeightList en SlbBackendServerAttachment:

BackendServerWeightList:
  - 100  # ECS instance 1: receives approximately 67% of traffic
  - 50   # ECS instance 2: receives approximately 33% of traffic

La proporción de pesos es 100:50, lo que significa que la instancia ECS 1 maneja aproximadamente dos tercios de las solicitudes. Para retirar temporalmente una instancia ECS del servicio (desmantelamiento gradual), establezca su peso en 0.

P3: ¿Cómo reemplazo el script de despliegue de Nginx en ECS::RunCommand con una aplicación personalizada?

Solución: Modifique la sección de instalación e inicio del script CommandContent y conserve la lógica de inicialización del disco de datos:

CommandContent:
  Fn::Sub:
    - |
      #!/bin/bash
      # ... Data disk initialization code (keep as is) ...

      # === Replace with your application deployment script ===
      # Example: Deploy a Java Spring Boot application
      yum install -y java-11-openjdk
      wget -P /disk1 https://your-oss-bucket.oss-cn-hangzhou.aliyuncs.com/app.jar
      nohup java -jar /disk1/app.jar --server.port=80

P4: ¿Cómo sustituyo CLB por ALB (Application Load Balancer)?

Pasos de migración:

  1. Reemplace ALIYUN::SLB::LoadBalancer por ALIYUN::ALB::LoadBalancer.

  2. Utilice ALIYUN::ALB::ServerGroup para crear un grupo de servidores y agregar las instancias ECS backend.

  3. Utilice ALIYUN::ALB::Listener + ALIYUN::ALB::Rule para configurar el enrutamiento HTTP/HTTPS de capa 7.

  4. ALB admite de forma nativa el acceso a la red pública, por lo que no es necesario asociar una EIP por separado.

P5: ¿Cómo utilizo una VPC existente en lugar de crear una nueva?

Solución: Elimine la VPC y el vSwitch de Resources y páselos como parámetros:

Parameters:
  ExistingVpcId:
    Type: String
    Label:
      zh-cn: Existing VPC ID
      en: Existing VPC ID
    AssociationProperty: ALIYUN::ECS::VPC::VPCId
  ExistingVSwitchId:
    Type: String
    Label:
      zh-cn: Existing VSwitch ID
      en: Existing vSwitch ID
    AssociationProperty: ALIYUN::VPC::VSwitch::VSwitchId
    AssociationPropertyMetadata:
      VpcId: ${ExistingVpcId}

Para más problemas comunes de despliegue, consulte FAQ.

Referencias