All Products
Search
Document Center

Resource Orchestration Service:Use ROS CDK to create multiple resources at a time

Last Updated:Feb 28, 2026

Create a security group with multiple inbound access rules by using a for loop in Resource Orchestration Service (ROS) Cloud Development Toolkit (CDK). The loop pattern defines multiple similar resources without duplicating code.

When values are known ahead of time, such as a list of ports, use native language loops (for in TypeScript, foreach in C#). These loops run at synthesis time and are the simplest way to create multiple resources from static data.

Prerequisites

Before you begin, make sure you have:

  • ROS CDK installed (npm install -g @alicloud/ros-cdk-cli)

  • An Alibaba Cloud account with a valid AccessKey pair

  • Node.js and npm installed (for the TypeScript example)

Step 1: Initialize a project

Create a project directory and initialize a new ROS CDK project:

mkdir demo
cd demo
ros-cdk init --language=typescript --generate-only=true

Step 2: Configure an Alibaba Cloud credential

  1. Run the configuration command:

       ros-cdk config
  2. Enter the credential parameters when prompted: This example uses mode 1 (AccessKey) with the cn-beijing region. Choose the authentication mode and region that match your environment.

       ros-cdk config
       endpoint(optional, default:https://ros.aliyuncs.com):
       defaultRegionId(optional, default:cn-hangzhou):cn-beijing
    
       [1] AK
       [2] StsToken
       [3] RamRoleArn
       [4] EcsRamRole
       [0] CANCEL
    
       Authenticate mode [1...4 / 0]: 1
       accessKeyId:************************
       accessKeySecret:******************************
    
        ✅ Your cdk configuration has been saved successfully!

Step 3: Install dependencies

  1. Add the @alicloud/ros-cdk-ecs package to package.json. This package provides Elastic Compute Service (ECS) constructs for creating security groups and ingress rules.

       // package.json
       {
         "name": "demo",
         "version": "0.1.0",
         "bin": {
           "demo": "bin/demo.js"
         },
         "scripts": {
           "build": "tsc",
           "test": "jest"
         },
         "devDependencies": {
           "@types/jest": "^25.2.1",
           "@types/node": "10.17.5",
           "typescript": "^3.9.7",
           "jest": "^25.5.0",
           "ts-jest": "^25.3.1",
           "ts-node": "^8.1.0",
           "babel-jest": "^26.6.3",
           "@babel/core": "^7.12.9",
           "@babel/preset-env": "7.12.7",
           "@babel/preset-typescript": "^7.12.7",
           "@alicloud/ros-cdk-assert": "^1.4.0"
         },
         "dependencies": {
           "@alicloud/ros-cdk-core": "^1.4.0",
           "@alicloud/ros-cdk-ecs": "^1.4.0"
         }
       }
  2. Install the dependencies:

       npm install

Step 4: Write the stack code

Edit lib/demo-stack.ts to define a security group with three inbound rules (SecurityGroupIngress). The for loop iterates over a list of ports and creates one ingress rule per port.

The following examples show the same logic in four languages. Each creates:

  • A security group

  • Three inbound rules for TCP ports 22 (SSH), 3389 (RDP), and 80 (HTTP)

TypeScript

// lib/demo-stack.ts
import * as ros from '@alicloud/ros-cdk-core';
import * as ecs from '@alicloud/ros-cdk-ecs';

export class DemoStack extends ros.Stack {
  constructor(scope: ros.Construct, id: string, props?: ros.StackProps) {
    super(scope, id, props);
    new ros.RosInfo(this, ros.RosInfo.description, "This is the simple ros cdk app example.");
    // The code that defines your stack goes here

    const sg = new ecs.SecurityGroup(this, 'ros-cdk-test-sg');

    let PortList= ['22','3389','80'];
    for (let port of PortList) {
       new ecs.SecurityGroupIngress(this, `ros-cdk-test-sg-ingress-${port}`, {
        portRange: `${port}/${port}`,
        nicType: 'intranet',
        sourceCidrIp: '0.0.0.0/0',
        ipProtocol: 'tcp',
        securityGroupId: sg.attrSecurityGroupId
      },true);
    }
  }
}

Java

// src/main/java/com/myorg/DemoStack.java
package com.myorg;

import com.aliyun.ros.cdk.core.*;

import com.aliyun.ros.cdk.ecs.*;

import java.util.ArrayList;
import java.util.List;

public class DemoStack extends Stack {
    public DemoStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public DemoStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your stack goes here
        List<String> port_list = new ArrayList<>();
        port_list.add("22");
        port_list.add("3389");
        port_list.add("80");
        SecurityGroup sg = SecurityGroup.Builder.create(this, "sg").build();
        for (String element : port_list) {
            SecurityGroupIngress.Builder.create(this, "ros-cdk-test-sg-ingress-" + element).
                    nicType("intranet").sourceCidrIp("0.0.0.0/0").ipProtocol("tcp").securityGroupId(sg.getAttrSecurityGroupId()).portRange(element + "/" + element).build();
        }

    }
}

Python

# demo/demo_stack.py
import ros_cdk_core as core
import ros_cdk_ecs as ecs


class DemoStack(core.Stack):

    def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        sg = ecs.SecurityGroup(self, "ros-cdk-test-sg")

        prot_list = ["22", "3389", "80"]

        for i in prot_list:
            ecs.SecurityGroupIngress(self, "ros-cdk-test-sg-ingress-" + i,
                                     ecs.SecurityGroupIngressProps(port_range=i + "/" + i, nic_type="intranet",
                                                                   source_cidr_ip="0.0.0.0/0",
                                                                   ip_protocol="tcp",
                                                                   security_group_id=sg.attr_security_group_id))

C#

// src/Demo/DemoStack.cs
using AlibabaCloud.SDK.ROS.CDK.Core;
using AlibabaCloud.SDK.ROS.CDK.Ecs;

namespace Demo
{
    public class DemoStack : Stack
    {
        public DemoStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your stack goes here

            var sg = new SecurityGroup(this, "ros-cdk-test-sg");

            object[] portArray = new object[3] {"22", "3389", "80"};

            foreach (var port in  portArray)
            {
                new SecurityGroupIngress(this, "ros-cdk-test-sg-ingress-" + port, new SecurityGroupIngressProps
                {
                    PortRange = port+ "/" + port,
                    NicType = "intranet",
                    SourceCidrIp = "0.0.0.0/0",
                    IpProtocol = "tcp",
                    SecurityGroupId = sg.AttrSecurityGroupId
                });
            }

        }
    }
}

Step 5: Synthesize the template

Run the synth command to generate a ROS template from the stack code. This previews the resources without making changes to your account.

ros-cdk synth --json

Expected output:

{
  "Description": "This is the simple ros cdk app example.",
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "TemplateTags": [
        "Create by ROS CDK"
      ]
    }
  },
  "ROSTemplateFormatVersion": "2015-09-01",
  "Resources": {
    "ros-cdk-test-sg": {
      "Type": "ALIYUN::ECS::SecurityGroup"
    },
    "ros-cdk-test-sg-ingress-22": {
      "Type": "ALIYUN::ECS::SecurityGroupIngress",
      "Properties": {
        "IpProtocol": "tcp",
        "PortRange": "22/22",
        "NicType": "intranet",
        "Priority": 1,
        "SecurityGroupId": {
          "Fn::GetAtt": [
            "ros-cdk-test-sg",
            "SecurityGroupId"
          ]
        },
        "SourceCidrIp": "0.0.0.0/0"
      }
    },
    "ros-cdk-test-sg-ingress-3389": {
      "Type": "ALIYUN::ECS::SecurityGroupIngress",
      "Properties": {
        "IpProtocol": "tcp",
        "PortRange": "3389/3389",
        "NicType": "intranet",
        "Priority": 1,
        "SecurityGroupId": {
          "Fn::GetAtt": [
            "ros-cdk-test-sg",
            "SecurityGroupId"
          ]
        },
        "SourceCidrIp": "0.0.0.0/0"
      }
    },
    "ros-cdk-test-sg-ingress-80": {
      "Type": "ALIYUN::ECS::SecurityGroupIngress",
      "Properties": {
        "IpProtocol": "tcp",
        "PortRange": "80/80",
        "NicType": "intranet",
        "Priority": 1,
        "SecurityGroupId": {
          "Fn::GetAtt": [
            "ros-cdk-test-sg",
            "SecurityGroupId"
          ]
        },
        "SourceCidrIp": "0.0.0.0/0"
      }
    }
  }
}

The template confirms that the for loop expanded into three separate ALIYUN::ECS::SecurityGroupIngress resources, one for each port. Each ingress rule references the security group through Fn::GetAtt.

Step 6: Deploy the stack

Deploy the stack to create the resources in your Alibaba Cloud account:

ros-cdk deploy --sync=true

Expected output:

DemoStack: deploying...
|DemoStack               |2021-12-28T09:17:54 | CREATE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress | sg-2ze7gbyb0sngx7et**** | ros-cdk-test-sg-ingress-22

|DemoStack               |2021-12-28T09:17:54 | CREATE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress | sg-2ze7gbyb0sngx73a**** | ros-cdk-test-sg-ingress-80

|DemoStack               |2021-12-28T09:17:54 | CREATE_COMPLETE      | ALIYUN::ECS::SecurityGroup | sg-2ze7gbyb0sngx7r4**** | ros-cdk-test-sg

|DemoStack               |2021-12-28T09:17:54 | CREATE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress | sg-2ze7gbyb0snget3**** | ros-cdk-test-sg-ingress-3389


 ✅ The deployment(sync deploy stack) has finished!
status: CREATE_COMPLETE
StatusReason: Stack CREATE completed successfully
StackId: a6f1fd14-c985-4dd2-9913-1e7bbeef****

Step 7 (optional): Delete the stack

To clean up the resources created in this tutorial, delete the stack:

  1. Run the destroy command:

       ros-cdk destroy --sync=true
  2. Confirm the deletion when prompted: Expected output:

       The following stack(s) will be destroyed(Only deployed stacks will be displayed).
    
       DemoStack
    
       Please confirm.(Y/N)
       y
       DemoStack: destroying...
       |DemoStack               | DELETE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress |  | ros-cdk-test-sg-ingress-22
    
       |DemoStack               | DELETE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress |  | ros-cdk-test-sg-ingress-80
    
       |DemoStack               | DELETE_COMPLETE      | ALIYUN::ECS::SecurityGroup |  | ros-cdk-test-sg
    
       |DemoStack               | DELETE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress |  | ros-cdk-test-sg-ingress-3389
    
    
       ✅ The task(sync destroy stack) has finished!
       status: DELETE_COMPLETE
       StatusReason: Stack DELETE completed successfully
       StackId: a6f1fd14-c985-4dd2-9913-1e7bbeef****

References

  • API reference page: The CDK construct library provides a collection of API operations for you to build your CDK applications. For more information about how to use the API operations and the features of the API operations, see Ros Cdk References.

  • CDK command: For more information about how to use CDK commands and the usage examples, see ROS CDK commands.

  • CDK feature: For more information about how to use CDK features such as outputs and pseudo parameters and the usage examples, see ROS CDK features.

  • GitHub repository: For more information about the official GitHub repository of ROS CDK, visit Resource-Orchestration-Service-Cloud-Development-Kit. On the website, you can submit issues and view the service license and release notes.