This topic describes how to use Cloud Development Toolkit (CDK) of Resource Orchestration Service (ROS) to deploy the NGINX service. In this example, ROS CDK for TypeScript is used.
Step 1: Initialize a project
Run the following commands to create a project directory and initialize the project:
mkdir demo
cd demo
ros-cdk init --language=typescript --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.
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
You can modify the
package.jsonfile to add the ros-cdk-ecs dependency package.{ "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", "@alicloud/ros-cdk-ros": "1.4.0" } }Run the following command to install the dependencies:
npm install
Step 4: Manage a stack
You can modify the
lib/demo-stack.tsfile to create an ECS instance and install the NGINX service.The following section provides examples of multiple programming languages for your reference.
TypeScript example
import * as ros from '@alicloud/ros-cdk-core'; import * as ecs from '@alicloud/ros-cdk-ecs'; import * as ROS from '@alicloud/ros-cdk-ros'; 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 nginxDefaultPort = new ros.RosParameter(this, 'NginxDefaultPort', { type: ros.RosParameterType.STRING, }); const ecsInstanceType = new ros.RosParameter(this, 'EcsInstanceType', { type: ros.RosParameterType.STRING, }); const systemDiskCategory = new ros.RosParameter(this, 'SystemDiskCategory', { type: ros.RosParameterType.STRING, }); const vpc = new ecs.Vpc(this, 'vpc-from-ros-cdk', { vpcName: 'test-ros-cdk-vpc', cidrBlock: '10.0.0.0/8', description: 'This is ros cdk test' }); const vsw = new ecs.VSwitch(this, `vsw-from-ros-cdk`, { vpcId: vpc.attrVpcId, // zoneId: ros.Fn.select(0, ros.Fn.getAzs(ros.Fn.ref('ALIYUN::Region'))), zoneId: 'cn-beijing-h', vSwitchName: 'test-ros-cdk-vsw', cidrBlock: '10.0.0.0/16', }); const sg = new ecs.SecurityGroup(this, 'ros-cdk-test-sg',{ vpcId: vpc.attrVpcId, securityGroupName: 'test-ros-cdk-sg', securityGroupIngress: [{'portRange':'22/22','nicType':'intranet','ipProtocol':'tcp','sourceCidrIp':'0.0.0.0/0'}, {'portRange':'80/80','nicType':'intranet','ipProtocol':'tcp','sourceCidrIp':'0.0.0.0/0'}] }); const ecsWaitConditionHandle = new ROS.WaitConditionHandle(this,'RosWaitConditionHandle',{ count: 1 }) const ecsWaitCondition = new ROS.WaitCondition(this,'RosWaitCondition',{ timeout: 300, handle: ros.Fn.ref('RosWaitConditionHandle'), count: 1 }) let NginxDefaultPort = nginxDefaultPort.valueAsString const ecsGroups = new ecs.InstanceGroup(this,'ros-cdk-test-ecs',{ vpcId: vpc.attrVpcId, vSwitchId: vsw.attrVSwitchId, imageId: 'centos_7', maxAmount: 1, securityGroupId: sg.attrSecurityGroupId, instanceType: ecsInstanceType.valueAsString, systemDiskCategory: systemDiskCategory.valueAsString, instanceName: 'test-ros-cdk-ecs', userData: ros.Fn.replace({ NOTIFY: ecsWaitConditionHandle.attrCurlCli }, `#!/bin/bash\nyum install -y nginx\nsed -i \'s/listen 80;/listen ${NginxDefaultPort};/\' /etc/nginx/nginx.conf \nsystemctl restart nginx\n NOTIFY`), }); } }Java example
package com.myorg; import com.aliyun.ros.cdk.core.*; import com.aliyun.ros.cdk.ecs.*; import com.aliyun.ros.cdk.ros.WaitConditionHandle; import com.aliyun.ros.cdk.ros.WaitCondition; import java.util.Arrays; import java.util.Map; import java.util.HashMap; 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<Object> list1 = Arrays.asList(); Map<String, String> Port22 = new HashMap<>(); Map<String, String> Port80 = new HashMap<>(); Map<String, Object> NOTIFY = new HashMap<>(); Port22.put("PortRange", "22/22"); Port22.put("SourceCidrIp", "0.0.0.0/0"); Port22.put("IpProtocol", "tcp"); Port22.put("NicType", "intranet"); Port80.put("NicType", "intranet"); Port80.put("SourceCidrIp", "0.0.0.0/0"); Port80.put("IpProtocol", "tcp"); Port80.put("PortRange", "80/80"); list1.add(Port22); list1.add(Port80); RosParameter NginxDefaultPort = RosParameter.Builder.create(this, "NginxDefaultPort").type(RosParameterType.STRING).build(); RosParameter EcsInstanceType = RosParameter.Builder.create(this, "EcsInstanceType").type(RosParameterType.STRING).build(); RosParameter SystemDiskCategory = RosParameter.Builder.create(this, "SystemDiskCategory").type(RosParameterType.STRING).build(); String str1 = "#!/bin/bash\\nyum install -y nginx\\nsed -i \\'s/listen 80;/listen "; String nginx_default_port = NginxDefaultPort.getValueAsString(); String str2 = ";/\\' /etc/nginx/nginx.conf \\nsystemctl restart nginx\\n NOTIFY"; String user_data_str = str1 + nginx_default_port + str2; Vpc vpc = Vpc.Builder.create(this, "vpc-from-ros-cdk").vpcName("test-ros-cdk-vpc"). cidrBlock("10.0.0.0/8").description("This is ros cdk test").build(); VSwitch vswitch = VSwitch.Builder.create(this, "vsw-from-ros-cdk").vpcId(vpc.getAttrVpcId()). cidrBlock("10.0.0.0/16").vSwitchName("test-ros-cdk-vsw").zoneId("cn-beijing-h").build(); SecurityGroup sg = SecurityGroup.Builder.create(this, "ros-cdk-test-sg").vpcId(vpc.getAttrVpcId()) .securityGroupIngress(list1).securityGroupName("test-ros-cdk-sg").build(); WaitConditionHandle waitConditionHandle = WaitConditionHandle.Builder.create(this, "RosWaitConditionHandle").count(1).build(); WaitCondition waitCondition = WaitCondition.Builder.create(this, "RosWaitCondition"). count(1).handle(Fn.ref("RosWaitConditionHandle")).timeout(300).build(); NOTIFY.put("NOTIFY", waitConditionHandle.getAttrCurlCli()); InstanceGroup.Builder.create(this, "ros-cdk-test-ecs").vpcId(vpc.getAttrVpcId()). vSwitchId(vswitch.getAttrVSwitchId()).maxAmount(1).securityGroupId(sg.getAttrSecurityGroupId()). instanceType(EcsInstanceType.getValueAsString()).userData(Fn.replace(NOTIFY, user_data_str)). instanceName("test-ros-cdk-ecs").imageId("centos_7").systemDiskCategory(SystemDiskCategory.getValueAsString()).build(); } }Python example
import ros_cdk_core as core import ros_cdk_ecs as ecs import ros_cdk_ros as ros 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 nginx_default_port = core.RosParameter(self, "NginxDefaultPort", type=core.RosParameterType.STRING) ecs_instance_type = core.RosParameter(self, "EcsInstanceType", type=core.RosParameterType.STRING) system_disk_category = core.RosParameter(self, "SystemDiskCategory", type=core.RosParameterType.STRING) vpc = ecs.Vpc(self, "vpc-from-ros-cdk", ecs.VPCProps( cidr_block="10.0.0.0/8", vpc_name="vpc-from-ros-cdk", description="This is ros cdk test" )) vswitch = ecs.VSwitch(self, "vsw-from-ros-cdk", ecs.VSwitchProps( cidr_block="10.0.0.0/16", zone_id="cn-beijing-h", vpc_id=vpc.attr_vpc_id, v_switch_name="test-ros-cdk-vsw" )) sg = ecs.SecurityGroup(self, "ros-cdk-test-sg", ecs.SecurityGroupProps( vpc_id=vpc.attr_vpc_id, security_group_name="test-ros-cdk-sg", security_group_ingress=[ {'portRange': '22/22', 'nicType': 'intranet', 'ipProtocol': 'tcp', 'sourceCidrIp': '0.0.0.0/0'}, {'portRange': '80/80', 'nicType': 'intranet', 'ipProtocol': 'tcp', 'sourceCidrIp': '0.0.0.0/0'}] )) wait_condition_handle = ros.WaitConditionHandle(self, "RosWaitConditionHandle", ros.WaitConditionHandleProps( count=1 )) wait_condition = ros.WaitCondition(self, "RosWaitCondition", ros.WaitConditionProps( timeout=300, count=1, handle=core.Fn.ref("RosWaitConditionHandle") )) ecs.InstanceGroup(self, "ros-cdk-test-ecs", ecs.InstanceGroupProps( vpc_id=vpc.attr_vpc_id, v_switch_id=vswitch.attr_v_switch_id, security_group_id=sg.attr_security_group_id, max_amount=1, instance_type=ecs_instance_type.value_as_string, instance_name="test-ros-cdk-ecs", system_disk_category=system_disk_category.value_as_string, image_id="centos_7", user_data=core.Fn.replace({"NOTIFY": wait_condition_handle.attr_curl_cli}, "#!/bin/bash\nyum install -y nginx\nsed -i \'s/listen 80;/listen " + nginx_default_port.value_as_string + ";/\' /etc/nginx/nginx.conf \nsystemctl restart nginx\n NOTIFY") ))C# example
using System.Collections.Generic; using AlibabaCloud.SDK.ROS.CDK.Core; using AlibabaCloud.SDK.ROS.CDK.Ecs; using AlibabaCloud.SDK.ROS.CDK.Ros; using IStackProps = AlibabaCloud.SDK.ROS.CDK.Core.IStackProps; using Stack = AlibabaCloud.SDK.ROS.CDK.Core.Stack; 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 IDictionary<string, object> notifyObj = new Dictionary<string, object>(); Dictionary<string, string> port22Obj = new Dictionary<string, string>(); Dictionary<string, string> port80Obj = new Dictionary<string, string>(); port22Obj.Add("PortRange", "22/22"); port22Obj.Add("SourceCidrIp", "0.0.0.0/0"); port22Obj.Add("IpProtocol", "tcp"); port22Obj.Add("NicType", "intranet"); port80Obj.Add("PortRange", "80/80"); port80Obj.Add("SourceCidrIp", "0.0.0.0/0"); port80Obj.Add("IpProtocol", "tcp"); port80Obj.Add("NicType", "intranet"); object[] RegionArray = new object[2] {port22Obj, port80Obj}; var NginxDefaultPort = new RosParameter(this, "NginxDefaultPort", new RosParameterProps { Type = RosParameterType.STRING, }); var EcsInstanceType = new RosParameter(this, "EcsInstanceType", new RosParameterProps { Type = RosParameterType.STRING }); var SystemDiskCategory = new RosParameter(this, "SystemDiskCategory", new RosParameterProps { Type = RosParameterType.STRING }); var Vpc = new Vpc(this, "vpc-from-ros-cdk", new VPCProps { CidrBlock = "10.0.0.0/8", VpcName = "test-ros-cdk-vpc", Description = "This is ros cdk test" }); var VSwitch = new VSwitch(this, "vsw-from-ros-cdk", new VSwitchProps { CidrBlock = "10.0.0.0/16", ZoneId = "cn-beijing-h", VpcId = Vpc.AttrVpcId, VSwitchName = "test-ros-cdk-vsw" }); var sg = new SecurityGroup(this, "ros-cdk-test-sg", new SecurityGroupProps { VpcId = Vpc.AttrVpcId, SecurityGroupName = "test-ros-cdk-sg", SecurityGroupIngress = RegionArray, }); var wait_condition_handle = new WaitConditionHandle(this, "RosWaitConditionHandle", new WaitConditionHandleProps { Count = 1 }); var wait_condition = new WaitCondition(this, "RosWaitCondition", new WaitConditionProps { Timeout = 300, Count = 1, Handle = Fn.Ref("RosWaitConditionHandle") }); string str1 = "#!/bin/bash\nyum install -y nginx\nsed -i \'s/listen 80;/listen "; string str2 = ";/\' /etc/nginx/nginx.conf \nsystemctl restart nginx\n NOTIFY"; string str3 = NginxDefaultPort.ValueAsString; string result = str1+str3+ str2; notifyObj.Add("NOTIFY", wait_condition_handle.AttrCurlCli); var ecs = new InstanceGroup(this, "ros-cdk-test-ecs", new InstanceGroupProps { VpcId = Vpc.AttrVpcId, VSwitchId = VSwitch.AttrVSwitchId, SecurityGroupId = sg.AttrSecurityGroupId, MaxAmount = 1, InstanceType = EcsInstanceType.ValueAsString, InstanceName = "test-ros-cdk-ecs", ImageId = "centos_7", SystemDiskCategory = SystemDiskCategory.ValueAsString, UserData = Fn.Replace(notifyObj, result) }); } } }Run the following command to generate a template file:
ros-cdk synth --jsonCommand output:
{ "Description": "This is the simple ros cdk app example.", "Metadata": { "ALIYUN::ROS::Interface": { "TemplateTags": [ "Create by ROS CDK" ] } }, "ROSTemplateFormatVersion": "2015-09-01", "Parameters": { "NginxDefaultPort": { "Type": "String" }, "EcsInstanceType": { "Type": "String" }, "SystemDiskCategory": { "Type": "String" } }, "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-vpc" } }, "vsw-from-ros-cdk": { "Type": "ALIYUN::ECS::VSwitch", "Properties": { "CidrBlock": "10.0.0.0/16", "VpcId": { "Fn::GetAtt": [ "vpc-from-ros-cdk", "VpcId" ] }, "ZoneId": "cn-beijing-h", "VSwitchName": "test-ros-cdk-vsw" } }, "ros-cdk-test-sg": { "Type": "ALIYUN::ECS::SecurityGroup", "Properties": { "SecurityGroupIngress": [ { "PortRange": "22/22", "SourceCidrIp": "0.0.0.0/0", "IpProtocol": "tcp", "NicType": "intranet" }, { "PortRange": "80/80", "SourceCidrIp": "0.0.0.0/0", "IpProtocol": "tcp", "NicType": "intranet" } ], "SecurityGroupName": "test-ros-cdk-sg", "VpcId": { "Fn::GetAtt": [ "vpc-from-ros-cdk", "VpcId" ] } } }, "RosWaitConditionHandle": { "Type": "ALIYUN::ROS::WaitConditionHandle", "Properties": { "Count": 1, "Mode": "Full" } }, "RosWaitCondition": { "Type": "ALIYUN::ROS::WaitCondition", "Properties": { "Handle": { "Ref": "RosWaitConditionHandle" }, "Timeout": 300, "Count": 1 } }, "ros-cdk-test-ecs": { "Type": "ALIYUN::ECS::InstanceGroup", "Properties": { "ImageId": "centos_7", "InstanceType": { "Ref": "EcsInstanceType" }, "MaxAmount": 1, "AllocatePublicIP": true, "AutoRenew": "False", "AutoRenewPeriod": 1, "InstanceChargeType": "PostPaid", "InstanceName": "test-ros-cdk-ecs", "InternetChargeType": "PayByTraffic", "InternetMaxBandwidthIn": 200, "InternetMaxBandwidthOut": 1, "IoOptimized": "optimized", "Period": 1, "PeriodUnit": "Month", "SecurityGroupId": { "Fn::GetAtt": [ "ros-cdk-test-sg", "SecurityGroupId" ] }, "SystemDiskCategory": { "Ref": "SystemDiskCategory" }, "UserData": { "Fn::Replace": [ { "NOTIFY": { "Fn::GetAtt": [ "RosWaitConditionHandle", "CurlCli" ] } }, { "Fn::Join": [ "", [ "#!/bin/bash\nyum install -y nginx\nsed -i 's/listen 80;/listen ", { "Ref": "NginxDefaultPort" }, ";/' /etc/nginx/nginx.conf \nsystemctl restart nginx\n NOTIFY" ] ] } ] }, "VpcId": { "Fn::GetAtt": [ "vpc-from-ros-cdk", "VpcId" ] }, "VSwitchId": { "Fn::GetAtt": [ "vsw-from-ros-cdk", "VSwitchId" ] } } } } }Run the following command to create a stack:
ros-cdk deploy --parameters EcsInstanceType=ecs.c6e.large --parameters NginxDefaultPort=8080 --parameters SystemDiskCategory=cloud_essd --sync=trueCommand output:
DemoStack: deploying... |DemoStack |2021-12-28T09:08:38 | CREATE_COMPLETE | ALIYUN::ECS::SecurityGroup | sg-2ze515oc21n45wgs**** | ros-cdk-test-sg |DemoStack |2021-12-28T09:08:38 | CREATE_COMPLETE | ALIYUN::ECS::VSwitch | vsw-2zeuuwgla2qqrw89**** | vsw-from-ros-cdk |DemoStack |2021-12-28T09:08:38 | CREATE_COMPLETE | ALIYUN::ROS::WaitConditionHandle | | RosWaitConditionHandle |DemoStack |2021-12-28T09:08:38 | CREATE_COMPLETE | ALIYUN::ECS::VPC | vpc-2zedbloxtm5jetdg**** | vpc-from-ros-cdk |DemoStack |2021-12-28T09:08:38 | CREATE_COMPLETE | ALIYUN::ECS::InstanceGroup | i-2ze6yjdmete88**** | ros-cdk-test-ecs |DemoStack |2021-12-28T09:08:38 | CREATE_COMPLETE | ALIYUN::ROS::WaitCondition | | RosWaitCondition ✅ The deployment(sync deploy stack) has finished! status: CREATE_COMPLETE StatusReason: Stack CREATE completed successfully StackId: f7ddd89b-914a-44a4-aac9-80derdg****(Optional) Delete the stack.
Run the following command:
ros-cdk destroy --sync=trueFollow 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:
DemoStack: destroying... |DemoStack | DELETE_COMPLETE | ALIYUN::ECS::SecurityGroup | | ros-cdk-test-sg |DemoStack | DELETE_COMPLETE | ALIYUN::ECS::VSwitch | | vsw-from-ros-cdk |DemoStack | DELETE_COMPLETE | ALIYUN::ROS::WaitConditionHandle | | RosWaitConditionHandle |DemoStack | DELETE_COMPLETE | ALIYUN::ECS::VPC | | vpc-from-ros-cdk |DemoStack | DELETE_COMPLETE | ALIYUN::ECS::InstanceGroup | | ros-cdk-test-ecs |DemoStack | DELETE_COMPLETE | ALIYUN::ROS::WaitCondition | | RosWaitCondition ✅ The task(sync destroy stack) has finished! status: DELETE_COMPLETE StatusReason: Stack DELETE completed successfully StackId: f7ddd89b-914a-44a4-aac9-80derdg****
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.