You can use Resource Orchestration Service (ROS) to generate a template based on a collection of existing resources in a resource management scenario. Then, you can modify the generated template based on your business requirements and use the template as a regular template to deploy multiple resources at a time.

Use case

If you want to create resources to deploy a web application, you can add the app:web tag to the resources. This way, you can filter the required resources by tag when you create a resource management scenario. You can click Create Template to generate a template based on the scenario. After the template is generated, you can use the Parameters section to modify the template. This improves the flexibility and reusability of the generated template. Then, you can use the modified template as a regular template to create a stack and deploy multiple resources at a time. In this example, the following resources are deployed:

  • One virtual private cloud (VPC)
  • One vSwitch
  • One security group
  • Two Elastic Compute Service (ECS) instances
  • One Server Load Balancer (SLB) instance

Step 1: Create resources and add tags to the resources

Create the preceding resources in the relevant consoles and add the app:web tag to the resources. The tag key is app and the tag value is web. For more information about tags, see Tag overview.

Note If the resources already exist, you need to only add the tag to the resources.
  1. In the VPC console, create a VPC and a vSwitch, and add the app:web tag to them.
    For more information, see Create a VPC and Add a tag to a VPC.
    Note To add the tag to a vSwitch, find the vSwitch and click the 002 icon in the Tags column. You can perform similar operations to add the tag to a VPC.
  2. In the ECS console, create a security group of the VPC type and add the app:web tag to the security group. When you create the security group, select the VPC that you created in Step 1 from the Network drop-down list.
  3. Create two ECS instances and add the app:web tag to the instances.
    1. Select the VPC and vSwitch that you created in Step 1.
    2. Select the security group that you created in Step 2.
    3. Configure relevant parameters for the ECS instances.
      For more information about the parameters, see Create an ECS instance.
    4. Add the app:web tag to the instances.
      For more information, see Add a tag to an ECS instance.
  4. In the SLB console, create an Application Load Balancer (ALB) instance and add the app:web tag to the instance.
    1. When you create the ALB instance, select the VPC that you created in Step 1.
    2. When you create a backend server group, add the ECS instances that you created in Step 3 to the group.
    3. Configure a listener and domain name resolution based on your business requirements.
    4. Add the app:web tag to the ALB instance.

Step 2: Create a resource management scenario

When you create a resource management scenario, filter the resources that you created in Step 1: Create resources and add tags to the resources by app:web. For more information, see Use a scenario to manage resources.

  1. Log on to the ROS console.
  2. In the left-side navigation pane, click Scenarios.
  3. In the upper-left corner of the Scenarios page, select a region where you want to create the scenario from the region drop-down list.
  4. On the Scenarios page, click Create Scenario.
  5. In the Create Scenario dialog box, enter a description of the scenario and set the scenario type to Resource Management.
  6. Configure parameters in the Resource Range section.
    1. Select Source Tag as Method.
    2. In the Source Tag section, set Tag Key to app and Tag Value to web.
    001
  7. Select No as Delete Resource.
    Note In this example, the resources in the stack are retained if you delete the stack.
  8. Click Create.
    After you create the scenario, Created appears in the Status column on the Scenarios page.

Step 3: Generate a template based on the scenario

  1. On the Scenarios page, click the ID of the scenario.
  2. On the scenario management page, click Create Template in the upper-right corner to generate a template.
    02

The generated template is in the JSON and YAML formats. In this example, the JSON template is used. The following section describes the template body and structure.

  • Template body

    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Resources": {
        "ECSInstance_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::ECS::Instance",
          "Properties": {
            "DeletionProtection": false,
            "VSwitchId": {
              "Ref": "ECSVSwitch_001"
            },
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ],
            "SystemDiskSize": 40,
            "HostName": "iZbp11ut2d6rr7gg78a****",
            "SystemDiskCategory": "cloud_essd",
            "ImageId": "centos_7_9_x64_20G_alibase_2022****.vhd",
            "SpotStrategy": "NoSpot",
            "AllocatePublicIP": false,
            "InstanceChargeType": "PostPaid",
            "IoOptimized": "optimized",
            "SecurityGroupIds": [
              {
                "Ref": "ECSSecurityGroup_001"
              }
            ],
            "InternetChargeType": "PayByTraffic",
            "ZoneId": "cn-hangzhou-i",
            "InstanceName": "launch-advisor-2022****",
            "InstanceType": "ecs.g7.large",
            "SystemDiskPerformanceLevel": "PL0"
          },
          "DependsOn": [
            "ECSSecurityGroup_001",
            "ECSVSwitch_001",
            "ECSVPC_001"
          ]
        },
        "ECSInstance_002": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::ECS::Instance",
          "Properties": {
            "DeletionProtection": false,
            "VSwitchId": {
              "Ref": "ECSVSwitch_001"
            },
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ],
            "SystemDiskSize": 40,
            "HostName": "iZbp11ut2d6rr7gg78a****",
            "SystemDiskCategory": "cloud_essd",
            "ImageId": "centos_7_9_x64_20G_alibase_2022****.vhd",
            "SpotStrategy": "NoSpot",
            "AllocatePublicIP": false,
            "InstanceChargeType": "PostPaid",
            "IoOptimized": "optimized",
            "SecurityGroupIds": [
              {
                "Ref": "ECSSecurityGroup_001"
              }
            ],
            "InternetChargeType": "PayByTraffic",
            "ZoneId": "cn-hangzhou-i",
            "InstanceName": "launch-advisor-2022****",
            "InstanceType": "ecs.g7.large",
            "SystemDiskPerformanceLevel": "PL0"
          },
          "DependsOn": [
            "ECSSecurityGroup_001",
            "ECSVSwitch_001",
            "ECSVPC_001"
          ]
        },
        "ECSSecurityGroup_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::ECS::SecurityGroup",
          "Properties": {
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "Description": "web-sg",
            "SecurityGroupName": "web-sg",
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ],
            "SecurityGroupIngress": [
              {
                "PortRange": "1/65535",
                "NicType": "intranet",
                "Priority": 1,
                "SourceCidrIp": "0.0.0.0/0",
                "Policy": "accept",
                "IpProtocol": "tcp"
              },
              {
                "PortRange": "80/80",
                "NicType": "intranet",
                "Priority": 1,
                "SourceCidrIp": "0.0.0.0/0",
                "Policy": "accept",
                "IpProtocol": "tcp"
              },
              {
                "PortRange": "443/443",
                "NicType": "intranet",
                "Priority": 1,
                "SourceCidrIp": "0.0.0.0/0",
                "Policy": "accept",
                "IpProtocol": "tcp"
              },
              {
                "PortRange": "22/22",
                "NicType": "intranet",
                "Priority": 1,
                "SourceCidrIp": "0.0.0.0/0",
                "Policy": "accept",
                "IpProtocol": "tcp"
              },
              {
                "PortRange": "3389/3389",
                "NicType": "intranet",
                "Priority": 1,
                "SourceCidrIp": "0.0.0.0/0",
                "Policy": "accept",
                "IpProtocol": "tcp"
              },
              {
                "PortRange": "-1/-1",
                "NicType": "intranet",
                "Priority": 1,
                "SourceCidrIp": "0.0.0.0/0",
                "Policy": "accept",
                "IpProtocol": "icmp",
                "SourcePortRange": "-1/-1"
              }
            ],
            "SecurityGroupType": "normal"
          },
          "DependsOn": [
            "ECSVPC_001"
          ]
        },
        "ECSVPC_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::ECS::VPC",
          "Properties": {
            "CidrBlock": "172.16.0.0/12",
            "VpcName": "web-vpc",
            "EnableIpv6": false,
            "Description": "web-vpc",
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ]
          }
        },
        "ECSVSwitch_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::ECS::VSwitch",
          "Properties": {
            "VSwitchName": "web-vsw",
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "Description": "web-vsw",
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ],
            "ZoneId": "cn-hangzhou-i",
            "CidrBlock": "172.16.0.0/24"
          },
          "DependsOn": [
            "ECSVPC_001"
          ]
        },
        "SLBBackendServerAttachment_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::SLB::BackendServerAttachment",
          "Properties": {
            "BackendServers": [
              {
                "ServerId": {
                  "Ref": "ECSInstance_002"
                },
                "Type": "ecs",
                "Weight": 100
              },
              {
                "ServerId": {
                  "Ref": "ECSInstance_001"
                },
                "Type": "ecs",
                "Weight": 100
              }
            ],
            "LoadBalancerId": {
              "Ref": "SLBLoadBalancer_001"
            }
          },
          "DependsOn": [
            "SLBLoadBalancer_001",
            "ECSInstance_001",
            "ECSInstance_002"
          ]
        },
        "SLBLoadBalancer_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::SLB::LoadBalancer",
          "Properties": {
            "DeletionProtection": false,
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "AddressIPVersion": "ipv4",
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ],
            "SupportPrivateLink": true,
            "PayType": "PayOnDemand",
            "SlaveZoneId": "cn-hangzhou-h",
            "AddressType": "intranet",
            "VSwitchId": {
              "Ref": "ECSVSwitch_001"
            },
            "LoadBalancerName": "web-app-slb",
            "InternetChargeType": "paybytraffic",
            "LoadBalancerSpec": "slb.s1.small",
            "MasterZoneId": "cn-hangzhou-i"
          },
          "DependsOn": [
            "ECSVPC_001",
            "ECSVSwitch_001"
          ]
        }
      }
    }
  • Template structure

    The template structure contains the following sections:
    ROSTemplateFormatVersion: '2015-09-01' // The syntax version of the template.
    Resources: {} // The details of the resources.
    • ROSTemplateFormatVersion: the syntax version of the template. Set the value to 2015-09-01.
    • Resources: the details of the resources, such as the properties and the dependencies of resources. The Resources section contains the resources that you created in Step 1: Create resources and add tags to the resources.
      • One VPC: ECSVPC_001.
      • One vSwitch: ECSvSwitch_001.
      • One security group: ECSSecurityGroup_001.
      • Two ECS instances: ECSInstance_001 and ECSInstance_002, hereinafter referred to as ECSInstance_00X.
      • One SLB instance: SLBLoadBalancer_ 001, SLBListener_001, and SLBBackendServerAttachment_001.

      The following figure shows the architecture of the resources.

      003

Step 4: Modify the generated template

In the generated template, the resource property values are literal values that are parsed from the parameters selected when you created the resources in the relevant consoles in Step 1: Create resources and add tags to the resources. You can add the Parameters and the Outputs sections to modify the generated template. This way, you can use the template as a regular template in different scenarios. In the Parameters section, you can specify values for parameters to overwrite the literal values of relevant properties such as zones and instance types.

Comparison between the generated template and the regular template

ROSTemplateFormatVersion: '2015-09-01' // The syntax version of the template.
Resources: {} // The details of the resources.
ROSTemplateFormatVersion: '2015-09-01' // The syntax version of the template.
Description: {} // The description of the template, including the scenarios and architecture of the template. 
Parameters: {} // The parameters for which you can specify values to overwrite the literal values of relevant resource properties.
Resources: {} // The details of the resources.
Outputs: {} // The output items of the template, such as the return values of resource properties. To query output items, call the GetStack operation or go to the ROS console. 
Note For more information about the parameters, see Template syntax.

The following table describes the mappings between the resources, the parameters, and the output items.

Resource Parameter Output item
ECSVPC_001 VpcCidrBlock: the CIDR block of the VPC. None.
ECSvSwitch_001 ZoneId: the ID of the zone. None.
VSwitchCidrBlock: the CIDR block of the vSwitch.
ECSSecurityGroup_001 None. None.
ECSInstance_00X ZoneId: the ID of the zone. InstanceId: the ID of the ECS instance.
ECSInstanceType: the instance type of the ECS instance.
SystemDiskCategory: the system disk category of the ECS instance.
SLBLoadBalancer_001 MasterZoneId: the ID of the primary zone. IpAddress: the IP address of the ALB instance.
SlaveZoneId: the ID of the secondary zone.
LoadBalancerSpec: the specification of the ALB instance.

Procedure

  • Resource: ECSVPC_001

    • In the Parameters section, add and specify the VpcCidrBlock parameter.
    • Use Ref to reference the VpcCidrBlock parameter contained in the Parameters section for the CidrBlock property.
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Resources": {
        "ECSVPC_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::ECS::VPC",
          "Properties": {
            "CidrBlock": "172.16.0.0/12"
          }
        }
      }
    }
    
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Parameters": {
        "VpcCidrBlock": {
          "Type": "String",
          "Label": " ",
          "Description": " ",
          "Default": "172.16.0.0/12"
        }
      },
      "Resources": {
        "ECSVPC_001": {
          "Type": "ALIYUN::ECS::VPC",
          "Properties": {
            "CidrBlock": {
              "Ref": "VpcCidrBlock"
            },
            "VpcName": "web-vpc",
            "EnableIpv6": false,
            "Description": "web-vpc",
            "Tags": [
              {
                "Value": "web",
                "Key": "app"
              }
            ]
          }
        }
      }
    }
    
    Note For more information about other properties of ECSVPC_001, see ALIYUN::ECS::VPC.
  • Resource: ECSvSwitch_001

    • In the Parameters section, add and specify the ZoneId and VSwitchCidrBlock parameters.
    • Use Ref to reference the ZoneId parameter contained in the Parameters section for the ZoneId property.
    • Use Ref to reference the VSwitchCidrBlock parameter contained in the Parameters section for the CidrBlock property.
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Resources": {
        "ECSVSwitch_001": {
          "Type": "ALIYUN::ECS::VSwitch",
          "Properties": {
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "ZoneId": "cn-hangzhou-i",
            "CidrBlock": "172.16.0.0/24"
          },
          "DependsOn": [
            "ECSVPC_001"
          ]
        }
      }
    }
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Parameters": {
        "ZoneId": {
          "Type": "String",
          "AssociationProperty": "ALIYUN::ECS::ZoneId",
          "Description": " ",
          "Label": " "
        },
        "VSwitchCidrBlock": {
          "Type": "String",
          "Label": " ",
          "Description": " ",
          "Default": "172.16.0.0/24"
        }
      },
      "Resources": {
        "ECSVPC_001": "",
        "ECSVSwitch_001": {
          "Type": "ALIYUN::ECS::VSwitch",
          "Properties": {
            "CidrBlock": {
              "Ref": "VSwitchCidrBlock"
            },
            "VpcId": {
              "Ref": "ECSVPC_001"
            },
            "ZoneId": {
              "Ref": "VSwitchZone"
            }
          },
          "DependsOn": [
            "ECSVPC_001"
          ]
        }
      }
    }
    
    Note
    • In the Parameters section, you can specify AssociationProperty to query resources in the specified region and specify AssociationPropertyMetadata to add filter conditions for the parameters. This way, the ROS console can display available values of a parameter based on the value of another parameter. For the ZoneId parameter, AssociationProperty is set to ALIYUN::ECS::ZoneId. This way, you can query available zone IDs in the specified region and select the required zone from a drop-down list in the ROS console. For more information, see AssociationProperty and AssociationPropertyMetadata.
    • If you add DependsOn to a resource, the system creates the resource after the dependency of the resource is created. In this example, the system creates ECSVSwitch_001 after ECSVPC_001 is created.
    • For more information about other properties of ECSVSwitch_001, see ALIYUN::ECS::VSwitch.
  • Resource: ECSInstance_00X

    • In the Parameters section, add and specify the ZoneId, ECSInstanceType, and SystemDiskCategory parameters.
    • Use Ref to reference the ZoneId parameter contained in the Parameters section for the ZoneId property.
    • Use Ref to reference the ECSInstanceType parameter contained in the Parameters section for the InstanceType property.
    • Use Ref to reference the SystemDiskCategory parameter contained in the Parameters section for the SystemDiskCategory property.
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Resources": {
        "ECSVSwitch_001": "",
        "ECSVPC_001": "",
        "ECSSecurityGroup_001": "",
        "ECSInstance_001": {
          "Type": "ALIYUN::ECS::Instance",
          "Properties": {
            "ZoneId": "cn-hangzhou-i",
            "InstanceType": "ecs.g7.large",
            "SystemDiskCategory": "cloud_essd"
          },
          "DependsOn": [
            "ECSSecurityGroup_001",
            "ECSVSwitch_001",
            "ECSVPC_001"
          ]
        }
      }
    }
    
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Parameters": {
        "ZoneId": "",
        "ECSInstanceType": {
          "Type": "String",
          "Description": " ",
          "Label": " ",
          "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
          "AssociationPropertyMetadata": {
            "ZoneId": "ZoneId"
          }
        },
        "SystemDiskCategory": {
          "Type": "String",
          "Description": " ",
          "AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
          "AssociationPropertyMetadata": {
            "ZoneId": "VSwitchZone",
            "InstanceType": "ECSInstanceType"
          },
          "Label": " "
        }
      },
      "Resources": {
        "ECSInstance_001": {
          "Type": "ALIYUN::ECS::Instance",
          "Properties": {
            "SystemDiskCategory": {
              "Ref": "SystemDiskCategory"
            },
            "InstanceType": {
              "Ref": "ECSInstanceType"
            },
            "ZoneId": {
              "Ref": "ZoneId"
            }
          },
          "DependsOn": [
            "ECSSecurityGroup_001",
            "ECSVSwitch_001",
            "ECSVPC_001"
          ]
        }
      }
    }
    
    Note
    • For the EcsInstanceType parameter, AssociationProperty is set to ALIYUN::ECS::Instance::InstanceType. This way, you can query available instance types of the ECS instance in the specified region and select the required instance type from a drop-down list in the ROS console.
    • AssociationPropertyMetadata is used to add filter conditions. In this example, AssociationPropertyMetadata is set to ZoneId. This way, you can query available instance types of the ECS instance in the specified zone.
    • For the SystemDiskCategory parameter, AssociationProperty is set to ALIYUN::ECS::Disk::SystemDiskCategory. This way, you can query available system disk categories of the ECS instance in the specified region.
    • For more information about other properties of ECSInstance_00X, see ALIYUN::ECS::Instance.
  • Resource: SLBLoadBalancer_001

    • In the Parameters section, add and specify the MasterZoneId, SlaveZoneId, and LoadBalancerSpec parameters.
    • Use Ref to reference the ZoneId parameter contained in the Parameters section for the MasterZoneId property.
    • Use Ref to reference the SlaveZoneId parameter contained in the Parameters section for the SlaveZoneId property.
    • Use Ref to reference the LoadBalancerSpec parameter contained in the Parameters section for the LoadBalancerSpec property.
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Resources": {
        "ECSVPC_001": "",
        "ECSVSwitch_001": "",
        "SLBLoadBalancer_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::SLB::LoadBalancer",
          "Properties": {
            "MasterZoneId": "cn-hangzhou-i",
            "SlaveZoneId": "cn-hangzhou-h",
            "LoadBalancerSpec": "slb.s1.small"
          },
          "DependsOn": [
            "ECSVPC_001",
            "ECSVSwitch_001"
          ]
        }
      }
    }
    
    {
      "ROSTemplateFormatVersion": "2015-09-01",
      "Parameters": {
        "ZoneId": "",
        "SlaveZoneId": {
          "Type": "String",
          "Description": " ",
          "Label": " "
        },
        "LoadBalancerSpec": {
          "Type": "String",
          "AssociationProperty": "ALIYUN::SLB::Instance::InstanceType",
          "Description": " ",
          "Label": " ",
          "AssociationPropertyMetadata": {
            "ZoneId": "VSwitchZone"
          }
        }
      },
      "Resources": {
        "ECSVPC_001": "",
        "ECSVSwitch_001": "",
        "SLBLoadBalancer_001": {
          "DeletionPolicy": "Retain",
          "Type": "ALIYUN::SLB::LoadBalancer",
          "Properties": {
            "LoadBalancerName": "web-app-slb",
            "LoadBalancerSpec": {
              "Ref": "LoadBalancerSpec"
            },
            "SlaveZoneId": {
              "Ref": "SlaveZoneId"
            },
            "MasterZoneId": {
              "Ref": "ZoneId"
            }
          },
          "DependsOn": [
            "ECSVPC_001",
            "ECSVSwitch_001"
          ]
        }
      }
    }
    
    Note
    • In the Parameters section, you can specify AssociationProperty to query the resources in the specified region and specify AssociationPropertyMetadata to add filter conditions for the parameters. This way, the ROS console can display available values of a parameter based on the value of another parameter.
    • For the ZoneId parameter, AssociationProperty is set to ALIYUN::ECS::ZoneId. This way, you can query the available zone IDs in the specified region and select the required zone from a drop-down list in the ROS console.
    • For the LoadBalancerSpec parameter, AssociationProperty is set to ALIYUN::SLB::Instance::InstanceType. This way, you can query the available specifications of the ALB instance in the specified region and select the required specification from a drop-down list in the ROS console. For more information, see AssociationProperty and AssociationPropertyMetadata.
    • For more information about other properties of SLBLoadBalancer_001, see ALIYUN::SLB::LoadBalancer.
  • Output item: IpAddress

    For more information about the return values of other properties in SLBLoadBalancer_001, see the "Return values" section of the ALIYUN::SLB::LoadBalancer topic.

    {
      "Outputs": {
        "SLBListenerIpAddress": {
          "Description": "The IP address of the load balancer.",
          "Value": {
            "Fn::GetAtt": [
              "SLBLoadBalancer_001",
              "IpAddress"
            ]
          }
        }
      }
    }
  • Output item: InstanceId

    For more information about the return values of other properties in ECSInstance_00X, see the "Return values" section of the ALIYUN::ECS::Instance topic.

    {
      "Outputs": {
        "ECSInstance_001": {
          "Description": "The instance ID of created ecs instance",
          "Value": {
            "Fn::GetAtt": [
              "ECSInstance_001",
              "InstanceId"
            ]
          }
        },
        "ECSInstance_002": {
          "Description": "The instance ID of created ecs instance",
          "Value": {
            "Fn::GetAtt": [
              "ECSInstance_002",
              "InstanceId"
            ]
          }
        }
      }
    }

Complete regular template

{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Parameters": {
    "ZoneId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::Instance:ZoneId",
      "Description": " ",
      "Label": " "
    },
    "SlaveZoneId": {
      "Type": "String",
      "Description": " ",
      "Label": " "
    },
    "VpcCidrBlock": {
      "Type": "String",
      "Label": " ",
      "Description": " ",
      "Default": "172.16.0.0/12"
    },
    "VSwitchCidrBlock": {
      "Type": "String",
      "Label": " ",
      "Description": " ",
      "Default": "172.16.0.0/24"
    },
    "ECSInstanceType": {
      "Type": "String",
      "Description": " ",
      "Label": " ",
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "AssociationPropertyMetadata": {
        "ZoneId": "ZoneId"
      }
    },
    "SystemDiskCategory": {
      "Type": "String",
      "Description": " ",
      "AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
      "AssociationPropertyMetadata": {
        "ZoneId": "ZoneId",
        "InstanceType": "ECSInstanceType"
      },
      "Label": " "
    },
    "LoadBalancerSpec": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::SLB::Instance::InstanceType",
      "Description": " ",
      "Label": " ",
      "AssociationPropertyMetadata": {
        "ZoneId": "ZoneId"
      },
      "Default": "slb.s1.small"
    }
  },
  "Resources": {
    "ECSVPC_001": {
      "Type": "ALIYUN::ECS::VPC",
      "Properties": {
        "CidrBlock": {
          "Ref": "VpcCidrBlock"
        },
        "VpcName": "web-vpc",
        "EnableIpv6": false,
        "Description": "web-vpc",
        "Tags": [
          {
            "Value": "web",
            "Key": "app"
          }
        ]
      }
    },
    "ECSVSwitch_001": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": "web-vsw",
        "VpcId": {
          "Ref": "ECSVPC_001"
        },
        "Description": "web-vsw",
        "Tags": [
          {
            "Value": "web",
            "Key": "app"
          }
        ],
        "ZoneId": {
          "Ref": "ZoneId"
        },
        "CidrBlock": {
          "Ref": "VSwitchCidrBlock"
        }
      },
      "DependsOn": [
        "ECSVPC_001"
      ]
    },
    "ECSSecurityGroup_001": {
      "Type": "ALIYUN::ECS::SecurityGroup",
      "Properties": {
        "VpcId": {
          "Ref": "ECSVPC_001"
        },
        "Description": "web-sg",
        "SecurityGroupName": "web-sg",
        "Tags": [
          {
            "Value": "web",
            "Key": "app"
          }
        ],
        "SecurityGroupIngress": [
          {
            "PortRange": "80/80",
            "NicType": "intranet",
            "Priority": 1,
            "SourceCidrIp": "0.0.0.0/0",
            "Policy": "accept",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "443/443",
            "NicType": "intranet",
            "Priority": 1,
            "SourceCidrIp": "0.0.0.0/0",
            "Policy": "accept",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "22/22",
            "NicType": "intranet",
            "Priority": 1,
            "SourceCidrIp": "0.0.0.0/0",
            "Policy": "accept",
            "IpProtocol": "tcp"
          }
        ],
        "SecurityGroupType": "normal"
      },
      "DependsOn": [
        "ECSVPC_001"
      ]
    },
    "ECSInstance_001": {
      "Type": "ALIYUN::ECS::Instance",
      "Properties": {
        "DeletionProtection": true,
        "SystemDiskCategory": {
          "Ref": "SystemDiskCategory"
        },
        "VpcId": {
          "Ref": "ECSVPC_001"
        },
        "Description": "web-ecs",
        "Tags": [
          {
            "Value": "web",
            "Key": "app"
          }
        ],
        "VSwitchId": {
          "Ref": "ECSVSwitch_001"
        },
        "SystemDiskSize": 40,
        "ImageId": "centos_7_9_x64_20G_alibase_2022****.vhd",
        "SpotStrategy": "NoSpot",
        "AllocatePublicIP": false,
        "InstanceChargeType": "PostPaid",
        "IoOptimized": "optimized",
        "SecurityGroupIds": [
          {
            "Ref": "ECSSecurityGroup_001"
          }
        ],
        "InternetChargeType": "PayByTraffic",
        "ZoneId": {
          "Ref": "ZoneId"
        },
        "InstanceName": "web-ecs002",
        "InstanceType": {
          "Ref": "ECSInstanceType"
        },
        "SystemDiskPerformanceLevel": "PL0"
      },
      "DependsOn": [
        "ECSSecurityGroup_001",
        "ECSVSwitch_001",
        "ECSVPC_001"
      ]
    },
    "ECSInstance_002": {
      "Type": "ALIYUN::ECS::Instance",
      "Properties": {
        "DeletionProtection": true,
        "SystemDiskCategory": {
          "Ref": "SystemDiskCategory"
        },
        "VpcId": {
          "Ref": "ECSVPC_001"
        },
        "Description": "web-ecs",
        "Tags": [
          {
            "Value": "web",
            "Key": "app"
          }
        ],
        "VSwitchId": {
          "Ref": "ECSVSwitch_001"
        },
        "SystemDiskSize": 40,
        "ImageId": "centos_7_9_x64_20G_alibase_2022****.vhd",
        "SpotStrategy": "NoSpot",
        "AllocatePublicIP": false,
        "InstanceChargeType": "PostPaid",
        "IoOptimized": "optimized",
        "SecurityGroupIds": [
          {
            "Ref": "ECSSecurityGroup_001"
          }
        ],
        "InternetChargeType": "PayByTraffic",
        "ZoneId": {
          "Ref": "ZoneId"
        },
        "InstanceName": "web-ecs001",
        "InstanceType": {
          "Ref": "ECSInstanceType"
        },
        "SystemDiskPerformanceLevel": "PL0"
      },
      "DependsOn": [
        "ECSSecurityGroup_001",
        "ECSVSwitch_001",
        "ECSVPC_001"
      ]
    },
    "SLBListener_001": {
      "Type": "ALIYUN::SLB::Listener",
      "Properties": {
        "AclStatus": "off",
        "Protocol": "tcp",
        "Description": "tcp_80",
        "HealthCheck": {
          "Interval": 2,
          "HealthyThreshold": 3,
          "Switch": "on",
          "UnhealthyThreshold": 3,
          "HealthCheckType": "tcp"
        },
        "LoadBalancerId": {
          "Ref": "SLBLoadBalancer_001"
        },
        "ListenerPort": 80,
        "Bandwidth": -1,
        "BackendServerPort": 80,
        "Scheduler": "tch",
        "StartListener": true,
        "Persistence": {
          "PersistenceTimeout": 0
        }
      },
      "DependsOn": [
        "SLBLoadBalancer_001"
      ]
    },
    "SLBLoadBalancer_001": {
      "Type": "ALIYUN::SLB::LoadBalancer",
      "Properties": {
        "DeletionProtection": false,
        "VpcId": {
          "Ref": "ECSVPC_001"
        },
        "AddressIPVersion": "ipv4",
        "Tags": [
          {
            "Value": "web",
            "Key": "app"
          }
        ],
        "SupportPrivateLink": true,
        "PayType": "PayOnDemand",
        "AddressType": "intranet",
        "VSwitchId": {
          "Ref": "ECSVSwitch_001"
        },
        "LoadBalancerName": "web-slb",
        "InternetChargeType": "paybytraffic",
        "LoadBalancerSpec": {
          "Ref": "LoadBalancerSpec"
        },
        "MasterZoneId": {
          "Ref": "ZoneId"
        },
        "SlaveZoneId": {
          "Ref": "SlaveZoneId"
        }
      },
      "DependsOn": [
        "ECSVPC_001",
        "ECSVSwitch_001"
      ]
    },
    "SLBBackendServerAttachment_001": {
      "Type": "ALIYUN::SLB::BackendServerAttachment",
      "Properties": {
        "BackendServers": [
          {
            "ServerId": {
              "Ref": "ECSInstance_001"
            },
            "Type": "ecs",
            "Weight": 100
          },
          {
            "ServerId": {
              "Ref": "ECSInstance_002"
            },
            "Type": "ecs",
            "Weight": 100
          }
        ],
        "LoadBalancerId": {
          "Ref": "SLBLoadBalancer_001"
        }
      },
      "DependsOn": [
        "SLBLoadBalancer_001",
        "ECSInstance_001",
        "ECSInstance_002"
      ]
    }
  },
  "Outputs": {
    "ECSInstance_001": {
      "Description": "The instance ID of created ecs instance",
      "Value": {
        "Fn::GetAtt": [
          "ECSInstance_001",
          "InstanceId"
        ]
      }
    },
    "ECSInstance_002": {
      "Description": "The instance ID of created ecs instance",
      "Value": {
        "Fn::GetAtt": [
          "ECSInstance_002",
          "InstanceId"
        ]
      }
    },
    "SLBListenerIpAddress": {
      "Description": "The IP address of the load balancer.",
      "Value": {
        "Fn::GetAtt": [
          "SLBLoadBalancer_001",
          "IpAddress"
        ]
      }
    }
  }
}

Step 5: (Optional) Deploy multiple resources at a time

You can use the regular template to create a stack and deploy multiple resources at a time.

  1. In the ROS console, use the regular template that you created in Step 4: Modify the generated template to create a stack and deploy multiple resources at a time.
    For more information, see Create a stack.
  2. On the stack details page, click the Resources tab to view the details of the deployed resources.