ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: 创建ECS实例部署Nginx，配置安全组、公网访问和自定义脚本安装ChatGLM应用，支持付费类型选择和资源时长设置。
  en: Create an ECS instance to deploy Nginx, configure security groups for public
    network access, and customize script installation for the ChatGLM application,
    supporting selection of payment options and resource duration settings.
Parameters:
  PayType:
    Type: String
    Label:
      en: ECS Instance Charge Type
      zh-cn: 付费类型
    Default: PostPaid
    AllowedValues:
      - PostPaid
      - PrePaid
    AssociationProperty: ChargeType
    AssociationPropertyMetadata:
      LocaleKey: InstanceChargeType
  PayPeriodUnit:
    Type: String
    Label:
      en: Pay Period Unit
      zh-cn: 购买资源时长周期
    Default: Month
    AllowedValues:
      - Month
      - Year
    AssociationProperty: PayPeriodUnit
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid
  PayPeriod:
    Type: Number
    Label:
      en: Period
      zh-cn: 购买资源时长
    Default: 1
    AllowedValues:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
      - 7
      - 8
      - 9
    AssociationProperty: PayPeriod
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Not:
            Fn::Equals:
              - ${PayType}
              - PostPaid
  ZoneId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::ZoneId
    Label:
      en: VSwitch Availability Zone
      zh-cn: 交换机可用区
  # 新建ack所在的vpc的网段
  VpcCidrBlock:
    Type: String
    Label:
      en: VPC CIDR IPv4 Block
      zh-cn: 专有网络IPv4网段
    Description:
      zh-cn: VPC的ip地址段范围，<br>您可以使用以下的ip地址段或其子网:<br><font color='green'>[10.0.0.0/8]</font><br><font color='green'>[172.16.0.0/12]</font><br><font color='green'>[192.168.0.0/16]</font>
      en: 'The ip address range of the VPC in the CidrBlock form; <br>You can use the following ip address ranges and their subnets: <br><font color=''green''>[10.0.0.0/8]</font><br><font color=''green''>[172.16.0.0/12]</font><br><font color=''green''>[192.168.0.0/16]</font>'
    Default: 192.168.0.0/16
    AssociationProperty: ALIYUN::VPC::VPC::CidrBlock
  # 新建ack所在的交换机的网段
  VSwitchCidrBlock:
    Type: String
    Label:
      en: VSwitch CIDR Block
      zh-cn: 交换机子网网段
    Description:
      zh-cn: 必须属于VPC的子网段。
      en: Must belong to the subnet segment of VPC.
    Default: 192.168.1.0/24
    AssociationProperty: ALIYUN::VPC::VSwitch::CidrBlock
    AssociationPropertyMetadata:
      VpcCidrBlock: VpcCidrBlock
  EcsInstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例类型
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      InstanceChargeType: ${InstanceChargeType}
    AllowedValues:
      - ecs.gn7e-c16g1.4xlarge
      - ecs.gn7e-c16g1.16xlarge
      - ecs.gn7e-c16g1.32xlarge
      - ecs.gn7i-c8g1.2xlarge
      - ecs.gn7i-c16g1.4xlarge
      - ecs.gn7i-c32g1.8xlarge
      - ecs.gn6v-c8g1.2xlarge
      - ecs.gn6v-c8g1.8xlarge
      - ecs.gn6v-c8g1.16xlarge
      - ecs.gn6v-c10g1.20xlarge
      - ecs.gn6i-c4g1.xlarge
      - ecs.gn6i-c8g1.2xlarge
      - ecs.gn6i-c16g1.4xlarge
      - ecs.gn6i-c24g1.6xlarge
      - ecs.gn6i-c40g1.10xlarge
      - ecs.gn6i-c24g1.12xlarge
      - ecs.gn6i-c24g1.24xlarge
  InstancePassword:
    NoEcho: true
    Type: String
    Description:
      en: Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: 服务器登录密码,长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号）
    AllowedPattern: '^[a-zA-Z0-9-\(\)\`\~\!\@\#\$\%\^\&\*\_\-\+\=\|\{\}\[\]\:\;\<\>\,\.\?\/]*$'
    Label:
      en: Instance Password
      zh-cn: 实例密码
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: 长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号）
    MinLength: 8
    MaxLength: 30
    AssociationProperty: ALIYUN::ECS::Instance::Password
  UserName:
    Type: String
    Label:
      en: User Name
      zh-cn: 软件登录名
    Default: admin
  Password:
    NoEcho: true
    Type: String
    Description:
      en: Software login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: 软件登录密码
    AllowedPattern: '^[a-zA-Z0-9-\(\)\`\~\!\@\#\$\%\^\&\*\_\-\+\=\|\{\}\[\]\:\;\<\>\,\.\?\/]*$'
    Label:
      en: Software Login Password
      zh-cn: 软件登录密码
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: 长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号）
    MinLength: 8
    MaxLength: 30
    AssociationProperty: ALIYUN::ECS::Instance::Password
Resources:
  # 新建vpc
  EcsVpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      VpcName:
        Ref: ALIYUN::StackName
      CidrBlock:
        Ref: VpcCidrBlock
  # 新建vswitch
  EcsVSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      VSwitchName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: EcsVpc
      ZoneId:
        Ref: ZoneId
      CidrBlock:
        Ref: VSwitchCidrBlock
  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: EcsVpc
      # 安全组入端口
      SecurityGroupIngress:
        - PortRange: 50000/50000
          Priority: 1
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
          NicType: internet
      # 安全组出端口
      SecurityGroupEgress:
        - PortRange: '-1/-1'
          Priority: 1
          IpProtocol: all
          DestCidrIp: 0.0.0.0/0
          NicType: internet
        - PortRange: '-1/-1'
          Priority: 1
          IpProtocol: all
          DestCidrIp: 0.0.0.0/0
          NicType: intranet
  # 定义waitCondition和waitConditionHandle来等待跳板机命令执行完毕部署成功
  WaitCondition:
    Type: ALIYUN::ROS::WaitCondition
    Properties:
      Count: 1
      Handle:
        Ref: WaitConditionHandle
      Timeout: 3600
  WaitConditionHandle:
    Type: ALIYUN::ROS::WaitConditionHandle
  EcsInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      # 实例名
      InstanceName:
        Fn::Join:
          - '-'
          - - Ref: ALIYUN::StackName
            - '[1,4]'
      IoOptimized: optimized
      # 付费类型
      InstanceChargeType:
        Ref: PayType
      PeriodUnit:
        Ref: PayPeriodUnit
      Period:
        Ref: PayPeriod
      # 网络配置
      VpcId:
        Ref: EcsVpc
      ZoneId:
        Ref: ZoneId
      VSwitchId:
        Ref: EcsVSwitch
      SecurityGroupId:
        Ref: EcsSecurityGroup
      # 磁盘类型和大小
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 500
      MaxAmount: 1
      # 镜像
      ImageId: centos_7
      # 实例类型
      InstanceType:
        Ref: EcsInstanceType
      Password:
        Ref: InstancePassword
      # 公网开启
      AllocatePublicIP: true
      # 公网带宽
      InternetMaxBandwidthOut: 100
  # 到机器上执行命令
  InstanceRunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      Sync: true
      CommandContent:
        Fn::Sub:
          # 将master的ip输入到/root/conf.txt
          # 可以在后续的步骤中通过conf.txt里的内容完成slave的初始化
          - |
            #!/bin/bash
            cd /root/chatglm
            git-lfs clone https://huggingface.co/THUDM/chatglm-6b
            cd /root/chatglm/ChatGLM-6B
            /workspace/miniconda/bin/streamlit run web_demo2.py --server.port 50001 &
            for ((i=0;i<100;i++))
            do
               curl 127.0.0.1:50001
               if [ "$?" == 0 ]
               then
                 break
               fi
               sleep 1
            done
            htpasswd -bc /etc/nginx/password ${UserName} '${Password}'
            systemctl start nginx
            systemctl status nginx
            systemctl enable nginx
            # 执行成功回调WaitCondition结束waitCondition的等待
            ${CurlCli} -d "{\"Data\" : \"Success\", \"status\" : \"SUCCESS\"}"
          - UserName:
              Ref: UserName
            Password:
              Ref: Password
            # 获取到waitConditionHandle的地址放到 ${CurlCli}变量里
            CurlCli:
              Fn::GetAtt:
                - WaitConditionHandle
                - CurlCli
      Type: RunShellScript
      InstanceIds:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      # 超时时间
      Timeout: '3600'
# 定义输出
Outputs:
  # 将公网ip做为http返回的地址显示在控制台
  Endpoint:
    Description:
      zh-cn: 对外暴露的公网IP地址
      en: Public IP Addresses
    Value:
      Fn::Sub:
        - http://${ServerAddress}:50000
        - ServerAddress:
            Fn::Select:
              - 0
              - Fn::GetAtt:
                 - EcsInstanceGroup
                 - PublicIps
  PrivateEndpoint:
    Description:
      zh-cn: 内网IP地址
      en: Public IP Addresses
    Value:
      Fn::Sub:
        - http://${ServerAddress}:50000
        - ServerAddress:
            Fn::Select:
              - 0
              - Fn::GetAtt:
                  - EcsInstanceGroup
                  - PrivateIps

Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
      - 'acs:integrate:计算巢:ChatGLM'
    # 分组信息
    ParameterGroups:
      - Parameters:
          - PayType
          - PayPeriodUnit
          - PayPeriod
        Label:
          default:
            en: PayType Configuration
            zh-cn: 付费类型配置
      - Parameters:
          - EcsInstanceType
          - InstancePassword
        Label:
          default:
            en: Instance
            zh-cn: ECS实例配置
      - Parameters:
          - UserName
          - Password
        Label:
          default:
            en: Login Information
            zh-cn: 登录信息
      - Parameters:
          - ZoneId
        Label:
          default:
            zh-cn: 可用区配置
            en: Zone Configuration
      - Parameters:
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: 选择网络配置
            en: Choose existing Infrastructure Configuration

