ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: 端到端全链路追踪诊断。
  en: End-to-end full-link tracking and diagnosis.
Parameters:
  ZoneId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::ZoneId
    Label:
      en: VSwitch Availability Zone
      zh-cn: 交换机可用区
  ECSInstanceType:
    Type: String
    Label:
      en: Instance Type
      zh-cn: 实例规格
    Description:
      en: <font color='blue'><b>Before selecting a model, please confirm whether the model is in stock in the current availability zone. To save testing costs, it is recommended to use a model with 2 cores and 4G memory, for example:ecs.c7.large</b></font>.
      zh-cn: <font color='blue'><b>选择机型前请先确认当前可用区下该机型是否有库存，为节省测试成本，推荐使用2核4G内存的规格，例如：ecs.c7.large</b></font>。
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      Constraints:
        Memory:
          - 4
          - 6
          - 8
          - 10
          - 12
          - 14
          - 16
          - 18
          - 20
          - 22
          - 24
          - 26
          - 28
          - 30
          - 32
      ZoneId: ZoneId
  ECSPassword:
    Type: String
    Label:
      en: root account password
      zh-cn: root 账号密码
    Description:
      en: Server root account login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 服务器root账号登录密码,长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号）。
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
      zh-cn: 长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号）。
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    MinLength: 8
    MaxLength: 30
    NoEcho: true
  DBInstanceClass:
    Type: String
    Label:
      en: RDS Instance Class
      zh-cn: RDS实例规格
    AssociationProperty: ALIYUN::RDS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId:
        Ref: ZoneId
      EngineVersion: '8.0'
      DBInstanceStorageType: cloud_essd
      Engine: MySQL
      Category: Basic
      CommodityCode: bards
    Default: mysql.n2m.medium.2c
  DBAccountName:
    Type: String
    ConstraintDescription:
      en: >-
        Consist of 2 to 32 characters of lowercase letters, underline. 
        Must begin with a letter and be end with an alphanumeric character
      zh-cn: >-
        由 2 到 32 个小写字母组成，支持小写字母、数字和下划线，以小写字母开头。
    Label:
      zh-cn: RDS数据库账号
      en: RDS DB Username
    Default: db_normal_account
    AllowedPattern: '^[a-z][a-z0-9_]{0,31}$'
  DBPassword:
    NoEcho: true
    Type: String
    Description:
      en: >-
        RDS user password, Length 8-30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special
        symbol in)
      zh-cn: >-
        数据库账号密码，长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
        中的特殊符号）
    Label:
      en: RDS Instance Password
      zh-cn: RDS数据库密码
    ConstraintDescription:
      en: >-
        Length 8-30, must contain three(Capital letters, lowercase letters,
        numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: '长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;''<>,.?/ 中的特殊符号）'
    AssociationProperty: ALIYUN::RDS::Instance::AccountPassword
  RedisClass:
    Type: String
    Label:
      en: Tair Specifications
      zh-cn: Tair 规格
    Description:
      en: <font color='blue'><b>Before selecting a model, please confirm whether the model is in stock in the current availability zone. To save testing costs, it is recommended to use a model with 1G memory, for example:redis.shard.small.2.ce</b></font>, see detail:<a href='https://help.aliyun.com/zh/redis/product-overview/cost-efficient-instances' target='_blank'><b><font color='red'>Specification inquiry</font></b></a>.
      zh-cn: <font color='blue'><b>选择机型前请先确认当前可用区下该机型是否有库存，为节省测试成本，推荐使用1GB的规格，例如：redis.shard.small.2.ce</b></font>，<a href='https://help.aliyun.com/zh/redis/product-overview/cost-efficient-instances' target='_blank'><b><font color='red'>规格查询</font></b></a>。
    AssociationProperty: ALIYUN::REDIS::Instance::InstanceClass
    AssociationPropertyMetadata:
      Engine: Redis
      ProductType: OnECS
      InstanceChargeType: PostPaid
      ZoneId: ${ZoneId}
      OrderType: BUY
    Default: redis.shard.small.2.ce
  RedisAccountPassword:
    NoEcho: true
    Type: String
    Description:
      en: RDS user password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: 数据库账号密码，长度8-30，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号）
    Label:
      en: Tair Instance Password
      zh-cn: Tair 数据库密码
    ConstraintDescription:
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
      zh-cn: 必须包含三种及以上类型：大写字母、小写字母、数字、特殊符号。长度为8～32位。特殊字符包括!@#$%^&*()_+-=
    AssociationProperty: ALIYUN::RDS::Instance::AccountPassword
  MseLicenseKey:
    Type: String
    Label:
      en: Current MSE region License Key
      zh-cn: 当前环境 MSE License Key
    Description:
      en: Log on <a href="https://mse.console.aliyun.com/#/msc/home" target="_blank"><b><font color='blue'>MSE console </font></a>, Click Governance Center > Overview in the left navigation bar. On the top menu bar, select the region where the ROS resource stack is created. Click the License Key link in the upper right corner of the overview page to obtain the MSE License Key.
      zh-cn: 登录<a href='https://mse.console.aliyun.com/#/msc/home' target='_blank'><b><font color='blue'>微服务引擎MSE控制台</font></a>，点击左侧导航栏治理中心 > 概览，在顶部菜单栏，选择创建ROS资源栈对应的地域, 在概览页面点击右上角查看 License Key 链接，获取MSE License Key。
  ArmsLicenseKey:
    Type: String
    Label:
      en: Current ARMS region License Key
      zh-cn: 当前环境 ARMS License Key
    Description:
      en: Log on <a href="https://arms.console.aliyun.com/?spm=5176.mse-prod.console-base_search-panel.dtab-product_arms.719f142feXioLD#/intgr/integrations?showIntgrDetail=true&intgrId=apm-java&name=Java+%E5%BA%94%E7%94%A8%E7%9B%91%E6%8E%A7&pageType=console&tab=startIntgr&version=0.0.1" target="_blank"><b><font color='blue'>ARMS console </font></a>, In the Access Center page of the ARMS management console of the real-time application monitoring service, select Server Application > Java Application Monitoring. In the Java Application Monitoring page, select the environment type and set it to Manual Installation. In the Agent Installation step, obtain the value of the variable -Darms.licenseKey.
      zh-cn: 登录<a href='https://arms.console.aliyun.com/?spm=5176.mse-prod.console-base_search-panel.dtab-product_arms.719f142feXioLD#/intgr/integrations?showIntgrDetail=true&intgrId=apm-java&name=Java+%E5%BA%94%E7%94%A8%E7%9B%91%E6%8E%A7&pageType=console&tab=startIntgr&version=0.0.1' target='_blank'><b><font color='blue'>ARMS控制台</font></a>，在应用实时监控服务 ARMS 管理控制台接入中心页面选择服务端应用 > Java 应用监控，在Java 应用监控页面开始接入页签中选择所属环境类型设置为手动安装，在安装 Agent步骤中获取变量-Darms.licenseKey对应的值。
Resources:
  VPC:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
      VpcName:
        Fn::Sub: VPC-${ALIYUN::StackId}
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VSwitchName:
        Fn::Sub: vsw_001-${ALIYUN::StackId}
      VpcId:
        Ref: VPC
      CidrBlock: 192.168.1.0/24
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: VPC
      SecurityGroupName:
        Fn::Sub: SecurityGroup_1-${ALIYUN::StackId}
      SecurityGroupIngress:
        - PortRange: 80/80
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
  ECSInstanceGroup:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: VPC
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: aliyun_3_9_x64_20G_alibase_
      InstanceType:
        Ref: ECSInstanceType
      IoOptimized: optimized
      MaxAmount: 1
      Password:
        Ref: ECSPassword
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 40
      InternetMaxBandwidthOut: 5
  RdsInstance:
    Type: 'ALIYUN::RDS::DBInstance'
    Properties:
      DBInstanceClass:
        Ref: DBInstanceClass
      ZoneId:
        Ref: ZoneId
      DBInstanceStorage: 50
      Category: Basic
      DBInstanceStorageType: cloud_essd
      VSwitchId:
        Ref: VSwitch
      Engine: MySQL
      VpcId:
        Ref: VPC
      EngineVersion: '8.0'
      SecurityIPList: '192.168.0.0/16'
  RdsAccount:
    DependsOn:
      - RdsInstance
    Type: ALIYUN::RDS::Account
    Properties:
      DBInstanceId:
        Ref: RdsInstance
      AccountPassword:
        Ref: DBPassword
      AccountType: Normal
      AccountName:
        Ref: DBAccountName
  RdsDatabase:
    Type: ALIYUN::RDS::Database
    Properties:
      CharacterSetName: utf8mb4
      DBInstanceId:
        Ref: RdsInstance
      DBName: flashsale
  AccountPrivilege:
    DependsOn:
      - RdsDatabase
      - RdsAccount
    Type: ALIYUN::RDS::AccountPrivilege
    Properties:
      AccountPrivilege: ReadWrite
      DBInstanceId:
        Ref: RdsInstance
      DBName: flashsale
      AccountName:
        Ref: DBAccountName
  RedisInstance:
    Type: ALIYUN::REDIS::Instance
    Properties:
      EngineVersion: '5.0'
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: VPC
      VSwitchId:
        Ref: VSwitch
      InstanceClass:
        Ref: RedisClass
      InstanceName:
        Fn::Sub: flashsale_redis-${ALIYUN::StackId}
      Password:
        Ref: RedisAccountPassword
      ProductType: OnECS
      DeletionForce: true
      ShardCount: 1
      NodeType: single
  RedisWhitelist:
    Type: ALIYUN::REDIS::Whitelist
    Properties:
      InstanceId:
        Ref: RedisInstance
      SecurityIps: 192.168.0.0/16
  MseMicroRegistryInstance:
    Type: ALIYUN::MSE::Cluster
    Properties:
      VpcId:
        Ref: VPC
      VSwitchId:
        Ref: VSwitch
      ClusterAliasName:
        Fn::Sub: my_nacos-${ALIYUN::StackId}
      MseVersion: mse_dev
      InstanceCount: 1
      ClusterVersion: NACOS_2_0_0
      ClusterType: Nacos-Ans
      ClusterSpecification: MSE_SC_1_2_60_c
      NetType: privatenet
      PubNetworkFlow: 0
  AutoEnableService:
    Type: 'ALIYUN::ROS::AutoEnableService'
    Properties:
      ServiceName: RocketMQ
  RocketMQ:
    Type: ALIYUN::ROCKETMQ5::Instance
    Properties:
      ProductInfo:
        MsgProcessSpec: rmq.s2.2xlarge
      InternetInfo:
        InternetSpec: disable
        FlowOutType: uninvolved
      InstanceName:
        Fn::Sub: ROCKETMQ5-${ALIYUN::StackId}
      SubSeriesCode: cluster_ha
      SeriesCode: standard
      PaymentType: PayAsYouGo
      VpcInfo:
        VpcId:
          Ref: VPC
        VSwitchId:
          Ref: VSwitch
    DependsOn:
      - AutoEnableService
  Topic1:
    Type: ALIYUN::ROCKETMQ5::Topic
    Properties:
      InstanceId:
        Ref: RocketMQ
      Remark: 预扣库存成功后订单创建失败
      MessageType: NORMAL
      TopicName: order-fail-after-pre-deducted-inventory
  Topic2:
    Type: ALIYUN::ROCKETMQ5::Topic
    Properties:
      InstanceId:
        Ref: RocketMQ
      Remark: 库存系统扣减库存成功后订单创建失败
      MessageType: NORMAL
      TopicName: order-fail-after-deducted-inventory
  Topic3:
    Type: ALIYUN::ROCKETMQ5::Topic
    Properties:
      InstanceId:
        Ref: RocketMQ
      Remark: 订单创建成功
      MessageType: TRANSACTION
      TopicName: order-success
  ConsumerGroup:
    Type: ALIYUN::ROCKETMQ5::ConsumerGroup
    Properties:
      ConsumerGroupId: flashsale-service-consumer-group
      InstanceId:
        Ref: RocketMQ
      ConsumeRetryPolicy:
        RetryPolicy: DefaultRetryPolicy
        MaxRetryTimes: 5
      DeliveryOrderType: Concurrently
  WaitCondition:
    Type: ALIYUN::ROS::WaitCondition
    Properties:
      Count: 1
      Handle:
        Ref: WaitConditionHandle
      Timeout: 1200
    DependsOn:
      - ConsumerGroup
      - AccountPrivilege
      - MseMicroRegistryInstance
      - RedisInstance
      - Topic1
      - Topic2
      - Topic3
  WaitConditionHandle:
    Type: ALIYUN::ROS::WaitConditionHandle
  InstanceRunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        - Fn::Select:
            - 0
            - Fn::GetAtt:
                - ECSInstanceGroup
                - InstanceIds
      CommandContent:
        Fn::Sub: |-
          #!/bin/bash
          cat << EOF >> ~/.bash_profile
          export REGION="${ALIYUN::Region}"
          export DB_URL="${RdsInstance.InnerConnectionString}:3306/flashsale"
          export DB_USERNAME="${DBAccountName}"
          export DB_PASSWORD="${DBPassword}"
          export REDIS_HOST="${RedisInstance.ConnectionDomain}"
          export REDIS_PASSWORD="${RedisAccountPassword}"
          export NACOS_URL="${MseMicroRegistryInstance.IntranetDomain}:8848"
          export ROCKETMQ_ENDPOINT="${RocketMQ.VpcEndpoint}"
          export ROCKETMQ_USERNAME="${RocketMQ.UserName}"
          export ROCKETMQ_PASSWORD="${RocketMQ.Password}"
          export MSE_LICENSE_KEY="${MseLicenseKey}"
          export ARMS_LICENSE_KEY="${ArmsLicenseKey}"
          export ROS_DEPLOY=true
          EOF
          
          source ~/.bash_profile
          
          curl -fsSL https://help-static-aliyun-doc.aliyuncs.com/install-script/arms-apm/install.sh | bash

          # 执行成功回调WaitCondition结束waitCondition的等待
          ${WaitConditionHandle.CurlCli} -d "{\"Data\" : \"Success\", \"status\" : \"SUCCESS\"}"
      Type: RunShellScript
      Timeout: '1200'
    DependsOn:
      - Topic1
      - Topic2
      - Topic3
Outputs:
  ARMSAddress:
    Description:
      en: ARMS address.
      zh-cn: ARMS地址。
    Value:
      Fn::Sub: https://arms.console.aliyun.com/#/tracing/list/${ALIYUN::Region}
  PublicIPAddress:
    Description:
      zh-cn: 商品秒杀页面地址。
      en: The address of the product flash sale page.
    Value:
      'Fn::Sub':
        - 'http://${ServerAddress}'
        - ServerAddress:
            'Fn::Select':
              - 0
              - 'Fn::GetAtt':
                  - ECSInstanceGroup
                  - PublicIps
Metadata:
  'ALIYUN::ROS::Interface':
    Outputs:
      - PublicIPAddress
      - ARMSAddress
    ParameterGroups:
      - Parameters:
          - ZoneId
          - ECSInstanceType
          - ECSPassword
        Label:
          default:
            zh-cn: ECS 配置
            en: ECS Configuration
      - Parameters:
          - DBInstanceClass
          - DBAccountName
          - DBPassword
        Label:
          default:
            zh-cn: RDS 配置
            en: RDS Configuration
      - Parameters:
          - RedisClass
          - RedisAccountPassword
        Label:
          default:
            zh-cn: Tair 配置
            en: Tair Configuration
      - Parameters:
          - MseLicenseKey
          - ArmsLicenseKey
        Label:
          default:
            zh-cn: MSE 和 ARMS 配置
            en: MSE and ARMS Configuration
    TemplateTags:
      - acs:technical-solution:high-availability-architecture:端到端全链路追踪诊断-tech_solu_186