This topic describes how to use Cloud Development Toolkit (CDK) of Resource Orchestration Service (ROS) in different programming languages. In this topic, a virtual private cloud (VPC) and a vSwitch of Alibaba Cloud are created and associated.
Scenario
If you want to create and configure resources by using a familiar programming language, you can use ROS CDK. ROS CDK frees you from the complex syntax of JSON and YAML templates and automates resource deployment and O&M. For more information, see Overview.
Supported programming languages
TypeScript
JavaScript
Java
Python
C#
Go
Prerequisites
Java: Java Development Kit (JDK) and Maven of the following versions are used:
JDK: JDK 8 or later
Maven: Maven 3.6 or later
Python: Python 3.7 or later is used.
C#: .NET Core 3.1 is installed on your on-premises environment. .NET SDK 5.0 or later is used.
Step 1: Initialize a project
Each ROS CDK application must be created in a separate project directory. The application uses the dependencies of modules in the directory. Before you create an application, you must create a project directory and initialize the project.
Run the following commands to create a project directory and initialize the project:
TypeScript
mkdir demo
cd demo
ros-cdk init --language=typescript --generate-only=trueJavaScript
mkdir demo
cd demo
ros-cdk init --language=javascript --generate-only=trueJava
mkdir demo
cd demo
ros-cdk init --language=java --generate-only=truePython
mkdir demo
cd demo
ros-cdk init --language=python --generate-only=trueRun the following command to create a virtual environment that belongs to the current project.
You must run the command because a virtual environment is required to run a Python project.
python3 -m venv .venvRun the following command to go to the virtual environment:
source .venv/bin/activateC#
mkdir demo
cd demo
ros-cdk init --language=csharp --generate-only=trueGo
mkdir demo
cd demo
ros-cdk init --language=go --generate-only=trueStep 2: Configure an Alibaba Cloud credential
Run the following command to configure an Alibaba Cloud credential:
ros-cdk configFollow on-screen instructions to configure the credential parameters.
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!Parameter description:
endpoint: the endpoint of ROS. Default value: https://ros.aliyuncs.com.
defaultRegionId: the ID of the region where you want to deploy the ROS stack. Default value: cn-hangzhou.
Authenticate mode: the authentication method. In this example, an AccessKey pair is used for authentication. In this case, you must specify the AccessKey ID and the AccessKey secret. For more information about how to obtain an AccessKey pair, see Configure a credential in interactive mode (fast).
Step 3: (Optional) Preview the project structure
Run the following command to preview the project structure:
tree .Command output:
TypeScript
.
├── README.md
├── bin
│ └── demo.ts
├── cdk.json
├── jest.config.js
├── lib
│ └── demo-stack.ts
├── package.json
├── test
│ └── demo.test.ts
└── tsconfig.json
4 directories, 8 filesThe following section describes the project structure:
bin/demo.ts: the launch file of the project.NoteA project can contain only one application.
In this example, an application of the ros.App type and a stack that is named DemoStack and is of the DemoStack type are created. The stack is added to the application. The
demo.tsfile contains the following content:#!/usr/bin/env node import * as ros from '@alicloud/ros-cdk-core'; import { DemoStack } from '../lib/demo-stack'; const app = new ros.App({outdir: './cdk.out'}); new DemoStack(app, 'DemoStack'); app.synth();lib/demo-stack.ts: the definition file of the stack.You can add resources to the stack to dynamically create the stack. In the code generated when the project is initialized, the file provides only the description of the stack. The
demo-stack.tsfile contains the following content:import * as ros from '@alicloud/ros-cdk-core'; 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 } }test/demo.test.ts: the unit testing file.The file is used to check whether the stack is created based on the expected logic. The
demo.test.tsfile contains the following content:import { expect as expectCDK, matchTemplate, MatchStyle } from '@alicloud/ros-cdk-assert'; import * as ros from '@alicloud/ros-cdk-core'; import * as Demo from '../lib/demo-stack'; test('Stack with version.', () => { const app = new ros.App(); // WHEN const stack = new Demo.DemoStack(app, 'MyTestStack'); // THEN expectCDK(stack).to( matchTemplate( { ROSTemplateFormatVersion: '2015-09-01', Description: "This is the simple ros cdk app example.", Metadata: { "ALIYUN::ROS::Interface": { "TemplateTags" : [ "Create by ROS CDK" ] } } }, MatchStyle.EXACT, ), ); });
JavaScript
.
├── README.md
├── bin
│ └── demo.js
├── cdk.json
├── jest.config.js
├── lib
│ └── demo-stack.js
├── package.json
└── test
└── demo.test.js
4 directories, 7 filesThe following section describes the project structure:
bin/demo.js: the launch file of the project.NoteA project can contain only one application.
In this example, an application of the ros.App type and a stack that is named DemoStack and is of the DemoStack type are created. The stack is added to the application. The
demo.jsfile contains the following content:#!/usr/bin/env node const ros = require('@alicloud/ros-cdk-core'); const { DemoStack } = require('../lib/demo-stack'); const app = new ros.App(); new DemoStack(app, 'DemoStack'); app.synth();lib/demo-stack.js: the definition file of the stack.You can add resources to the stack to dynamically create the stack. In the code generated when the project is initialized, the file provides only the description of the stack. The
demo-stack.jsfile contains the following content:const ros = require('@alicloud/ros-cdk-core'); class DemoStack extends ros.Stack { /** * * @param {ros.Construct} scope * @param {string} id * @param {ros.StackProps} props */ constructor(scope, id, props) { 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 } } module.exports = { DemoStack }test/demo.test.js: the unit testing file.The file is used to check whether the stack is created based on the expected logic. The
demo.test.jsfile contains the following content:const { expect, matchTemplate, MatchStyle } = require('@alicloud/ros-cdk-assert'); const ros = require('@alicloud/ros-cdk-core'); const Demo = require('../lib/demo-stack'); test('Stack with version.', () => { const app = new ros.App(); // WHEN const stack = new Demo.DemoStack(app, 'MyTestStack'); // THEN expect(stack).to(matchTemplate({ ROSTemplateFormatVersion: '2015-09-01', Description: "This is the simple ros cdk app example.", Metadata: { "ALIYUN::ROS::Interface": { "TemplateTags" : [ "Create by ROS CDK" ] } } }, MatchStyle.EXACT)) });
Java
.
├── README.md
├── cdk.json
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── myorg
│ ├── DemoApp.java
│ └── DemoStack.java
└── test
└── java
└── com
└── myorg
└── DemoTest.java
10 directories, 6 filesThe following section describes the project structure:
src/main/java/com/myorg/DemoApp.java: the launch file of the project.NoteA project can contain only one application.
In this example, an application of the App type and a stack that is named DemoStack and is of the DemoStack type are created. The stack is added to the application. The
DemoApp.javafile contains the following content:package com.myorg; import com.aliyun.ros.cdk.core.*; import java.util.Arrays; public class DemoApp { public static void main(final String[] args) { App app = new App(); new DemoStack(app, "DemoStack"); app.synth(); } }src/main/java/com/myorg/DemoStack.java: the definition file of the stack.You can add resources to the stack to dynamically create the stack. In the code generated when the project is initialized, the file provides only the description of the stack. The
DemoStack.javafile contains the following content:package com.myorg; import com.aliyun.ros.cdk.core.*; 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 } }src/test/java/com/myorg/DemoTest.java: the unit testing file.The file is used to check whether the stack is created based on the expected logic. The
DemoTest.javafile contains the following content:package com.myorg; import com.aliyun.ros.cdk.core.*; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; import com.fasterxml.jackson.databind.node.ArrayNode; import java.io.IOException; import static org.junit.Assert.assertEquals; public class DemoTest { private final static ObjectMapper JSON = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); @Test public void testStack() throws IOException { App app = new App(); DemoStack stack = new DemoStack(app, "test"); // synthesize the stack to a ROS template and compare against // a checked-in JSON file. JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); ObjectNode expected = new ObjectMapper().createObjectNode(); expected.put("ROSTemplateFormatVersion", "2015-09-01"); ObjectNode metadata = expected.putObject("Metadata"); ObjectNode rosInterface = metadata.putObject("ALIYUN::ROS::Interface"); ArrayNode templateTags = rosInterface.putArray("TemplateTags"); templateTags.add("Create by ROS CDK"); assertEquals(expected, actual); } }
Python
.
├── README.md
├── app.py
├── cdk.json
├── demo
│ ├── __init__.py
│ └── demo_stack.py
├── requirements.txt
├── setup.py
├── source.bat
└── test
├── __init__.py
└── test_demo.py
3 directories, 10 filesThe following section describes the project structure:
app.py: the launch file of the project.NoteA project can contain only one application.
In this example, an application of the core.App type and a stack that is named demo and is of the DemoStack type are created. The stack is added to the application. The
app.pyfile contains the following content:#!/usr/bin/env python3 import ros_cdk_core as core from demo.demo_stack import DemoStack app = core.App() DemoStack(app, "demo") app.synth()demo/demo_stack.py: the definition file of the stack.You can add resources to the stack to dynamically create the stack. In the code generated when the project is initialized, the file provides only the description of the stack. The
demo_stack.pyfile contains the following content:import ros_cdk_core as core 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 heretest/test_demo.py: the unit testing file.The file is used to check whether the stack is created based on the expected logic. The
test_demo.pyfile contains the following content:#!/usr/bin/env python3 import unittest import ros_cdk_core as core from demo.demo_stack import DemoStack class TestStack(unittest.TestCase): def setUp(self): pass def test_stack(self): app = core.App() stack = DemoStack(app, "testdemo") artifact = app.synth().get_stack_artifact(stack.artifact_id).template expect = { "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01" } self.assertDictContainsSubset(artifact, expect) def tearDown(self): pass if __name__ == '__main__': unittest.main()
C#
.
├── README.md
├── cdk.json
├── global.sln
└── src
├── Demo
│ ├── Demo.csproj
│ ├── DemoStack.cs
│ ├── GlobalSuppressions.cs
│ └── Program.cs
└── DemoTest
├── DemoTest.cs
└── DemoTest.csproj
4 directories, 9 filesAfter the project is initialized, an application file named Program.cs and a stack file named DemoStack.cs are automatically created. You can dynamically create a stack by using custom code in the DemoStack.cs file. The stack is automatically added to the application. A project can contain only one application. The following section describes the project structure:
src/Demo/DemoStack.cs: the stack file.In the code generated when the project is initialized, the file provides only the description of the stack. The
DemoStack.csfile contains the following content:using AlibabaCloud.SDK.ROS.CDK.Core; 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 } } }src/Demo/Program.cs: the application file.You can add the stack to the application. The
Program.csfile contains the following content:using AlibabaCloud.SDK.ROS.CDK.Core; using System; using System.Collections.Generic; using System.Linq; namespace Demo { sealed class Program { public static void Main(string[] args) { var app = new App(); new DemoStack(app, "DemoStack"); app.Synth(); } } }src/DemoTest/DemoTest.cs: the unit testing file.The file is used to check whether the stack is created based on the expected logic. The
DemoTest.csfile contains the following content:using AlibabaCloud.SDK.ROS.CDK.Core; using NUnit.Framework; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Demo; namespace Stack.UnitTests.Services { [TestFixture] public class Stack_IsStackShould { [Test] public void DemoStack_IsStackShould() { var app = new App(); var testStack = new DemoStack(app, "TestStack"); var result = app.Synth().GetStackArtifact(testStack.ArtifactId).Template; var actualJson = JsonConvert.SerializeObject(result); JObject obj = new JObject(); JObject metadata = new JObject(); JObject rosInterface = new JObject(); JArray templateTags = new JArray(); metadata.Add("ALIYUN::ROS::Interface", rosInterface); rosInterface.Add("TemplateTags", templateTags); templateTags.Add("Create by ROS CDK"); obj.Add("Metadata", metadata); obj.Add("ROSTemplateFormatVersion", "2015-09-01"); var expected = JsonConvert.SerializeObject(obj); Assert.AreEqual(actualJson, expected); } } }
Go
.
├── README.md
├── cdk.json
├── demo.go
├── demo_test.go
└── go.mod
1 directory, 5 filesThe following section describes the project structure:
demo.go: the launch file of the project, which is also the definition file of the stack.NoteA project can contain only one application.
In this example, an application of the ros.App type and a stack named NewDemoStack are created. The stack is added to the application.
package main import ( "github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore" ) type demoStackProps struct { alicloudroscdkcore.StackProps } func NewdemoStack(scope alicloudroscdkcore.Construct, id string, props *demoStackProps) alicloudroscdkcore.Stack { var sprops alicloudroscdkcore.StackProps if props != nil { sprops = props.StackProps } stack := alicloudroscdkcore.NewStack(scope, &id, &sprops) // The code that defines your stack goes here return stack } func main() { app := alicloudroscdkcore.NewApp(nil) props := &demoStackProps{} NewdemoStack(app, "demoStack", props) app.Synth(nil) }demo_test.go: the unit testing file.The file is used to check whether the stack is created based on the expected logic. The
demo_test.gofile contains the following content:package main import ( "github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore" "github.com/stretchr/testify/assert" "testing" ) func TestNewdemoStack(t *testing.T) { app := alicloudroscdkcore.NewApp(nil) props := &demoStackProps{} stack := NewdemoStack(app, "myTestStack", props) artifact := app.Synth(nil).GetStackArtifact(stack.ArtifactId()).Template() expect := map[string]interface{}{ "Metadata": map[string]interface{}{ "ALIYUN::ROS::Interface": map[string]interface{}{ "TemplateTags": []interface{}{"Create by ROS CDK"}, }, }, "ROSTemplateFormatVersion": "2015-09-01", } assert.Equal(t, expect, artifact) }
Step 4: Install dependencies
Add the dependency package of Elastic Compute Service (ECS).
TypeScript
Modify the
package.jsonfile.{ "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" } }JavaScript
Modify the
package.jsonfile.{ "name": "demo", "version": "0.1.0", "bin": { "demo": "bin/demo.js" }, "scripts": { "build": "echo \"The build step is not required when using JavaScript!\" && exit 0", "cdk": "cdk", "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" } }Java
Modify the
pom.xmlfile.<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.myorg</groupId> <artifactId>demo</artifactId> <version>0.1</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <cdk.version>1.4.0</cdk.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <configuration> <mainClass>com.myorg.DemoApp</mainClass> </configuration> </plugin> </plugins> </build> <dependencies> <!-- AliCloud ROS Cloud Development Kit (ROS CDK) --> <dependency> <groupId>com.aliyun</groupId> <artifactId>ros-cdk-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>ros-cdk-ecs</artifactId> <version>1.4.0</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>Python
Modify the
requirements.txtfile.ros-cdk-core==1.4.0 ros-cdk-ecs==1.4.0C#
Modify the
src/Demo/Demo.csprojfile.<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> <!-- Roll forward to future major versions of the netcoreapp as needed --> <RollForward>Major</RollForward> </PropertyGroup> <ItemGroup> <!-- CDK Construct Library dependencies --> <PackageReference Include="AlibabaCloud.SDK.ROS.CDK.Core" Version="1.4.0" /> <PackageReference Include="AlibabaCloud.SDK.ROS.CDK.Ecs" Version="1.4.0" /> <!-- jsii Roslyn analyzers (un-comment to obtain compile-time checks for missing required props <PackageReference Include="Amazon.Jsii.Analyzers" Version="*" PrivateAssets="all" /> --> </ItemGroup> </Project>Go
Modify the
go.modfile.module demo go 1.18 require ( github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore v1.4.0 github.com/alibabacloud-go/ros-cdk/alicloudroscdkecs v1.4.0 github.com/stretchr/testify v1.8.4 )Install the dependencies.
TypeScript
npm installJavaScript
npm installJava
mvn compilePython
Method 1:
pip install -r requirements.txtMethod 2:
pip install ros-cdk-core ros-cdk-ecs
C#
NoteFor the C# programming language, you do not need to install the dependencies by running commands.
Go
go get
Step 5: Add resources
Add a VPC and a vSwitch.
TypeScript
Modify the
lib/demo-stack.tsfile.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 vpc = new ecs.Vpc(this, 'vpc-from-ros-cdk', { vpcName: 'test-ros-cdk', cidrBlock: '10.0.0.0/8', description: 'This is ros cdk test' }); new ecs.VSwitch(this, 'vsw-from-ros-cdk', { vSwitchName: 'test-ros-cdk', cidrBlock: '10.0.0.0/16', zoneId: 'cn-hangzhou-i', vpcId: vpc.ref }); } }JavaScript
Modify the
lib/demo-stack.jsfile.const ros = require('@alicloud/ros-cdk-core'); const ecs = require('@alicloud/ros-cdk-ecs'); class DemoStack extends ros.Stack { /** * * @param {ros.Construct} scope * @param {string} id * @param {ros.StackProps} props */ constructor(scope, id, props) { 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 vpc = new ecs.Vpc(this, 'vpc-from-ros-cdk', { vpcName: 'test-ros-cdk-javascript', cidrBlock: '10.0.0.0/8', description: 'This is ros cdk test', }); new ecs.VSwitch(this, 'vsw-from-ros-cdk', { vSwitchName: 'test-ros-cdk-javascript', cidrBlock: '10.0.0.0/16', zoneId: 'cn-hangzhou-i', vpcId: vpc.ref, }); } } module.exports = { DemoStack }Java
Modify the
DemoStack.javafile.package com.myorg; import com.aliyun.ros.cdk.core.*; import com.aliyun.ros.cdk.ecs.*; 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 Vpc vpc = Vpc.Builder.create(this, "vpc-from-ros-cdk").vpcName("TestJavaCDK").description("This is ros java cdk test"). cidrBlock("10.0.0.0/8").build(); VSwitch vsw = VSwitch.Builder.create(this, "vsw-from-ros-cdk").vSwitchName("TestJavaCDK").zoneId("cn-hangzhou-i"). cidrBlock("10.0.0.0/16").vpcId(vpc.getRef()).build(); } }Python
Modify the
demo_stack.pyfile.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 vpc = ecs.Vpc(self, "MyVPC", ecs.VPCProps( cidr_block='10.0.0.0/8', vpc_name='test-ros-cdk-python', description='This is ros python cdk test' )) ecs.VSwitch(self, "MyVSwitch", ecs.VSwitchProps( cidr_block='10.0.0.0/16', v_switch_name='test-ros-cdk-python', zone_id='cn-hangzhou-i', vpc_id=vpc.ref ))C#
Modify the
DemoStack.csfile.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) { var vpc = new Vpc(this, "vpc-from-ros-cdk", new VPCProps { VpcName = "test-ros-cdk-csharp", CidrBlock = "10.0.0.0/8", Description = "This is ros cdk test" }); new VSwitch(this, "vsw-from-ros-cdk", new VSwitchProps { VSwitchName = "test-ros-cdk-csharp", CidrBlock = "10.0.0.0/16", ZoneId="cn-hangzhou-i", VpcId=vpc.Ref, }); } } }Go
Replace the content of the
demo.gofile with the following code:package main import ( "github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore" "github.com/alibabacloud-go/ros-cdk/alicloudroscdkecs" ) type demoStackProps struct { alicloudroscdkcore.StackProps } func NewdemoStack(scope alicloudroscdkcore.Construct, id string, props *demoStackProps) alicloudroscdkcore.Stack { var sprops alicloudroscdkcore.StackProps if props != nil { sprops = props.StackProps } stack := alicloudroscdkcore.NewStack(scope, &id, &sprops) // The code that defines your stack goes here vpcKey := "Vpc" vpcProps := alicloudroscdkecs.VPCProps{CidrBlock: "10.0.0.0/8"} vpc := alicloudroscdkecs.NewVpc(stack, &vpcKey, &vpcProps, nil) vswKey := "VSwitch" vswProps := alicloudroscdkecs.VSwitchProps{ CidrBlock: "10.0.0.0/16", ZoneId: "cn-hangzhou-i", VpcId: vpc.Ref(), } alicloudroscdkecs.NewVSwitch(stack, &vswKey, &vswProps, nil) return stack } func main() { app := alicloudroscdkcore.NewApp(nil) props := &demoStackProps{} NewdemoStack(app, "demoStack", props) app.Synth(nil) }(Optional) Generate a template file.
TypeScript
ros-cdk synth --jsonJavaScript
ros-cdk synth --jsonJava
mvn compile ros-cdk synth --jsonPython
ros-cdk synth --jsonC#
ros-cdk synth --jsonGo
go get ros-cdk synth --jsonCommand output:
TypeScript
{ "Description": "This is the simple ros cdk app example.", "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros cdk test", "EnableIpv6": false, "VpcName": "test-ros-cdk" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "test-ros-cdk" } } } }JavaScript
{ "Description": "This is the simple ros cdk app example.", "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros cdk test", "EnableIpv6": false, "VpcName": "test-ros-cdk-javascript" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "test-ros-cdk-javascript" } } } }Java
{ "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros java cdk test", "EnableIpv6": false, "VpcName": "TestJavaCDK" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "TestJavaCDK" } } } }Python
{ "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros java cdk test", "EnableIpv6": false, "VpcName": "TestJavaCDK" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "TestJavaCDK" } } } }C#
{ "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros cdk test", "EnableIpv6": false, "VpcName": "test-ros-cdk-csharp" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "test-ros-cdk-csharp" } } } }Go
{ "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "Vpc": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "EnableIpv6": false } }, "VSwitch": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "Vpc" }, "ZoneId": "cn-hangzhou-i" } } } }
Step 6: (Optional) Perform unit testing
Check whether the VPC and vSwitch can be created in the stack.
TypeScript
Modify the
test/demo.test.tsfile.import { expect as expectCDK, matchTemplate, MatchStyle } from '@alicloud/ros-cdk-assert'; import * as ros from '@alicloud/ros-cdk-core'; import * as Demo from '../lib/demo-stack'; test('Stack with version.', () => { const app = new ros.App(); // WHEN const stack = new Demo.DemoStack(app, 'MyTestStack'); // THEN expectCDK(stack).to( matchTemplate( { "Description": "This is the simple ros cdk app example.", "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros cdk test", "EnableIpv6": false, "VpcName": "test-ros-cdk" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "test-ros-cdk" } } } }, MatchStyle.EXACT, ), ); });JavaScript
Modify the
demo.test.jsfile.const { expect, matchTemplate, MatchStyle } = require('@alicloud/ros-cdk-assert'); const ros = require('@alicloud/ros-cdk-core'); const Demo = require('../lib/demo-stack'); test('Stack with version.', () => { const app = new ros.App(); // WHEN const stack = new Demo.DemoStack(app, 'MyTestStack'); // THEN expect(stack).to(matchTemplate({ "Description": "This is the simple ros cdk app example.", "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "vpc-from-ros-cdk": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros cdk test", "EnableIpv6": false, "VpcName": "test-ros-cdk-javascript" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "vpc-from-ros-cdk" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "test-ros-cdk-javascript" } } } }, MatchStyle.EXACT)) });Java
Modify the
DemoTest.javafile.package com.myorg; import com.aliyun.ros.cdk.core.*; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; import com.fasterxml.jackson.databind.node.ArrayNode; import java.io.IOException; import static org.junit.Assert.assertEquals; public class DemoTest { private final static ObjectMapper JSON = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); @Test public void testStack() throws IOException { App app = new App(); DemoStack stack = new DemoStack(app, "test"); // synthesize the stack to a ROS template and compare against // a checked-in JSON file. JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); ObjectNode expected = new ObjectMapper().createObjectNode(); expected.put("ROSTemplateFormatVersion", "2015-09-01"); ObjectNode metadata = expected.putObject("Metadata"); ObjectNode rosInterface = metadata.putObject("ALIYUN::ROS::Interface"); ArrayNode templateTags = rosInterface.putArray("TemplateTags"); templateTags.add("Create by ROS CDK"); ObjectNode resources = expected.putObject("Resources"); ObjectNode vpc = resources.putObject("vpc-from-ros-cdk"); vpc.put("Type","ALIYUN::ECS::VPC"); ObjectNode vpcProperties = vpc.putObject("Properties"); vpcProperties.put("CidrBlock","10.0.0.0/8"); vpcProperties.put("Description","This is ros java cdk test"); vpcProperties.put("EnableIpv6",false); vpcProperties.put("VpcName","TestJavaCDK"); ObjectNode vsw = resources.putObject("vsw-from-ros-cdk"); vsw.put("Type","ALIYUN::ECS::VSwitch"); ObjectNode vswProperties = vsw.putObject("Properties"); vswProperties.put("CidrBlock","10.0.0.0/16"); ObjectNode vpcId = vswProperties.putObject("VpcId"); vpcId.put("Ref","vpc-from-ros-cdk"); vswProperties.put("ZoneId","cn-hangzhou-i"); vswProperties.put("VSwitchName","TestJavaCDK"); assertEquals(expected, actual); } }Python
Modify the
test_demo.pyfile.#!/usr/bin/env python3 import unittest import ros_cdk_core as core from demo.demo_stack import DemoStack class TestStack(unittest.TestCase): def setUp(self): pass def test_stack(self): app = core.App() stack = DemoStack(app, "testdemo") artifact = app.synth().get_stack_artifact(stack.artifact_id).template expect = { "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": { "MyVPC": { "Type": "ALIYUN::ECS::VPC", "Properties": { "CidrBlock": "10.0.0.0/8", "Description": "This is ros python cdk test", "EnableIpv6": False, "VpcName": "test-ros-cdk-python" } }, "MyVSwitch": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Ref": "MyVPC" }, "ZoneId": "cn-hangzhou-i", "VSwitchName": "test-ros-cdk-python" } } } } self.assertDictContainsSubset(artifact, expect) def tearDown(self): pass if __name__ == '__main__': unittest.main()C#
Modify the
DemoTest.csfile.using AlibabaCloud.SDK.ROS.CDK.Core; using NUnit.Framework; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Demo; namespace Stack.UnitTests.Services { [TestFixture] public class Stack_IsStackShould { [Test] public void DemoStack_IsStackShould() { var app = new App(); var testStack = new DemoStack(app, "TestStack"); var result = app.Synth().GetStackArtifact(testStack.ArtifactId).Template; var actualJson = JsonConvert.SerializeObject(result); JObject obj = new JObject(); JObject Resources = new JObject(); JObject VPC = new JObject(); JObject VSW = new JObject(); JObject vpcProperties = new JObject(); JObject vswProperties = new JObject(); JObject metadata = new JObject(); JObject rosInterface = new JObject(); JArray templateTags = new JArray(); JObject vpcId = new JObject(); metadata.Add("ALIYUN::ROS::Interface", rosInterface); rosInterface.Add("TemplateTags", templateTags); templateTags.Add("Create by ROS CDK"); obj.Add("Metadata", metadata); VPC.Add("Type", "ALIYUN::ECS::VPC"); VPC.Add("Properties", vpcProperties); Resources.Add("vpc-from-ros-cdk", VPC); vpcProperties.Add("CidrBlock", "10.0.0.0/8"); vpcProperties.Add("Description", "This is ros cdk test"); vpcProperties.Add("EnableIpv6", false); vpcProperties.Add("VpcName", "test-ros-cdk-csharp"); VSW.Add("Type", "ALIYUN::ECS::VSwitch"); VSW.Add("Properties", vswProperties); Resources.Add("vsw-from-ros-cdk", VSW); vswProperties.Add("CidrBlock", "10.0.0.0/16"); vpcId.Add("Ref", "vpc-from-ros-cdk"); vswProperties.Add("VpcId", vpcId); vswProperties.Add("ZoneId", "cn-hangzhou-i"); vswProperties.Add("VSwitchName", "test-ros-cdk-csharp"); obj.Add("ROSTemplateFormatVersion", "2015-09-01"); obj.Add("Resources", Resources); var expected = JsonConvert.SerializeObject(obj); Assert.AreEqual(actualJson, expected); } } }Go
Modify the
demo_test.gofile.package main import ( "github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore" "github.com/stretchr/testify/assert" "testing" ) func TestNewdemoStack(t *testing.T) { app := alicloudroscdkcore.NewApp(nil) props := &demoStackProps{} stack := NewdemoStack(app, "myTestStack", props) artifact := app.Synth(nil).GetStackArtifact(stack.ArtifactId()).Template() expect := map[string]interface{}{ "Metadata": map[string]interface{}{ "ALIYUN::ROS::Interface": map[string]interface{}{ "TemplateTags": []interface{}{"Create by ROS CDK"}, }, }, "ROSTemplateFormatVersion": "2015-09-01", "Resources": map[string]interface{}{ "Vpc": map[string]interface{}{ "Type": "ALIYUN::ECS::VPC", "Properties": map[string]interface{}{ "CidrBlock": "10.0.0.0/8", "EnableIpv6": false, }, }, "VSwitch": map[string]interface{}{ "Type": "ALIYUN::ECS::VSwitch", "Properties": map[string]interface{}{ "CidrBlock": "10.0.0.0/16", "VpcId": map[string]interface{}{ "Ref": "Vpc", }, "ZoneId": "cn-hangzhou-i", }, }, }, } assert.Equal(t, expect, artifact) }Perform unit testing.
TypeScript
npm testJavaScript
npm testJava
mvn testPython
python -m unittest -vC#
dotnet testGo
go get go testCommand output:
TypeScript
> demo@0.1.0 test > jest PASS test/demo.test.ts ✓ Stack with version. (89ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.731s Ran all test suites.JavaScript
> demo@0.1.0 test > jest PASS test/demo.test.js ✓ Stack with version. (94ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.298s Ran all test suites.Java
[INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.myorg.DemoTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.892 s -- in com.myorg.DemoTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.319 s [INFO] Finished at: 2024-03-26T14:20:08+08:00 [INFO] ------------------------------------------------------------------------Python
test_stack (test.test_demo.TestStack) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.021s OKC#
Starting test execution, please wait... A total of 1 test files matched the specified pattern. Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: 1 s - DemoTest.dll (netcoreapp3.1)Go
PASS ok demo 0.971s
Step 7: Deploy the stack
You can run ROS CDK commands to create, query, and delete the stack.
Run the following command to create the stack:
ros-cdk deploy --region cn-hangzhouCommand output:
✅ The deployment(create stack) has completed!
StackId: 701ecf04-d758-457f-a0fc-7e00e2b6****Step 8: (Optional) Query the stack
Run the following command to query the stack:
ros-cdk list-stacksCommand output:
✅ The Stacks list in cn-hangzhou is:
[
{
"Status": "CREATE_COMPLETE",
"OperationInfo": {},
"ResourceGroupId": "rg-acfm2xwmxvr****",
"ServiceManaged": false,
"StatusReason": "Stack CREATE completed successfully",
"CreateTime": "2024-03-25T06:02:10",
"DeletionProtection": "Disabled",
"StackType": "ROS",
"RegionId": "cn-hangzhou",
"DisableRollback": false,
"StackName": "DemoStack",
"Tags": [
{
"Value": "rg-acfm2xwmxvr****",
"Key": "acs:rm:rgId"
}
],
"TimeoutInMinutes": 20,
"StackId": "701ecf04-d758-457f-a0fc-7e00e2b6****"
}
] Step 9: (Optional) Update the stack
In this example, the description of the VPC is updated. The vSwitch is deleted.
TypeScript
Modify the
lib/demo-stack.tsfile.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 vpc = new ecs.Vpc(this, 'vpc-from-ros-cdk', { vpcName: 'test-ros-cdk', cidrBlock: '10.0.0.0/8', description: 'Test update vpc name by ros cdk.' }); } }JavaScript
Modify the
lib/demo-stack.jsfile.const ros = require('@alicloud/ros-cdk-core'); const ecs = require('@alicloud/ros-cdk-ecs'); class DemoStack extends ros.Stack { /** * * @param {ros.Construct} scope * @param {string} id * @param {ros.StackProps} props */ constructor(scope, id, props) { 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 vpc = new ecs.Vpc(this, 'vpc-from-ros-cdk', { vpcName: 'test-ros-cdk-javascript', cidrBlock: '10.0.0.0/8', description: 'Test update vpc name by ros cdk.', }); } } module.exports = { DemoStack }Java
Modify the
DemoStack.javafile.package com.myorg; import com.aliyun.ros.cdk.core.*; import com.aliyun.ros.cdk.ecs.*; 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 Vpc.Builder.create(this, "VPC").vpcName("TestJavaCDK").description("Test update vpc name by ros cdk."). cidrBlock("10.0.0.0/8").build(); } }Python
Modify the
demo_stack.pyfile.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 vpc = ecs.Vpc(self, "MyVPC", ecs.VPCProps( cidr_block='10.0.0.0/8', vpc_name='test-ros-cdk-python', description='Test update vpc name by ros cdk.' ))C#
Modify the
DemoStack.csfile.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) { var vpc = new Vpc(this, "vpc-from-ros-cdk", new VPCProps { VpcName = "test-ros-cdk-csharp", CidrBlock = "10.0.0.0/8", Description = "Test update vpc name by ros cdk." }); } } }Go
package main import ( "github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore" "github.com/alibabacloud-go/ros-cdk/alicloudroscdkecs" ) type demoStackProps struct { alicloudroscdkcore.StackProps } func NewdemoStack(scope alicloudroscdkcore.Construct, id string, props *demoStackProps) alicloudroscdkcore.Stack { var sprops alicloudroscdkcore.StackProps if props != nil { sprops = props.StackProps } stack := alicloudroscdkcore.NewStack(scope, &id, &sprops) // The code that defines your stack goes here vpcKey := "Vpc" vpcProps := alicloudroscdkecs.VPCProps{CidrBlock: "10.0.0.0/8", Description: "Test update vpc name by ros cdk."} alicloudroscdkecs.NewVpc(stack, &vpcKey, &vpcProps, nil) return stack } func main() { app := alicloudroscdkcore.NewApp(nil) props := &demoStackProps{} NewdemoStack(app, "demoStack", props) app.Synth(nil) }Run the following command again to update the stack:
ros-cdk deploy --region cn-hangzhouCommand output:
✅ The deployment(update stack) has completed! StackId: 701ecf04-d758-457f-a0fc-7e00e2b6****
Step 10: Delete the stack
Run the following command to delete the stack:
ros-cdk destroyFollow on-screen instructions to confirm the deletion operation.
The following stack(s) will be destroyed(Only deployed stacks will be displayed). DemoStack Please confirm.(Y/N) YCommand output:
✅ Deleted RequestedId: 1BF864E1-7965-4148-A302-E6ABFF80****
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, go to the Ros Cdk References page.
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 licenses and release notes.