Operation Orchestration Service (OOS) provides a special Loop property for tasks. This property lets you run a single task in a loop.
Tasks for API-class actions and cloud product actions support loops. However, tasks for functional actions, such as Trigger and Sleep, do not support loops.
Task loops support concurrent execution. However, in single-step mode, loop tasks run sequentially, not concurrently.
Limitations
The Items list in a Loop can contain a maximum of 1,000 items.
Syntax
YAML structure
---
Tasks:
- Name: TaskName1 # Required. The name of the task. Valid characters are letters, digits, underscores (_), and hyphens (-). The name can be up to 200 characters long. Use camel case, such as StartInstance.
Action: TaskType # Required. The task type, also called an action. For more information, see the documentation about actions.
Description: description # Optional. A description of the task.
Properties: # The property list varies based on the action used. For more information, see the documentation about actions.
Property1: Value1 # The properties and values required by the action.
Outputs: # The response parameters of the current task. They can be used as inputs for subsequent tasks or as outputs for the template.
OutputParameterName1:
Type: TypeName # Optional. The type of the response parameter. The default is String.
ValueSelector: "jq selector" # If the task is an OpenAPI call, the result of the call is treated as a JSON input. Use a jq expression to extract the required value from the JSON. For more information, see examples in cloud product actions and public templates.
Loop:
Items: [i-id1,i-id2,i-id3,i-id4] # Required. The loop elements. Accepts a list of items. Each item is used as a parameter for an execution of the loop task. You can also use a parameter name that resolves to a list, such as {{describeInstance.InstanceIds}}.
RateControl:
MaxErrors: 0 # Optional. The maximum number of errors allowed. You can specify a number or a percentage, such as 10 or 10%. The default is 0.
Mode: "Batch/Concurrency" # Required. The mode for controlling the loop execution rate. Options are Concurrency or Batch. Concurrency means concurrent execution. Batch means batch execution.
Batch: [1, 2, 3] # Optional. This parameter takes effect when Mode is set to Batch. It specifies the batch control. For information about how to define batches, see the batch control section below.
ConcurrencyInBatches: [1, 1, 1] # Optional. This parameter takes effect when Mode is set to Batch. It controls the concurrency for each batch. The default is 20. To define it, enter the concurrency for each batch in [].
Concurrency: 1 # Optional. This parameter takes effect when Mode is set to Concurrency. It controls the concurrency for all executions. You can specify a number or a percentage. The default is 1.
BatchPauseOption: "FirstBatchPause/Automatic/EveryBatchPause" # Optional. This parameter takes effect when Mode is set to Batch. It specifies the pause option after each batch completes. Options are FirstBatchPause, Automatic, and EveryBatchPause. FirstBatchPause pauses after the first batch. Automatic runs without pausing. EveryBatchPause pauses after every batch.
Outputs:
FinalOutputParameterName1: # The name of the parameter that is output after the loop task is processed by a function.
AggregateType: BuiltInFunctionName1 # Select a built-in function to aggregate the outputs, such as Fn::Sum, Fn::Max, or Fn::ListJoin.
AggregateField: OutputParameterName1 # The name of the response parameter from the execution of a loop element.JSON structure (see the comments in the YAML example for details)
{
"Tasks": [
{
"Name": "TaskName1",
"Action": "TaskType",
"Description": "description",
"Properties": {
"Property1": "Value1"
},
"Outputs": {
"OutputParameterName1": {
"Type": "TypeName",
"ValueSelector": "jq selector"
}
},
"Loop": {
"Items": [
"i-id1",
"i-id2",
"i-id3",
"i-id4"
],
"RateControl": {
"MaxErrors": 0,
"Mode": "Concurrency/Batch",
"Batch": [
1,
2,
3
],
"ConcurrencyInBatches": [
1,
1,
1
],
"Concurrency": 1,
"BatchPauseOption": "FirstBatchPause/Automatic/EveryBatchPause"
},
"Outputs": {
"FinalOutputParameterName1": {
"AggregateType": "BuiltInFunctionName1",
"AggregateField": "OutputParameterName1"
}
}
}
}
]
}The Items list
The Items property accepts a list, such as a literal list: [item1, item2, item3].
Alternatively, the Items property can reference the name of a list-type parameter, such as the Outputs from a previous task.
Items as a list.
YAML
Loop: Items: [item1,item2,item3,item4] # A list of items, such as [i-id1,i-id2,i-id3,i-id4]. Each item is used as a parameter for an execution of the task that contains the Loop.JSON (see the comments in the YAML example for details)
{ "Items": [ "item1", "item2", "item3", "item4" ] }Items as a list-type parameter name.
YAML
Items: '{{ParameterName1}}' # A parameter name that can be resolved to a list, such as describeInstance.InstanceIds. Each item is used as a parameter for an execution of the task that contains the Loop.JSON (see the comments in the YAML example for details)
{ "Items": "{{ParameterName1}}" }
Loop execution rate control
There are two modes:
Concurrency control: Executes items concurrently at a specified rate until all items are processed.
Batch control: Divides items into batches of a specified size. The next batch starts only after the previous batch is complete.
Concurrency control (Concurrency)
For example, if Items contains 10 items and Concurrency is 3, the system executes three items concurrently until all items are processed.
YAML
Concurrency: 3 # Allows a number or percentage for concurrency control, such as 3. Mode: ConcurrencyJSON (see the comments in the YAML example for details)
{ "Concurrency": 3, "Mode": "Concurrency" }For example, if Items contains 10 items and Concurrency is 20%, the concurrency is 2 (20% of 10). The system executes two items concurrently until all items are processed.
YAML
Concurrency: 20% # Optional. You can specify a number or a percentage, such as 20%. Mode: ConcurrencyJSON (see the comments in the YAML example for details)
{ "Concurrency": "20%", "Mode": "Concurrency" }
Batch control (Batch)
For example, if Items contains 10 items and Batch is [3], the items are divided into batches of 3. This results in four batches with sizes of 3, 3, 3, and 1, assuming all item executions succeed.
YAML
Batch: [1, 2, 3] # Optional. You can define batch control using a list of numbers or percentages, such as [3]. Mode: BatchJSON (see the comments in the YAML example for details)
{ "Batch": [ 1, 2, 3 ], "Mode": "Batch" }For example, if Items contains 10 items and Batch is [30%], the batch size is 3 (30% of 10). This results in four batches with sizes of 3, 3, 3, and 1, assuming all item executions succeed:
YAML
Batch: [30%] # Optional. You can define batch control using a list of numbers or percentages, such as [30%]. Mode: BatchJSON (see the comments in the YAML example for details)
{ "Batch": [ "30%" ], "Mode": "Batch" }For example, if Items contains 10 items and Batch is [3, 10%, 30%], the first batch size is 3, the second is 1 (10% of 10), and the third and subsequent batches are 3 (30% of 10). This results in four batches with sizes of 3, 1, 3, and 3, assuming all item executions succeed.
YAML
Mode: Batch Batch: [3, 10%,30%] # Optional. You can define batch control using a list that contains multiple numbers or percentages, such as [3, 10%, 30%].JSON (see the comments in the YAML example for details)
{ "Mode": "Batch", "Batch": [ 3, "10%", "30%" ] }
Error control with MaxErrors
You can define the MaxErrors property in a Loop. This property works as follows:
You can specify a number or a percentage of the total number of items. For example, 10 or 10%. The default value is 0, which means that if any item fails, the entire loop task is marked as failed.
The first item in the loop is always executed.
Whether subsequent items are executed depends on if the number of errors (ErrorCount) exceeds the MaxErrors value.
If the number of errors exceeds the MaxErrors value, the loop stops executing subsequent items, and the loop task is marked as failed.
If the number of errors is less than or equal to the MaxErrors value, the loop continues to execute.
The final status of the loop task is determined by comparing the total ErrorCount with MaxErrors. If ErrorCount is greater than MaxErrors, the task is marked as Failed. Otherwise, it is marked as Success.
Specify as a number.
YAML
MaxErrors: 2 # Optional. You can specify a number or a percentage. For example, 2 means the maximum allowed ErrorCount is 2.JSON (see the comments in the YAML example for details)
{ "MaxErrors": 2 }
Specify as a percentage.
YAML
MaxErrors: 25% # Optional. You can specify a number or a percentage. For example, for 4 items, 25% means the maximum allowed ErrorCount is 25% × 4 = 1.JSON (see the comments in the YAML example for details)
{ "MaxErrors": "25%" }
Loop outputs
A Loop in a task or template can produce outputs. The final output of a Loop is an aggregation of the outputs from each item's execution. You can define the AggregateType property to select a built-in function for this aggregation.
Define the AggregateType property.
YAML
AggregateType: Fn::Max # Select a built-in function to aggregate the Loop outputs, such as Fn::Max. This means the largest value of the Number-type OutputParameterName1 from all sub-task outputs is used as the Loop's output value.JSON (see the comments in the YAML example for details)
{
"AggregateType": "Fn::Max"
} Examples
Concurrent mode
YAML format
FormatVersion: OOS-2019-06-01
Description: Creates one or more ECS instances.
Parameters:
regionId:
Description: The ID of region.
Type: String
Default: '{{ ACS::RegionId }}'
imageId:
Description: The ID of the image resource that you specify when you create the
instance.
Type: String
AllowedPattern: '[A-Za-z0-9_\-\.]*'
MinLength: 1
MaxLength: 100
instanceType:
Description: The type of the instance.
Type: String
AllowedPattern: ecs\.[A-Za-z0-9\.\-]*
MaxLength: 30
MinLength: 1
securityGroupId:
Description: The ID of the security group to which the instance belongs.
Type: String
AllowedPattern: sg-[A-Za-z0-9]*
MaxLength: 30
MinLength: 1
vSwitchId:
Description: The ID of the VSwitch.
Type: String
AllowedPattern: vsw-[A-Za-z0-9]*
MaxLength: 30
MinLength: 1
amount:
Description: The specified number of instances you want to create.
Type: Number
Default: 1
internetMaxBandwidthIn:
Description: The maximum inbound public bandwidth.
Type: Number
Default: 200
internetMaxBandwidthOut:
Description: The maximum outbound public bandwidth.
Type: Number
Default: 0
Tasks:
- Name: runInstances
Action: ACS::ExecuteAPI
Description: Creates one or more instances.
Properties:
Service: ECS
API: RunInstances
Parameters:
RegionId: '{{ regionId }}'
Amount: '{{ amount }}'
ImageId: '{{ imageId }}'
InstanceType: '{{ instanceType }}'
SecurityGroupId: '{{ securityGroupId }}'
VSwitchId: '{{ vSwitchId }}'
InternetMaxBandwidthIn: '{{ internetMaxBandwidthIn }}'
InternetMaxBandwidthOut: '{{ internetMaxBandwidthOut }}'
Outputs:
instanceIds:
Type: List
ValueSelector: InstanceIdSets.InstanceIdSet[]
- Name: untilInstanceReady
Action: ACS::WaitFor
Description: Waits for the created instances to be Running.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
RegionId: '{{ regionId }}'
InstanceIds:
- '{{ ACS::TaskLoopItem }}'
DesiredValues:
- Running
PropertySelector: Instances.Instance[].Status
Loop:
RateControl:
Mode: Concurrency
MaxErrors: 0
Concurrency: 1
Items: '{{ runInstances.instanceIds }}'
Outputs:
instanceIds:
Type: List
Value: '{{ runInstances.instanceIds }}'
JSON format
{
"FormatVersion": "OOS-2019-06-01",
"Description": "Creates one or more ECS instances.",
"Parameters": {
"regionId": {
"Description": "The ID of region.",
"Type": "String",
"Default": "{{ ACS::RegionId }}"
},
"imageId": {
"Description": "The ID of the image resource that you specify when you create the instance.",
"Type": "String",
"AllowedPattern": "[A-Za-z0-9_\\-\\.]*",
"MinLength": 1,
"MaxLength": 100
},
"instanceType": {
"Description": "The type of the instance.",
"Type": "String",
"AllowedPattern": "ecs\\.[A-Za-z0-9\\.\\-]*",
"MaxLength": 30,
"MinLength": 1
},
"securityGroupId": {
"Description": "The ID of the security group to which the instance belongs.",
"Type": "String",
"AllowedPattern": "sg-[A-Za-z0-9]*",
"MaxLength": 30,
"MinLength": 1
},
"vSwitchId": {
"Description": "The ID of the VSwitch.",
"Type": "String",
"AllowedPattern": "vsw-[A-Za-z0-9]*",
"MaxLength": 30,
"MinLength": 1
},
"amount": {
"Description": "The specified number of instances you want to create.",
"Type": "Number",
"Default": 1
},
"internetMaxBandwidthIn": {
"Description": "The maximum inbound public bandwidth.",
"Type": "Number",
"Default": 200
},
"internetMaxBandwidthOut": {
"Description": "The maximum outbound public bandwidth.",
"Type": "Number",
"Default": 0
}
},
"Tasks": [
{
"Name": "runInstances",
"Action": "ACS::ExecuteAPI",
"Description": "Creates one or more instances.",
"Properties": {
"Service": "ECS",
"API": "RunInstances",
"Parameters": {
"RegionId": "{{ regionId }}",
"Amount": "{{ amount }}",
"ImageId": "{{ imageId }}",
"InstanceType": "{{ instanceType }}",
"SecurityGroupId": "{{ securityGroupId }}",
"VSwitchId": "{{ vSwitchId }}",
"InternetMaxBandwidthIn": "{{ internetMaxBandwidthIn }}",
"InternetMaxBandwidthOut": "{{ internetMaxBandwidthOut }}"
}
},
"Outputs": {
"instanceIds": {
"Type": "List",
"ValueSelector": "InstanceIdSets.InstanceIdSet[]"
}
}
},
{
"Name": "untilInstanceReady",
"Action": "ACS::WaitFor",
"Description": "Waits for the created instances to be Running.",
"Properties": {
"Service": "ECS",
"API": "DescribeInstances",
"Parameters": {
"RegionId": "{{ regionId }}",
"InstanceIds": [
"{{ ACS::TaskLoopItem }}"
]
},
"DesiredValues": [
"Running"
],
"PropertySelector": "Instances.Instance[].Status"
},
"Loop": {
"RateControl": {
"Mode": "Concurrency",
"MaxErrors": 0,
"Concurrency": 1
},
"Items": "{{ runInstances.instanceIds }}"
}
}
],
"Outputs": {
"instanceIds": {
"Type": "List",
"Value": "{{ runInstances.instanceIds }}"
}
}
}Batch mode
YAML format
FormatVersion: OOS-2019-06-01
Description: Creates one or more ECS instances.
Parameters:
regionId:
Description: The ID of region.
Type: String
Default: '{{ ACS::RegionId }}'
imageId:
Description: The ID of the image resource that you specify when you create the
instance.
Type: String
AllowedPattern: '[A-Za-z0-9_\-\.]*'
MinLength: 1
MaxLength: 100
instanceType:
Description: The type of the instance.
Type: String
AllowedPattern: ecs\.[A-Za-z0-9\.\-]*
MaxLength: 30
MinLength: 1
securityGroupId:
Description: The ID of the security group to which the instance belongs.
Type: String
AllowedPattern: sg-[A-Za-z0-9]*
MaxLength: 30
MinLength: 1
vSwitchId:
Description: The ID of the VSwitch.
Type: String
AllowedPattern: vsw-[A-Za-z0-9]*
MaxLength: 30
MinLength: 1
amount:
Description: The specified number of instances you want to create.
Type: Number
Default: 1
internetMaxBandwidthIn:
Description: The maximum inbound public bandwidth.
Type: Number
Default: 200
internetMaxBandwidthOut:
Description: The maximum outbound public bandwidth.
Type: Number
Default: 0
Tasks:
- Name: runInstances
Action: ACS::ExecuteAPI
Description: Creates one or more instances.
Properties:
Service: ECS
API: RunInstances
Parameters:
RegionId: '{{ regionId }}'
Amount: '{{ amount }}'
ImageId: '{{ imageId }}'
InstanceType: '{{ instanceType }}'
SecurityGroupId: '{{ securityGroupId }}'
VSwitchId: '{{ vSwitchId }}'
InternetMaxBandwidthIn: '{{ internetMaxBandwidthIn }}'
InternetMaxBandwidthOut: '{{ internetMaxBandwidthOut }}'
Outputs:
instanceIds:
Type: List
ValueSelector: InstanceIdSets.InstanceIdSet[]
- Name: untilInstanceReady
Action: ACS::WaitFor
Description: Waits for the created instances to be Running.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
RegionId: '{{ regionId }}'
InstanceIds:
- '{{ ACS::TaskLoopItem }}'
DesiredValues:
- Running
PropertySelector: Instances.Instance[].Status
Loop:
RateControl:
Mode: Concurrency
MaxErrors: 0
Concurrency: 1
Items: '{{ runInstances.instanceIds }}'
Outputs:
instanceIds:
Type: List
Value: '{{ runInstances.instanceIds }}'
JSON format
{
"FormatVersion": "OOS-2019-06-01",
"Description": "Creates one or more ECS instances.",
"Parameters": {
"regionId": {
"Description": "The ID of region.",
"Type": "String",
"Default": "{{ ACS::RegionId }}"
},
"imageId": {
"Description": "The ID of the image resource that you specify when you create the instance.",
"Type": "String",
"AllowedPattern": "[A-Za-z0-9_\\-\\.]*",
"MinLength": 1,
"MaxLength": 100
},
"instanceType": {
"Description": "The type of the instance.",
"Type": "String",
"AllowedPattern": "ecs\\.[A-Za-z0-9\\.\\-]*",
"MaxLength": 30,
"MinLength": 1
},
"securityGroupId": {
"Description": "The ID of the security group to which the instance belongs.",
"Type": "String",
"AllowedPattern": "sg-[A-Za-z0-9]*",
"MaxLength": 30,
"MinLength": 1
},
"vSwitchId": {
"Description": "The ID of the VSwitch.",
"Type": "String",
"AllowedPattern": "vsw-[A-Za-z0-9]*",
"MaxLength": 30,
"MinLength": 1
},
"amount": {
"Description": "The specified number of instances you want to create.",
"Type": "Number",
"Default": 1
},
"internetMaxBandwidthIn": {
"Description": "The maximum inbound public bandwidth.",
"Type": "Number",
"Default": 200
},
"internetMaxBandwidthOut": {
"Description": "The maximum outbound public bandwidth.",
"Type": "Number",
"Default": 0
}
},
"Tasks": [
{
"Name": "runInstances",
"Action": "ACS::ExecuteAPI",
"Description": "Creates one or more instances.",
"Properties": {
"Service": "ECS",
"API": "RunInstances",
"Parameters": {
"RegionId": "{{ regionId }}",
"Amount": "{{ amount }}",
"ImageId": "{{ imageId }}",
"InstanceType": "{{ instanceType }}",
"SecurityGroupId": "{{ securityGroupId }}",
"VSwitchId": "{{ vSwitchId }}",
"InternetMaxBandwidthIn": "{{ internetMaxBandwidthIn }}",
"InternetMaxBandwidthOut": "{{ internetMaxBandwidthOut }}"
}
},
"Outputs": {
"instanceIds": {
"Type": "List",
"ValueSelector": "InstanceIdSets.InstanceIdSet[]"
}
}
},
{
"Name": "untilInstanceReady",
"Action": "ACS::WaitFor",
"Description": "Waits for the created instances to be Running.",
"Properties": {
"Service": "ECS",
"API": "DescribeInstances",
"Parameters": {
"RegionId": "{{ regionId }}",
"InstanceIds": [
"{{ ACS::TaskLoopItem }}"
]
},
"DesiredValues": [
"Running"
],
"PropertySelector": "Instances.Instance[].Status"
},
"Loop": {
"RateControl": {
"Mode": "Concurrency",
"MaxErrors": 0,
"Concurrency": 1
},
"Items": "{{ runInstances.instanceIds }}"
}
}
],
"Outputs": {
"instanceIds": {
"Type": "List",
"Value": "{{ runInstances.instanceIds }}"
}
}
}