ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: 创建VPC、安全组、ECS实例，配置OSS存储桶，实现Python服务端签名的OSS直传及回调，包含ECS初始化脚本与Apache部署。
  en: Create a Virtual Private Cloud (VPC), configure Security Groups, provision Elastic
    Compute Service (ECS) instances, set up Object Storage Service (OSS) buckets,
    implement server-side signing for Python-based OSS direct uploads with callback
    functionality, including ECS initialization scripts and deployment on Apache.
Parameters:
  OSSBucketName:
    Type: String
    Label:
      en: NewBucketName
      zh-cn: 新建存储空间名称
    Description:
      en: Bucket names must be globally unique within the scope of OSS. The length
        is 3~63 characters. Must start and end with a lowercase English letter or
        number, and can contain lowercase English letters, numbers, and dashes (-).
      zh-cn: Bucket 名称在 OSS 范围内必须全局唯一。长度为3~63个字符。必须以小写英文字母或数字开头和结尾，可包含小写英文字母、数字和短划线（-）。
    AssociationProperty: AutoCompleteInput
    AssociationPropertyMetadata:
      Length: 6
      Prefix: test-bucketname-
      CharacterClasses:
        - Class: lowercase
          min: 1
    AllowedPattern: ^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$
  ZoneId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::ZoneId
    AssociationPropertyMetadata:
      AutoSelectFirst: true
    Label:
      en: Availability Zone
      zh-cn: 可用区
  InstanceType:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    AssociationPropertyMetadata:
      InstanceChargeType: PostPaid
      SystemDiskCategory: cloud_essd
      ZoneId: ${ZoneId}
    Label:
      en: Instance Type
      zh-cn: 实例规格
  Password:
    Type: String
    Label:
      en: Instance Password
      zh-cn: 实例密码
    Description:
      en: The 8-30 long login password of instance, consists of the uppercase, lowercase
        letter and number. <br> special characters include（）'~！@#$%^&*_-+=|{}[]:;'<>,.?/.
      zh-cn: 长度8-30，必须包含大写字母、小写字母、数字、特殊符号三个；<br>特殊字符包括：（）'~！@#$%^&*_-+=|{}[]:;'<>,.?/
    ConstraintDescription:
      en: 'Length 8-30, must contain upper case letters, lower case letters, Numbers,
        special symbols three; special characters include: ()`~!@#$%^&*_-+=|{}[]:;''<>,.?/'
      zh-cn: 长度8-30，必须包含大写字母、小写字母、数字、特殊符号三种；特殊字符包括：()`~!@#$%^&*_-+=|{}[]:;' <>,.?/
    AllowedPattern: '[a-zA-Z0-9-\(\)\`\~\!@\#\$%\^&\*-+=\|\{\}\[\]\:\;\‘\,\.\?\/]*'
    MinLength: 8
    MaxLength: 30
    NoEcho: true
Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      CidrBlock: 10.0.0.0/8
      VpcName:
        Fn::Join:
          - _
          - - Vpc
            - Ref: ALIYUN::StackId
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      VpcId:
        Ref: Vpc
      SecurityGroupName:
        Fn::Join:
          - _
          - - SecurityGroup
            - Ref: ALIYUN::StackId
      SecurityGroupIngress:
        - Priority: 1
          PortRange: 80/80
          NicType: internet
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - Priority: 1
          PortRange: 22/22
          NicType: internet
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - Priority: 1
          PortRange: 8080/8080
          NicType: internet
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Fn::GetAtt:
          - Vpc
          - VpcId
      CidrBlock: 10.0.10.0/24
    DependsOn: Vpc
  WebServer:
    Type: ALIYUN::ECS::Instance
    Properties:
      ZoneId:
        Ref: ZoneId
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: ubuntu_18
      AllocatePublicIP: true
      InstanceType:
        Ref: InstanceType
      Password:
        Ref: Password
      SystemDiskCategory: cloud_essd
      SystemDiskDiskName: SystemDisk
      SystemDiskSize: 40
  OSSBucket:
    Type: ALIYUN::OSS::Bucket
    Properties:
      BucketName:
        Ref: OSSBucketName
      DeletionForce: true
      CORSConfiguration:
        CORSRule:
          - AllowedHeader:
              - '*'
            AllowedMethod:
              - POST
            AllowedOrigin:
              - '*'
            MaxAgeSeconds: 0
  InstanceRunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      InstanceIds:
        - Ref: WebServer
      Type: RunShellScript
      CommandContent:
        Fn::Sub:
          - |
            #!/bin/bash
            sudo apt update
            sudo apt-get install -y unzip
            sudo apt-get install -y python3-dev
            sudo apt install -y python-pip
            pip install pycryptodome
            sudo apt-get install -y apache2
            
            mkdir /home/aliyun
            cd /home/aliyun
            wget https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/97721/cn_zh/1545016122500/aliyun-oss-appserver-python-master.zip
            unzip aliyun-oss-appserver-python-master.zip
            rm aliyun-oss-appserver-python-master.zip
            mv aliyun-oss-appserver-python-preview_1.0.1-2f62c60e04b4ff204320adf47ded9d83fd79e826 aliyun-oss-appserver-python
            chmod -R 777 /home/aliyun
            cd /home/aliyun/aliyun-oss-appserver-python
            sed -i 's/<yourAccessKeyId>/${AccessKey.AccessKeyId}/' appserver.py
            sed -i 's/<yourAccessKeySecret>/${AccessKey.AccessKeySecret}/' appserver.py
            sed -i 's/bucket-name.oss-cn-hangzhou.aliyuncs.com/${OSSBucketName}.oss-${RegionId}.aliyuncs.com/' appserver.py
            sed -i 's/88.88.88.88:8888/${PublicIP}:8080/' appserver.py
            sed -i '36d' appserver.py
            sed -i 's/encodestring/encodebytes/' appserver.py
            
            cd /var/www/html
            wget https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/86983/APP_zh/1537971352825/aliyun-oss-appserver-js-master.zip
            unzip aliyun-oss-appserver-js-master.zip
            rm aliyun-oss-appserver-js-master.zip
            cd aliyun-oss-appserver-js-master
            sed -i 's/88.88.88.88:8888/${PublicIP}:8080/' upload.js
            mv * /var/www/html
            nohup python3 /home/aliyun/aliyun-oss-appserver-python/appserver.py &
          - OSSBucketName:
              Ref: OSSBucketName
            RegionId:
              Ref: ALIYUN::Region
            PublicIP:
              Fn::GetAtt:
                - WebServer
                - PublicIp
      Timeout: 3600
      Sync: true
  User:
    Type: ALIYUN::RAM::User
    Properties:
      UserName:
        Fn::Sub: create_by_document-${ALIYUN::StackId}
      PolicyAttachments:
        System:
          - AliyunOSSFullAccess
  AccessKey:
    Type: ALIYUN::RAM::AccessKey
    Properties:
      UserName:
        Ref: User
Outputs:
  Console.Bucket:
    Label:
      zh-cn: Bucket
      en: Bucket
    Description:
      zh-cn: 文件上传到的bucket控制台页面。可访问该链接查看上传情况。
      en: Bucket console page, view upload status.
    Value:
      Fn::Sub:
        - https://oss.console.aliyun.com/bucket/oss-${Region}/${OSSBucketName}
        - Region:
            Ref: ALIYUN::Region
          OSSBucketName:
            Ref: OSSBucketName
  Console.Url:
    Label:
      zh-cn: Url
      en: Url
    Description:
      zh-cn: 客户端测试页面。可访问该链接测试文件上传。
      en: Client html page.
    Value:
      Fn::Sub:
        - http://${IP}
        - IP:
            Fn::GetAtt:
              - WebServer
              - PublicIp
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - OSSBucketName
          - ZoneId
          - InstanceType
          - Password
    TemplateTags:
      - acs:document-help:oss:Python服务端签名直传并设置上传回调