使用ROS CDK部署云端2048小游戏

本文主要介绍如何基于ROS CDK新建一台ECS,在其上部署一个2048小游戏,并在本地浏览器游玩。本教程支持多种编程语言,包括TypeScript、JavaScript、Java、Python、C#和Go。

费用说明

ROS CDK本身不收费,但本方案需要部署ECS实例,会产生相关的资源费用。具体费用信息,请参见按量付费

准备工作

请确保您已经完成以下操作:

  • 安装和配置阿里云CLI、安装ROS CDK。具体操作,请参见安装ROS CDK。请确保您安装的ros-cdk-cli 版本在 1.2.0 以上,可以通过运行 npm list -g 确认。

  • 获取AccessKey信息,用于后续授权。如果没有,请参见创建AccessKey

    重要

    为保证账号安全,建议您创建专用于API访问的RAM用户并创建对应的AccessKey。具体操作,请参见创建RAM用户为RAM用户授权

  • 开发语言环境要求 。

    • TypeScript:Node.js 8.0或更高版本。

    • JavaScript:JSON解析工具包(工具包名称为jq)。

    • Java:JDK 1.8或以上版本、Maven 2.5或以上版本。

    • Python:Python 3.4以上版本。

    • C#:.NET Core 2.0以上版本、Visual Studio 2010 及以上版本。

    • Go:1.16或以上版本。

步骤一:初始化工程

在命令行窗口依次输入以下命令,在当前目录创建初始化工程。

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

步骤二:配置阿里云凭证信息

  1. 在命令行窗口执行以下命令,配置阿里云凭证信息。

    ros-cdk config
  2. 根据界面提示依次输入配置信息。

    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!

    配置内容说明如下:

    参数

    说明

    defaultRegionId

    ROS资源栈部署的地域。默认值为cn-hangzhou。您可以调用DescribeRegionsAPI,获取RegionId参数选择地域。

    image

    endpoint

    ROS服务地址。默认值为https://ros.aliyuncs.com。您可以调用DescribeRegionsAPI,获取地域对应的公网接入地址或VPC接入地址,选择ROS服务地址,并添加 https://

    image

    Authenticate mode

    鉴权方式。本示例的鉴权方式为[1] AK,您需要输入准备工作中获取的AccessKey IDAccessKey Secret。更多鉴权方式,请参见配置凭证

步骤三:安装依赖

在工程中修改配置文件,并安装依赖。

TypeScript

  1. 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.1.0"
      },
      "dependencies": {
        "@alicloud/ros-cdk-core": "^1.1.0",
        "@alicloud/ros-cdk-ecs": "^1.1.0"
      }
    }
  2. 在命令行窗口执行以下命令,安装依赖。

    npm install

JavaScript

  1. 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.1.0"
      },
      "dependencies": {
        "@alicloud/ros-cdk-core": "^1.1.0",
        "@alicloud/ros-cdk-ecs": "^1.1.0",
        "@alicloud/ros-cdk-assert": "^1.1.0"
      }
    }
  2. 在命令行窗口执行以下命令,安装依赖。

    npm install

Java

  1. 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.1.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.1.0</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>ros-cdk-ecs</artifactId>
                <version>1.1.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>
    
  2. 执行以下命令,安装依赖:

    mvn compile

Python

  1. requirements.txt文件内容,全部更改为下面代码。

    ros-cdk-core==1.1.0
    ros-cdk-ecs==1.1.0
  2. 在命令行窗口执行以下命令,安装依赖。

    pip install -r requirements.txt

C#

src/Demo/Demo.csproj文件内容,全部更改为下面代码(请根据您本地dotnet核心包版本修改)。

<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.1.0" />
    <PackageReference Include="AlibabaCloud.SDK.ROS.CDK.Ecs" Version="1.1.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

  1. go.mod文件内容,全部修改为下面代码(请根据您的Go语言版本修改)。

    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
    )
    
  2. 在命令行窗口执行以下命令,安装依赖。

    go get

步骤四:添加资源

为项目添加资源,本示例涉及到的资源有:

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, "Deploy 2048 game through ROS CDK.");

    const zoneId = new ros.RosParameter(this, 'ZoneId', {
      type: ros.RosParameterType.STRING
    });

    const vpc = new ecs.Vpc(this, 'Vpc', {
      cidrBlock: '192.168.0.0/16'
    });

    const sg = new ecs.SecurityGroup(this, 'SecurityGroup', {
      vpcId: vpc.ref
    });

    const vsw = new ecs.VSwitch(this, 'VSwitch', {
      cidrBlock: '192.168.0.0/24',
      zoneId: zoneId,
      vpcId: vpc.ref
    })

    const instance = new ecs.Instance(this, 'Instance', {
      vpcId: vpc.ref,
      vSwitchId: vsw.ref,
      securityGroupId: sg.ref,
      zoneId: zoneId,
      instanceType: 'ecs.c6e.large',
      imageId: 'centos_7_8',
      systemDiskCategory: 'cloud_essd',
      ioOptimized: 'optimized'
    });

    const sgIngress = new ecs.SecurityGroupIngress(this, 'SecurityGroupIngress', {
      ipProtocol: 'tcp',
      portRange: '80/80',
      sourceCidrIp: '0.0.0.0/0',
      securityGroupId: sg.ref,
      nicType: 'intranet'
    });

    const runCommand = new ecs.RunCommand(this, 'RunCommand', {
      instanceIds: [instance.ref],
      type: 'RunShellScript',
      sync: true,
      timeout: 3600,
      commandContent: `yum install -y httpd wget\nsystemctl start httpd\nwget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz\ntar xvf 2048.tgz\nmv 2048/* /var/www/html && rm -rf 2048`
    });
    runCommand.addDependency(sgIngress);

    new ros.RosOutput(this, 'Url', {
      value: `http://${instance.attrPublicIp}:80`
    });
  }
}

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, "Deploy 2048 game through ROS CDK.");
    // The code that defines your stack goes here
    const zoneId = new ros.RosParameter(this, 'ZoneId', {
      type: ros.RosParameterType.STRING
    });

    const vpc = new ecs.Vpc(this, 'Vpc', {
      cidrBlock: '192.168.0.0/16'
    });

    const sg = new ecs.SecurityGroup(this, 'SecurityGroup', {
      vpcId: vpc.ref
    });

    const vsw = new ecs.VSwitch(this, 'VSwitch', {
      cidrBlock: '192.168.0.0/24',
      zoneId: zoneId,
      vpcId: vpc.ref
    })

    const instance = new ecs.Instance(this, 'Instance', {
      vpcId: vpc.ref,
      vSwitchId: vsw.ref,
      securityGroupId: sg.ref,
      zoneId: zoneId,
      instanceType: 'ecs.c6e.large',
      imageId: 'centos_7_8',
      systemDiskCategory: 'cloud_essd',
      ioOptimized: 'optimized'
    });

    const sgIngress = new ecs.SecurityGroupIngress(this, 'SecurityGroupIngress', {
      ipProtocol: 'tcp',
      portRange: '80/80',
      sourceCidrIp: '0.0.0.0/0',
      securityGroupId: sg.ref,
      nicType: 'intranet'
    });

    const runCommand = new ecs.RunCommand(this, 'RunCommand', {
      instanceIds: [instance.ref],
      type: 'RunShellScript',
      sync: true,
      timeout: 3600,
      commandContent: `yum install -y httpd wget\nsystemctl start httpd\nwget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz\ntar xvf 2048.tgz\nmv 2048/* /var/www/html && rm -rf 2048`
    });
    runCommand.addDependency(sgIngress);

    new ros.RosOutput(this, 'Url', {
      value: `http://${instance.attrPublicIp}:80`
    });
  }
}

module.exports = { DemoStack }
重要

请将folderPath变量设置为你的本地文件夹路径,同时,将ossBucketName变量指定为你计划创建的OSS Bucket名称,Bucket 名称必须全局唯一!

Java

  1. src/main/java/com/myorg/DemoStack.java文件内容,全部改为下面代码。

    package com.myorg;
    
    import com.aliyun.ros.cdk.core.*;
    import com.aliyun.ros.cdk.ecs.*;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    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
            RosInfo.setDescription("Deploy 2048 game through ROS CDK.");
            RosParameter zoneId = RosParameter.Builder.create(this, "ZoneId")
                    .type(RosParameterType.STRING)
                    .build();
    
            Vpc vpc = Vpc.Builder.create(this, "Vpc")
                    .cidrBlock("192.168.0.0/16")
                    .build();
    
            SecurityGroup securityGroup = SecurityGroup.Builder.create(this, "SecurityGroup")
                    .vpcId(vpc.getRef())
                    .build();
    
            VSwitch vSwitch = VSwitch.Builder.create(this, "VSwitch")
                    .cidrBlock("192.168.0.0/24")
                    .zoneId(zoneId.getValue())
                    .vpcId(vpc.getRef())
                    .build();
    
            Instance instance = Instance.Builder.create(this, "Instance")
                    .vpcId(vpc.getRef())
                    .vSwitchId(vSwitch.getRef())
                    .securityGroupId(securityGroup.getRef())
                    .zoneId(zoneId.getValue())
                    .instanceType("ecs.c6e.large")
                    .imageId("centos_7_8")
                    .systemDiskCategory("cloud_essd")
                    .ioOptimized("optimized")
                    .build();
    
            SecurityGroupIngress securityGroupIngress = SecurityGroupIngress.Builder.create(this, "SecurityGroupIngress")
                    .ipProtocol("tcp")
                    .portRange("80/80")
                    .sourceCidrIp("0.0.0.0/0")
                    .securityGroupId(securityGroup.getRef())
                    .nicType("intranet")
                    .build();
    
            RunCommand runCommand = RunCommand.Builder.create(this, "RunCommand")
                    .instanceIds(new ArrayList<>(Arrays.asList(instance.getRef())))
                    .type("RunShellScript")
                    .sync(true)
                    .timeout(3600)
                    .commandContent("yum install -y httpd wget\nsystemctl start httpd\nwget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz\ntar xvf 2048.tgz\nmv 2048/* /var/www/html && rm -rf 2048")
                    .build();
            runCommand.addDependency(securityGroupIngress);
    
            RosOutput.Builder.create(this, "Url")
                    .value("http://" + instance.getAttrPublicIp().toString() +":80")
                    .build();
        }
    }
  2. 运行mvn compile以编译CDK项目。

Python

demo/demo_stack.py文件内容,全部改为下面代码。

import ros_cdk_core as core
import ros_cdk_ecs as ecs


class DemoStack(core.Stack):

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

        # The code that defines your stack goes here
        core.RosInfo(self, core.RosInfo.description, "Deploy 2048 game through ROS CDK.")

        zone_id = core.RosParameter(self, "ZoneId", type=core.RosParameterType.STRING)

        vpc = ecs.Vpc(self, "Vpc", ecs.VPCProps(cidr_block="192.168.0.0/16"))

        sg = ecs.SecurityGroup(self, "SecurityGroup", ecs.SecurityGroupProps(vpc_id=vpc.ref))

        vsw = ecs.VSwitch(self, "VSwitch", ecs.VSwitchProps(
            cidr_block='192.168.0.0/24',
            vpc_id=vpc.ref,
            zone_id=zone_id,
        ))

        instance = ecs.Instance(self, "Instance", ecs.InstanceProps(
            vpc_id=vpc.ref,
            instance_type="ecs.c6e.large",
            image_id="centos_7_8",
            security_group_id=sg.ref,
            v_switch_id=vsw.ref,
            zone_id=zone_id,
            system_disk_category="cloud_essd",
            io_optimized="optimized"
        ))

        sg_ingress = ecs.SecurityGroupIngress(self, "SecurityGroupIngress", ecs.SecurityGroupIngressProps(
            security_group_id=sg.ref,
            port_range="80/80",
            ip_protocol="tcp",
            source_cidr_ip="0.0.0.0/0",
            nic_type="intranet"
        ))

        run_command = ecs.RunCommand(self, "RunCommand", ecs.RunCommandProps(
            instance_ids=[instance.ref],
            command_content= "yum install -y httpd wget\nsystemctl start httpd\nwget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz\ntar xvf 2048.tgz\nmv 2048/* /var/www/html && rm -rf 2048",
            type="RunShellScript",
            timeout=3600,
            sync=True
        ))
        run_command.add_dependency(sg_ingress)

        core.RosOutput(self, "Url", value="http://{}:80".format(instance.attr_public_ip.to_string()))

C#

src/Demo/DemoStack.cs文件内容,全部改为下面代码。

using System.Collections.Generic;
using AlibabaCloud.SDK.ROS.CDK.Core;
using AlibabaCloud.SDK.ROS.CDK.Ecs;

namespace Demo
{
    public class DemoStack : Stack
    {
        public DemoStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your stack goes here
            new RosInfo(this, RosInfo.Description, "Deploy 2048 game through ROS CDK.");

            var zoneId = new RosParameter(this, "ZoneId", new RosParameterProps{
                Type = RosParameterType.STRING
            });

            var vpc = new Vpc(this, "Vpc", new VPCProps{
                CidrBlock = "192.168.0.0/16"
            });

            var sg = new SecurityGroup(this, "SecurityGroup", new SecurityGroupProps{
                VpcId = vpc.Ref
            });

            var vsw = new VSwitch(this, "VSwitch", new VSwitchProps{
                CidrBlock = "192.168.0.0/24",
                ZoneId = zoneId.Value,
                VpcId = vpc.Ref
            });

            var instance = new Instance(this, "Instance", new InstanceProps{
                VpcId = vpc.Ref,
                VSwitchId = vsw.Ref,
                SecurityGroupId = sg.Ref,
                ZoneId = zoneId.Value,
                InstanceType = "ecs.c6e.large",
                ImageId = "centos_7_8",
                SystemDiskCategory = "cloud_essd",
                IoOptimized = "optimized"
            });

            var sgIngress = new SecurityGroupIngress(this, "SecurityGroupIngress", new SecurityGroupIngressProps{
                IpProtocol = "tcp",
                PortRange = "80/80",
                SourceCidrIp = "0.0.0.0/0",
                SecurityGroupId = sg.Ref,
                NicType = "intranet"
            });

            var runCommand = new RunCommand(this, "RunCommand", new RunCommandProps{
                InstanceIds = new IResolvable[] { instance.AttrInstanceId },
                CommandContent = "yum install -y httpd wget\nsystemctl start httpd\nwget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz\ntar xvf 2048.tgz\nmv 2048/* /var/www/html && rm -rf 2048",
                Type = "RunShellScript",
                Timeout = 3600,
                Sync = true
            });
            runCommand.AddDependency(sgIngress);

            new RosOutput(this, "Url", new RosOutputProps{
                Value = "http://" + instance.AttrPublicIp.ToString() + ":80"
            });
        }
    }
}

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
	description := "Deploy 2048 game through ROS CDK."
	alicloudroscdkcore.RosInfo_SetDescription(&description)

	zoneIdKey := "ZoneId"
	zoneIdProps := alicloudroscdkcore.RosParameterProps{Type: alicloudroscdkcore.RosParameterType_STRING}
	zoneId := alicloudroscdkcore.NewRosParameter(stack, &zoneIdKey, &zoneIdProps)

	vpcKey := "Vpc"
	vpcProps := alicloudroscdkecs.VPCProps{CidrBlock: "192.168.0.0/16"}
	vpc := alicloudroscdkecs.NewVpc(stack, &vpcKey, &vpcProps, nil)

	sgKey := "SecurityGroup"
	sgProps := alicloudroscdkecs.SecurityGroupProps{VpcId: vpc.Ref()}
	sg := alicloudroscdkecs.NewSecurityGroup(stack, &sgKey, &sgProps, nil)

	vswKey := "VSwitch"
	vswProps := alicloudroscdkecs.VSwitchProps{
		CidrBlock: "192.168.0.0/24",
		ZoneId:    zoneId.Value(),
		VpcId:     vpc.Ref(),
	}
	vsw := alicloudroscdkecs.NewVSwitch(stack, &vswKey, &vswProps, nil)

	instanceKey := "Instance"
	instanceProps := alicloudroscdkecs.InstanceProps{
		VpcId:              vpc.Ref(),
		VSwitchId:          vsw.Ref(),
		SecurityGroupId:    sg.Ref(),
		ZoneId:             zoneId.Value(),
		InstanceType:       "ecs.c6e.large",
		ImageId:            "centos_7_8",
		SystemDiskCategory: "cloud_essd",
		IoOptimized:        "optimized",
	}
	instance := alicloudroscdkecs.NewInstance(stack, &instanceKey, &instanceProps, nil)

	sgIngressKey := "SecurityGroupIngress"
	sgIngressProps := alicloudroscdkecs.SecurityGroupIngressProps{
		IpProtocol:      "tcp",
		PortRange:       "80/80",
		SourceCidrIp:    "0.0.0.0/0",
		SecurityGroupId: sg.Ref(),
		NicType:         "intranet",
	}
	sgIngress := alicloudroscdkecs.NewSecurityGroupIngress(stack, &sgIngressKey, &sgIngressProps, nil)

	var instanceIds []*string
	runCommandKey := "RunCommand"
	runCommandProps := alicloudroscdkecs.RunCommandProps{
		InstanceIds:    append(instanceIds, instance.Ref()),
		Type:           "RunShellScript",
		Sync:           true,
		Timeout:        3600,
		CommandContent: "yum install -y httpd wget\nsystemctl start httpd\nwget 'https://computenest-artifacts-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/1853370294850618/cn-beijing/1697533575326/2048.tgz' -O 2048.tgz\ntar xvf 2048.tgz\nmv 2048/* /var/www/html && rm -rf 2048",
	}
	runCommand := alicloudroscdkecs.NewRunCommand(stack, &runCommandKey, &runCommandProps, nil)
	runCommand.AddDependency(sgIngress)

	urlKey := "Url"
	urlProps := alicloudroscdkcore.RosOutputProps{Value: "http://" + *instance.AttrPublicIp().ToString() + ":80"}
	alicloudroscdkcore.NewRosOutput(stack, &urlKey, &urlProps)

	return stack
}

func main() {
	app := alicloudroscdkcore.NewApp(nil)
	props := &demoStackProps{}

	NewdemoStack(app, "demoStack", props)

	app.Synth(nil)
}

步骤五:创建资源栈

  1. 在命令行窗口运行如下命令,创建资源栈。

    ros-cdk deploy --parameters ZoneId=cn-hangzhou-i --sync=true

    请选择合适的可用区进行部署。命令行终端返回The deployment(sync create stack) has completed!表示创建成功,全部信息如下。

    Create bucket(cdk-tcbgaxxxx-assets-cn-hangzhou) successfully!
    Upload file(./cdk.out/DemoStack.template.json) to bucket(cdk-tcbgaxxxx-assets-cn-hangzhou) successfully!
    DemoStack: deploying...
    |DemoStack               |2024-09-09T08:56:47 | CREATE_COMPLETE      | ALIYUN::ECS::SecurityGroup | sg-bp121z2wd687mdxxxxxx | SecurityGroup
    
    |DemoStack               |2024-09-09T08:56:47 | CREATE_COMPLETE      | ALIYUN::ECS::SecurityGroupIngress | sg-bp121z2wd687mdxxxxxx | SecurityGroupIngress
    
    |DemoStack               |2024-09-09T08:56:47 | CREATE_COMPLETE      | ALIYUN::ECS::Instance   | i-bp16t9mt9b0uscixxxxx | Instance
    
    |DemoStack               |2024-09-09T08:56:47 | CREATE_COMPLETE      | ALIYUN::ECS::VPC        | vpc-bp10y18ke2x6v0bjxxxxx | Vpc
    
    |DemoStack               |2024-09-09T08:56:47 | CREATE_COMPLETE      | ALIYUN::ECS::VSwitch    | vsw-bp1qfb9u90cuyu69xxxxx | VSwitch
    
    |DemoStack               |2024-09-09T08:56:47 | CREATE_COMPLETE      | ALIYUN::ECS::RunCommand | t-hz04w6ckiuxxxxx | RunCommand
    
    
    Outputs:
    
     Key: Url  Value: http://121.40.xxx.xx:80 Description: No description given
    
     ✅ The deployment(sync create stack) has completed!
    Status: CREATE_COMPLETE
    StatusReason: Stack CREATE completed successfully
    StackId: 40c92773-33fb-4249-bd46-3ab6xxxxxxxx
    
  2. 部署完成后,复制Outputs中的链接并在浏览器中打开,即可畅玩2048。

步骤六:删除资源栈

  1. 命令行窗口执行以下命令以删除资源栈。

    ros-cdk destroy --sync=true 

    CDK会二次确认即将删除的资源栈。

    The following stack(s) will be destroyed(Only deployed stacks will be displayed).
    
    DemoStack
    
    Please confirm.(Y/N)
  2. 输入y并回车,删除成功会显示如下信息。

    The task(sync destroy stack) has finished!
    status: DELETE_COMPLETE
    StatusReason: Stack DELETE completed successfully
    StackId: 40c92773-33fb-4249-bd46-3ab6xxxxxxxx