ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: 创建VPC、VSwitch、ECS实例部署Nginx，配置RDS（可选）、SLB、NAS和ESS，实现高可用Web服务部署。
  en: Create VPC, VSwitch, and ECS instances to deploy Nginx, and configure RDS (optional), SLB, NAS, and ESS to implement high-availability web service deployment.
# 参数配置
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
  InstanceCount:
    Type: Number
    Label:
      en: Instance Count
      zh-cn: 实例数量
    Default: 1
    MinValue: 1
    MaxValue: 100
  EnableRdsStoragePlugin:
    Label:
      en: Enable RDS Storage Plugin
      zh-cn: 开启RDS插件
    Description:
      en: Suggest open RDS storge plugin to store images and prompt
      zh-cn: 建议开启RDS存储插件以保留图片和prompt
    Default: true
    Type: Boolean
  DBInstanceClass:
    Label:
      zh-cn: 实例规格
      en: DB Instance Class
    AssociationProperty: ALIYUN::RDS::Instance::InstanceType
    AssociationPropertyMetadata:
      Engine: MySQL
      EngineVersion: 5.7
      Category: Basic
      Visible:
        Condition:
          Fn::Equals:
            - ${EnableRdsStoragePlugin}
            - true
    Default: 'mysql.n2.medium.1'
    AllowedValues:
      - mysql.n2.medium.1
      - mysql.n4.medium.1
      - mysql.n2.large.1
    Type: String
    Description:
      zh-cn: 根据数据库引擎的类型和可用的区域支持选择实例规格；<br><font color='red'>RDS新客首购2核4G-20GB首月只需8.8元/月</font>
      en: 'Select the instance specification based on the type of database engine and the available area support;<br>see detail: <a href=''https://www.alibabacloud.com/help/doc-detail/26312.html'' target=''_blank''><b><font color=''blue''>Instance specification sheet</font></b></a>'
  DBInstanceStorage:
    Label:
      zh-cn: 实例存储
      en: Storage
    Type: Number
    Description:
      zh-cn: RDS实例大小范围为20-2000，每5个增量，单位为GB
      en: The size range of RDS instances is 20 - 2000, Incrementing in every 5, unit GB
    MinValue: 20
    MaxValue: 2000
    ConstraintDescription:
      zh-cn: RDS实例大小范围为20-2000，每5个增量，单位为GB
      en: The size range of RDS instances is 20 - 2000, Incrementing in every 5, unit GB
    Default: 20
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${EnableRdsStoragePlugin}
            - true
  DBMasterUsername:
    Type: String
    Description:
      en: Primary account name of the database instance.The length cannot exceed 16 characters. Start with an English letter and can contain English letters, numbers and underscores (_).
      zh-cn: 数据库实例的主账号名称。长度不超过16个字符。以英文字母开头，可包含英文字母、数字和下划线（_）。
    ConstraintDescription:
      en: The length cannot exceed 16 characters. Start with an English letter and can contain English letters, numbers and underscores (_)
      zh-cn: 长度不超过16个字符。以英文字母开头，可包含英文字母、数字和下划线（_）
    Label:
      zh-cn: 数据库账号名称
      en: DB Username
    Default: rdsuser
    AllowedPattern: '^[a-zA-Z0-9\_]*$'
    MaxLength: 16
    MinLength: 2
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${EnableRdsStoragePlugin}
            - true
  DBMasterPassword:
    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，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ 中的特殊符号）
    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，必须包含三项（大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ 中的特殊符号）
    AllowedPattern: '^[a-zA-Z0-9-\(\)\`\~\!\@\#\$\%\^\&\*\_\-\+\=\|\{\}\[\]\:\;\<\>\,\.\?\/]*$'
    MinLength: 8
    MaxLength: 30
    Default: pleaseChangeThis
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${EnableRdsStoragePlugin}
            - true
  LoadBalancerSpec:
    Type: String
    AssociationProperty: ALIYUN::SLB::Instance::InstanceType
    Label:
      en: LoadBalancer Specifications
      zh-cn: 负载均衡实例规格
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
  LoadBalancerPersistenceTimeout:
    Type: Number
    Label:
      en: Persistence Timeout
      zh-cn: 会话保持超时时间
    Description:
      en: Persistence Timeout 0 means close persistence
      zh-cn: 用户web使用建议开启会话保持(配置600-3600)，API调用建议关闭会话保持(配置成0)
    Default: 600
    MinValue: 0
    MaxValue: 3600
  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
Conditions:
  UseRDSPlugin:
    Fn::Equals:
      - Ref: EnableRdsStoragePlugin
      - true
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
  # 创建Nat网关
  VpcNatGateway:
    Type: ALIYUN::VPC::NatGateway
    Properties:
      NatGatewayName:
        Ref: ALIYUN::StackName
      VSwitchId:
        Fn::GetAtt:
          - EcsVSwitch
          - VSwitchId
      VpcId:
        Fn::GetAtt:
          - EcsVpc
          - VpcId
  # 创建EIP
  NatGatewayEip:
    Type: ALIYUN::VPC::EIP
    Properties:
      # 名称
      Name:
        Fn::Join:
          - '-'
          - - nat
            - Ref: ALIYUN::StackName
      # 请根据需求配置带宽
      Bandwidth: 100
  # 绑定EIP和Nat网关
  NatGatewayEipAssociation:
    Type: ALIYUN::VPC::EIPAssociation
    Properties:
      AllocationId:
        Fn::GetAtt:
          - NatGatewayEip
          - AllocationId
      InstanceId:
        Fn::GetAtt:
          - VpcNatGateway
          - NatGatewayId
  # 配置NAT网关中的源地址转换表
  SNatEntry:
    DependsOn: NatGatewayEipAssociation
    Type: ALIYUN::ECS::SNatEntry
    Properties:
      SNatIp:
        Fn::GetAtt:
          - NatGatewayEip
          - EipAddress
      SNatTableId:
        Fn::GetAtt:
          - VpcNatGateway
          - SNatTableId
      SourceCIDR:
        Ref: VSwitchCidrBlock
  AccessGroup:
    Type: ALIYUN::NAS::AccessGroup
    Properties:
      AccessGroupName:
        Ref: ALIYUN::StackName
      AccessGroupType: Vpc
  # 创建权限组规则
  AccessRule:
    DependsOn: AccessGroup
    Type: ALIYUN::NAS::AccessRule
    Properties:
      AccessGroupName:
        Fn::GetAtt:
          - AccessGroup
          - AccessGroupName
      # 优先级
      Priority: 1
      # 读写权限类型
      RWAccessType: RDWR
      # 地址
      SourceCidrIp: 0.0.0.0/0
      # 用户权限类型
      UserAccessType: no_squash
  # 创建文件系统
  FileSystem:
    Type: ALIYUN::NAS::FileSystem
    Properties:
      # 协议类型
      ProtocolType: NFS
      # 存储类型
      StorageType: Capacity
      ZoneId:
        Ref: ZoneId
      VSwitchId:
        Ref: EcsVSwitch
      VpcId:
        Ref: EcsVpc
  # 创建挂载点
  MountTarget:
    DependsOn:
      - FileSystem
      - AccessRule
    Type: ALIYUN::NAS::MountTarget
    Properties:
      # 权限组名称
      AccessGroupName:
        Fn::GetAtt:
          - AccessGroup
          - AccessGroupName
      # 文件系统ID
      FileSystemId:
        Fn::GetAtt:
          - FileSystem
          - FileSystemId
      # 网络类型
      NetworkType: Vpc
      VSwitchId:
        Ref: EcsVSwitch
      VpcId:
        Ref: EcsVpc
  EcsSecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupName:
        Ref: ALIYUN::StackName
      VpcId:
        Ref: EcsVpc
      # 安全组出端口
      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:
        Ref: InstanceCount
      Handle:
        Ref: WaitConditionHandle
      Timeout: 2400
  WaitConditionHandle:
    Type: ALIYUN::ROS::WaitConditionHandle
  Database:
    Condition: UseRDSPlugin
    Type: ALIYUN::RDS::DBInstance
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: EcsVpc
      VSwitchId:
        Ref: EcsVSwitch
      Engine: MySQL
      EngineVersion: '5.7'
      DBInstanceClass:
        Ref: DBInstanceClass
      DBInstanceStorage:
        Ref: DBInstanceStorage
      DBInstanceStorageType: cloud_essd
      Category: Basic
      DBInstanceNetType: Intranet
      MasterUserType: Super
      MasterUserPassword:
        Ref: DBMasterPassword
      MasterUsername:
        Ref: DBMasterUsername
      PayType:
        Ref: PayType
      PeriodType:
        Ref: PayPeriodUnit
      Period:
        Ref: PayPeriod
      SecurityIPList:
        Ref: VSwitchCidrBlock
  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: 200
      MaxAmount:
        Ref: InstanceCount
      # 镜像
      ImageId: centos_7
      # 实例类型
      InstanceType:
        Ref: EcsInstanceType
      Password:
        Ref: InstancePassword
      # 公网开启
      AllocatePublicIP: false
      UserData:
        Fn::Sub:
          # 将master的ip输入到/root/conf.txt
          # 可以在后续的步骤中通过conf.txt里的内容完成slave的初始化
          - |
            #!/bin/bash
            #挂载nas
            yum install nfs-utils -y
            if (lsmod | grep sunrpc); then
            (modinfo sunrpc | grep tcp_max_slot_table_entries) && sysctl -w sunrpc.tcp_max_slot_table_entries=128
            (modinfo sunrpc | grep tcp_slot_table_entries) && sysctl -w sunrpc.tcp_slot_table_entries=128
            fi
            (modinfo sunrpc | grep tcp_max_slot_table_entries) && echo "options sunrpc tcp_max_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf
            (modinfo sunrpc | grep tcp_slot_table_entries) && echo "options sunrpc tcp_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf

            sudo mount -t nfs -o vers=4,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${MountTargetDomain}:/ /mnt

            test -e /mnt/stable-diffusion-webui || ( mv /home/stable-diffusion-webui /mnt/ && touch /mnt/mount_finish)

            for ((i=0;i<2400;i++))
            do
               test -e /mnt/mount_finish
               if [ "$?" == 0 ]
               then
                 break
               fi
               sleep 1
            done

            ls -lrt
            rm -rf /home/stable-diffusion-webui && ln -s /mnt/stable-diffusion-webui /home/stable-diffusion-webui

            docker stop `docker ps |grep aigc|awk -F' ' '{print $1}'`
            echo "docker run -d --gpus all -p8081:7860 -v /home/models:/workspace/stable-diffusion-webui/models -v /home/extensions:/workspace/stable-diffusion-webui/extensions -v /home/embeddings:/workspace/stable-diffusion-webui/embeddings -v /home/aesthetic_embeddings:/workspace/stable-diffusion-webui/aesthetic_embeddings -e DB_HOST=${DBConnectString} -e DB_USER=${DBMasterUsername} -e DB_PASSWORD='${DBMasterPassword}' -e DB_PORT=3306 registry.cn-shanghai.aliyuncs.com/tcc_public/aigc:stable-diffusion-v9 sh -c '/opt/conda/bin/python /opt/conda/bin/conda run --no-capture-output -n stabel python3 launch.py --listen --api --enable-insecure-extension-access' "> /etc/init.d/start_sd_docker.sh
            /etc/init.d/start_sd_docker.sh
            for ((i=0;i<100;i++))
            do
               curl 127.0.0.1:8081
               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\"}"
          - DBMasterUsername:
              Ref: DBMasterUsername
            # 从用户输入中拿到用户名和密码
            DBMasterPassword:
              Ref: DBMasterPassword
            # 从Database的Output中拿到内网连接串
            DBConnectString:
              Fn::If:
                - UseRDSPlugin
                - Fn::GetAtt:
                    - Database
                    - InnerConnectionString
                - ''
            UserName:
              Ref: UserName
            Password:
              Ref: Password
            RegionId:
              Ref: ALIYUN::Region
            MountTargetDomain:
              Fn::GetAtt:
                - MountTarget
                - MountTargetDomain
            # 获取到waitConditionHandle的地址放到 ${CurlCli}变量里
            CurlCli:
              Fn::GetAtt:
                - WaitConditionHandle
                - CurlCli
  Slb:
    Type: ALIYUN::SLB::LoadBalancer
    Properties:
      VpcId:
        Ref: EcsVpc
      VSwitchId:
        Ref: EcsVSwitch
      LoadBalancerName:
        Fn::Join:
          - '-'
          - - 'slb'
            - Ref: ALIYUN::StackName
      PayType:
        Ref: PayType
      PricingCycle:
        Ref: PayPeriodUnit
      Duration:
        Ref: PayPeriod
      AddressType: intranet
      LoadBalancerSpec:
        Ref: LoadBalancerSpec
      AutoPay: true
  EipSlbAddress:
    Type: ALIYUN::VPC::EIP
    Properties:
      Name:
        Fn::Join:
          - '-'
          - - 'slb'
            - Ref: ALIYUN::StackName
      InternetChargeType: PayByTraffic
      Bandwidth: 100
  EipSlbAddressAssociation:
    Type: ALIYUN::VPC::EIPAssociation
    Properties:
      InstanceId:
        Ref: Slb
      AllocationId:
        Ref: EipSlbAddress
  SlbBackendServerAttachment:
    DependsOn:
      - EcsInstanceGroup
    Type: ALIYUN::SLB::BackendServerAttachment
    Properties:
      BackendServerList:
        Fn::GetAtt:
          - EcsInstanceGroup
          - InstanceIds
      LoadBalancerId:
        Ref: Slb
      BackendServerWeightList:
        - 100
  SlbListener:
    DependsOn:
      - Slb
    Type: ALIYUN::SLB::Listener
    Properties:
      Persistence:
        CookieTimeout: 60
        StickySession: 'on'
        PersistenceTimeout:
          Ref: LoadBalancerPersistenceTimeout
        XForwardedFor: 'off'
        StickySessionType: insert
      ListenerPort: 8080
      Bandwidth: -1
      HealthCheck:
        HttpCode: http_2xx,http_3xx,http_4xx,http_5xx
        HealthCheckType: tcp
        UnhealthyThreshold: 3
        Timeout: 5
        HealthyThreshold: 3
        Port: 8080
        URI: /
        Interval: 2
      LoadBalancerId:
        Ref: Slb
      BackendServerPort: 8080
      Protocol: tcp
  EssInstanceScalingGroupEnable:
    Type: 'ALIYUN::ESS::ScalingGroupEnable'
    Properties:
      ScalingRuleArisExecuteVersion: '1'
      ScalingConfigurationId:
        Ref: EcsInstanceScalingConfiguration
      InstanceIds:
        'Fn::GetAtt':
          - EcsInstanceGroup
          - InstanceIds
      ScalingGroupId:
        Ref: EssInstanceScalingGroup
    DependsOn:
      - EcsInstanceScalingConfiguration
      - EssInstanceScalingGroup
  EcsInstanceScalingConfiguration:
    Type: 'ALIYUN::ESS::ScalingConfiguration'
    Properties:
      # 网络配置
      SecurityGroupId:
        Ref: EcsSecurityGroup
      # 伸缩组
      ScalingGroupId:
        Ref: EssInstanceScalingGroup
      ScalingConfigurationName:
        Fn::Join:
          - '-'
          - - 'sc'
            - Ref: ALIYUN::StackName
      # 实例类型
      InstanceType:
        Ref: EcsInstanceType
      # SLB
      LoadBalancerWeight: 100
      # 磁盘配置
      SystemDiskCategory: cloud_essd
      SystemDiskSize: 200
      ImageId: centos_7
      InstanceName:
        Fn::Join:
          - '-'
          - - Ref: ALIYUN::StackName
            - '[1,4]'
      UserData:
        Fn::Sub:
          # 将master的ip输入到/root/conf.txt
          # 可以在后续的步骤中通过conf.txt里的内容完成slave的初始化
          - |
            #!/bin/bash

            #挂载nas
            yum install nfs-utils -y
            if (lsmod | grep sunrpc); then
            (modinfo sunrpc | grep tcp_max_slot_table_entries) && sysctl -w sunrpc.tcp_max_slot_table_entries=128
            (modinfo sunrpc | grep tcp_slot_table_entries) && sysctl -w sunrpc.tcp_slot_table_entries=128
            fi
            (modinfo sunrpc | grep tcp_max_slot_table_entries) && echo "options sunrpc tcp_max_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf
            (modinfo sunrpc | grep tcp_slot_table_entries) && echo "options sunrpc tcp_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf

            sudo mount -t nfs -o vers=4,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${MountTargetDomain}:/ /mnt

            test -e /mnt/stable-diffusion-webui ||  mv /home/stable-diffusion-webui /mnt/
            rm -rf /home/stable-diffusion-webui && ln -s /mnt/stable-diffusion-webui /home/stable-diffusion-webui

            docker stop `docker ps |grep aigc|awk -F' ' '{print $1}'`
            echo "docker run -d --gpus all -p8081:7860 -v /home/models:/workspace/stable-diffusion-webui/models -v /home/extensions:/workspace/stable-diffusion-webui/extensions -v /home/embeddings:/workspace/stable-diffusion-webui/embeddings -v /home/aesthetic_embeddings:/workspace/stable-diffusion-webui/aesthetic_embeddings -e DB_HOST=${DBConnectString} -e DB_USER=${DBMasterUsername} -e DB_PASSWORD='${DBMasterPassword}' -e DB_PORT=3306 registry.cn-shanghai.aliyuncs.com/tcc_public/aigc:stable-diffusion-v9 sh -c '/opt/conda/bin/python /opt/conda/bin/conda run --no-capture-output -n stabel python3 launch.py --listen --api --enable-insecure-extension-access' "> /etc/init.d/start_sd_docker.sh
            /etc/init.d/start_sd_docker.sh
            for ((i=0;i<100;i++))
            do
               curl 127.0.0.1:8081
               if [ "$?" == 0 ]
               then
                 break
               fi
               sleep 1
            done
            ARGUS_VERSION=3.5.7 /bin/bash -c "$(curl -s https://cms-agent-${RegionId}.oss-${RegionId}-internal.aliyuncs.com/Argus/agent_install_ecs-1.7.sh)" >> /root/install_cms_agent.log
            htpasswd -bc /etc/nginx/password ${UserName} '${Password}'
            systemctl start nginx
            systemctl status nginx
            systemctl enable nginx
            # 执行成功回调WaitCondition结束waitCondition的等待
          - DBMasterUsername:
              Ref: DBMasterUsername
            # 从用户输入中拿到用户名和密码
            DBMasterPassword:
              Ref: DBMasterPassword
            # 从Database的Output中拿到内网连接串
            DBConnectString:
              Fn::If:
                - UseRDSPlugin
                - Fn::GetAtt:
                    - Database
                    - InnerConnectionString
                - ''
            RegionId:
              Ref: ALIYUN::Region
            UserName:
              Ref: UserName
            Password:
              Ref: Password
            MountTargetDomain:
              Fn::GetAtt:
                - MountTarget
                - MountTargetDomain
  EssInstanceScalingGroup:
    Type: 'ALIYUN::ESS::ScalingGroup'
    Properties:
      ScalingGroupName:
        Fn::Join:
          - '-'
          - - 'scg'
            - Ref: ALIYUN::StackName
      RemovalPolicys:
        - NewestInstance
      MinSize:
        Ref: InstanceCount
      MaxSize: 1000
      VSwitchId:
        Ref: EcsVSwitch
      DefaultCooldown: 300
      LoadBalancerIds:
        - Ref: Slb
      HealthCheckType: NONE
    DependsOn:
      - Slb
      - SlbListener
# 定义输出
Outputs:
  # 将公网ip做为http返回的地址显示在控制台
  Endpoint:
    Description:
      zh-cn: 对外暴露的公网IP地址
      en: Public IP Addresses
    Value:
      Fn::Sub:
        - http://${ServerAddress}:8080
        - ServerAddress:
            Fn::GetAtt:
               - EipSlbAddress
               - EipAddress

Metadata:
  ALIYUN::ROS::Interface:
    TemplateTags:
      - 'acs:integrate:计算巢:StableDiffusion'
    # 分组信息
    ParameterGroups:
      - Parameters:
          - PayType
          - PayPeriodUnit
          - PayPeriod
        Label:
          default:
            en: PayType Configuration
            zh-cn: 付费类型配置
      - Parameters:
          - EcsInstanceType
          - InstancePassword
          - InstanceCount
        Label:
          default:
            en: Instance
            zh-cn: ECS实例配置
      - Parameters:
          - LoadBalancerSpec
          - LoadBalancerPersistenceTimeout
        Label:
          default:
            en: SLB Configure
            zh-cn: 负载均衡配置
      - Parameters:
          - UserName
          - Password
        Label:
          default:
            en: Login Information
            zh-cn: 登录信息
      - Parameters:
          - EnableRdsStoragePlugin
          - DBInstanceClass
          - DBInstanceStorage
          - DBInstanceStorageType
          - DBMasterUsername
          - DBMasterPassword
        Label:
          default:
            en: Database
            zh-cn: RDS插件配置
      - Parameters:
          - ZoneId
        Label:
          default:
            zh-cn: 可用区配置
            en: Zone Configuration
      - Parameters:
          - VpcCidrBlock
          - VSwitchCidrBlock
        Label:
          default:
            zh-cn: 选择网络配置
            en: Choose existing Infrastructure Configuration