本文以创建阿里云专有网络(VPC)实例及其关联的交换机(vSwitch)实例为例,介绍在不同语言环境下如何使用ROS CDK。
应用场景
如果您想通过熟悉的编程语言完成对应资源的创建和配置,而不是依赖繁琐的JSON和YAML模板语法,您可以选择使用ROS CDK实现自动化部署及运维。更多信息,请参见概览。
支持的语言
TypeScript
JavaScript
Java
Python
C#
Go
前提条件
Java语言请确保JDK和Maven满足以下版本要求:
JDK:8及以上。
Maven:3.6及以上。
Python语言请确保Python版本在3.7及以上。
C#语言请确保本地存在.NET Core3.1版本,并且.NET SDK版本在5.0及以上。
步骤一:初始化工程
每个ROS CDK应用都要求创建在一个独立的工程目录下,且该应用需要使用独立工程目录中模块的依赖项。所以在创建应用之前,需要先创建一个工程目录并进行初始化。
执行以下命令,创建工程目录并初始化工程。
TypeScript
mkdir demo
cd demo
ros-cdk init --language=typescript --generate-only=true
JavaScript
mkdir demo
cd demo
ros-cdk init --language=javascript --generate-only=true
Java
mkdir demo
cd demo
ros-cdk init --language=java --generate-only=true
Python
mkdir demo
cd demo
ros-cdk init --language=python --generate-only=true
执行以下命令,创建一个属于当前工程的虚拟环境。
Python工程的运行依赖于虚拟环境(virtualenv),所以在初始化Python工程之后需要创建一个属于当前工程的虚拟环境。
python3 -m venv .venv
执行以下命令,进入虚拟环境。
source .venv/bin/activate
C#
mkdir demo
cd demo
ros-cdk init --language=csharp --generate-only=true
Go
mkdir demo
cd demo
ros-cdk init --language=go --generate-only=true
步骤二:配置阿里云凭证信息
执行以下命令,配置阿里云凭证信息。
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!
配置内容说明如下:
endpoint:ROS服务地址。默认值为https://ros.aliyuncs.com。
defaultRegionId:ROS资源栈部署的地域。默认值为cn-hangzhou。
Authenticate mode:鉴权方式。本示例的鉴权方式为AccessKey,您需要输入AccessKey ID和AccessKey Secret。关于如何获取AccessKey,请参见交互式配置(快速配置)。
(可选)步骤三:预览工程结构
执行以下命令,预览工程结构。
tree .
执行命令后,输出以下内容:
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 files
工程结构说明如下:
bin/demo.ts
:入口文件。说明一个工程有且仅有一个应用。
示例中创建了一个应用(类型为ros.App)和一个资源栈(类型为DemoStack,名称为DemoStack),并将资源栈添加到应用中。
demo.ts
文件内容如下:#!/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
:资源栈的定义文件。您可以将资源添加到资源栈中,动态构建资源栈。初始化生成的代码中,只为资源栈添加了描述信息。
demo-stack.ts
文件内容如下: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
:单元测试文件。用于验证构建资源栈的逻辑是否符合预期。
demo.test.ts
文件内容如下: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 files
工程结构说明如下:
bin/demo.js
:入口文件。说明一个工程有且仅有一个应用。
示例中创建了一个应用(类型为ros.App)和一个资源栈(类型为DemoStack,名称为DemoStack),并将资源栈添加到应用中。
demo.js
文件内容如下:#!/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
:资源栈的定义文件。您可以将资源添加到资源栈中,动态构建资源栈。初始化生成的代码中,只为资源栈添加了描述信息。
demo-stack.js
文件内容如下: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
:单元测试文件。用于验证构建资源栈的逻辑是否符合预期。
demo.test.js
文件内容如下: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 files
工程结构说明如下:
src/main/java/com/myorg/DemoApp.java
:入口文件。说明一个工程有且仅有一个应用。
示例中创建了一个应用(类型为App)和一个资源栈(类型为DemoStack,名称为DemoStack),并将资源栈添加到应用中。
DemoApp.java
文件内容如下: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
:资源栈的定义文件。您可以将资源添加到资源栈中,动态构建资源栈。初始化生成的代码中,只为资源栈添加了描述信息。
DemoStack.java
文件内容如下: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
:单元测试文件。用于验证构建资源栈的逻辑是否符合预期。
DemoTest.java
文件内容如下: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 files
工程结构说明如下:
app.py
:入口文件。说明一个工程有且仅有一个应用。
示例中创建了一个应用(类型为core.App)和一个资源栈(类型为DemoStack,名称为demo),并将资源栈添加到应用中。
app.py
文件内容如下:#!/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
:资源栈的定义文件。您可以将资源添加到资源栈中,动态构建资源栈。初始化生成的代码中,只为资源栈添加了描述信息。
demo_stack.py
文件内容如下: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 here
test/test_demo.py
:单元测试文件。用于验证构建资源栈的逻辑是否符合预期。
test_demo.py
文件内容如下:#!/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 files
初始化工程之后默认会定义一个应用文件(Program.cs),与一个资源栈文件(DemoStack.cs)。您可以在DemoStack.cs中通过自定义代码的方式动态构建资源栈。资源栈将被默认添加到应用中,每个工程只允许存在一个应用。工程结构说明如下:
src/Demo/DemoStack.cs
:资源栈文件。初始化生成的代码中,只为资源栈添加了描述信息。
DemoStack.cs
文件内容如下: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
:应用文件。您可以将资源栈添加到应用中。
Program.cs
文件内容如下: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
:单元测试文件。用于验证构建资源栈的逻辑是否符合预期。
DemoTest.cs
文件内容如下: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 files
工程结构说明如下:
demo.go
:入口文件,同时也是资源栈的定义文件。说明一个工程有且仅有一个应用。
示例中创建了一个应用(类型为ros.App)和一个资源栈(名称为NewDemoStack),并将资源栈添加到应用中。
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
:单元测试文件。用于验证构建资源栈的逻辑是否符合预期。
demo_test.go
文件内容如下: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) }
步骤四:安装依赖
添加ECS依赖包。
TypeScript
修改
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.0.25" }, "dependencies": { "@alicloud/ros-cdk-core": "^1.0.25", "@alicloud/ros-cdk-ecs": "^1.0.23" } }
JavaScript
修改
package.json
文件。{ "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.0.25" }, "dependencies": { "@alicloud/ros-cdk-core": "^1.0.25", "@alicloud/ros-cdk-ecs": "^1.0.23" } }
Java
修改
pom.xml
文件。<?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.0.25</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.0.25</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>ros-cdk-ecs</artifactId> <version>1.0.23</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
修改
requirements.txt
文件。ros-cdk-core==1.0.25 ros-cdk-ecs==1.0.23
C#
修改
src/Demo/Demo.csproj
文件。<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.0.25" /> <PackageReference Include="AlibabaCloud.SDK.ROS.CDK.Ecs" Version="1.0.23" /> <!-- 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
修改
go.mod
文件。module demo go 1.18 require ( github.com/alibabacloud-go/ros-cdk/alicloudroscdkcore v1.2.0 github.com/alibabacloud-go/ros-cdk/alicloudroscdkecs v1.2.0 github.com/stretchr/testify v1.8.4 )
执行以下命令,安装依赖。
TypeScript
npm install
JavaScript
npm install
Java
mvn compile
Python
方法一:
pip install -r requirements.txt
方法二:
pip install ros-cdk-core ros-cdk-ecs
C#
说明该语言无需命令行安装依赖。
Go
go get
步骤五:添加资源
添加一个VPC和一台vSwitch。
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 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
修改
lib/demo-stack.js
文件。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
修改
DemoStack.java
文件。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
修改
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 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#
修改
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) { 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
将
demo.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"} 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) }
(可选)执行以下命令,生成模板文件。
TypeScript
ros-cdk synth --json
JavaScript
ros-cdk synth --json
Java
mvn compile ros-cdk synth --json
Python
ros-cdk synth --json
C#
ros-cdk synth --json
Go
go get ros-cdk synth --json
执行命令后,输出以下内容:
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" } } } }
(可选)步骤六:单元测试
验证资源栈创建VPC和VSwitch的可行性。
TypeScript
修改
test/demo.test.ts
文件。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
修改
demo.test.js
文件。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
修改
DemoTest.java
文件。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
修改
test_demo.py
文件。#!/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#
修改
DemoTest.cs
文件。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
修改
demo_test.go
文件。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) }
执行以下命令,进行单元测试。
TypeScript
npm test
JavaScript
npm test
Java
mvn test
Python
python -m unittest -v
C#
dotnet test
Go
go get go test
执行命令后,输出以下内容:
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 OK
C#
正在启动测试执行,请稍候... 总共 1 个测试文件与指定模式相匹配。 已通过! - 失败: 0,通过: 1,已跳过: 0,总计: 1,持续时间: 1 s - DemoTest.dll (netcoreapp3.1)
Go
PASS ok demo 0.971s
步骤七:部署资源栈
您可以使用ROS CDK命令,创建、查询或删除资源栈。
执行以下命令,创建资源栈。
ros-cdk deploy --region cn-hangzhou
执行命令后,输出以下内容:
✅ The deployment(create stack) has completed!
StackId: 701ecf04-d758-457f-a0fc-7e00e2b6****
(可选)步骤八:查询资源栈
执行以下命令,查询资源栈。
ros-cdk list-stacks
执行命令后,输出以下内容:
✅ 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****"
}
]
(可选)步骤九:更新资源栈
更新VPC描述,并删除vSwitch资源
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 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
修改
lib/demo-stack.js
文件。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
修改
DemoStack.java
文件。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
修改
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 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#
修改
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) { 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) }
重新执行以下命令,更新资源栈。
ros-cdk deploy --region cn-hangzhou
执行命令后,输出以下内容:
✅ The deployment(update stack) has completed! StackId: 701ecf04-d758-457f-a0fc-7e00e2b6****
步骤十:删除资源栈
执行以下命令,删除资源栈。
ros-cdk destroy
根据界面提示,确认删除。
The following stack(s) will be destroyed(Only deployed stacks will be displayed). DemoStack Please confirm.(Y/N) Y
执行命令后,输出以下内容:
✅ Deleted RequestedId: 1BF864E1-7965-4148-A302-E6ABFF80****