全部產品
Search
文件中心

Resource Orchestration Service:ALIYUN::ECS::RunCommand

更新時間:Feb 06, 2026

ALIYUN::ECS::RunCommand類型用於在一台或多台ECS執行個體中執行一段Shell、PowerShell或者Bat類型的指令碼。

文法

{
  "Type": "ALIYUN::ECS::RunCommand",
  "Properties": {
    "Parameters": Map,
    "Description": String,
    "Timeout": Integer,
    "ContentEncoding": String,
    "Name": String,
    "WorkingDir": String,
    "CommandContent": String,
    "Type": String,
    "Frequency": String,
    "EnableParameter": Boolean,
    "InstanceIds": List,
    "KeepCommand": Boolean,
    "Sync": Boolean,
    "Tags": List,
    "RunAgainOn": List,
    "WindowsPasswordName": String,
    "RepeatMode": String,
    "ResourceGroupId": String,
    "Launcher": String,
    "ContainerName": String,
    "ContainerId": String,
    "Username": String
  }
}

屬性

屬性名稱

類型

必須

允許更新

描述

約束

Parameters

Map

指令碼中包含自訂參數時,執行指令碼時指定的自訂參數的索引值對。例如:指令碼內容為echo {{name}},則可以通過Parameters參數指定索引值對{"name":"Jack"}。自訂參數將自動替換變數值name,得到一條新的指令碼,實際執行的是echo Jack。

  • 最多支援10個自訂參數。

  • 鍵不允許為空白字串,最多支援64個字元。 值允許為空白字串。

  • 自訂參數與原始指令碼內容在Base64編碼後,綜合長度不能超過16KB。

  • 設定的自訂參數名集合必須為建立指令碼時定義的參數集的子集。

  • 對於未指定的參數,您可以使用Null 字元串代替。

Description

String

指令碼描述。

支援全字元集,長度不超過512個字元。

Timeout

Integer

執行指令碼的逾時時間。

單位:秒。

預設值:60。

當因為進程原因、缺失模組、缺失雲助手用戶端等原因無法運行指令碼時,會出現逾時現象。逾時後,會強制終止指令碼進程。

ContentEncoding

String

指令碼內容(CommandContent)的編碼方式。

取值:

  • Base64(預設值):Base64編碼。

  • PlainText:不編碼,採用明文傳輸。

說明

當您錯填值時,會被當作Base64處理。

Name

String

指令碼名稱。

支援全字元集,長度不超過128個字元。

WorkingDir

String

指令碼在ECS執行個體中的運行目錄。

預設值:

  • Linux執行個體:/root

  • Windows執行個體:C:\Windows\System32\

CommandContent

String

指令碼的明文內容或者Base64編碼後的內容。

  • 指令碼內容Base64編碼後不能超過16KB。

  • EnableParameter取值為true時,可以在指令碼內容中啟用自訂參數功能:自訂參數寫作兩個大括弧({{}})中,在兩個大括弧({{}})內參數名前後的空格以及分行符號會被忽略。

  • 自訂參數個數不能超過10個。自訂參數名可包含英文字母、數字、短劃線(-)和底線(_)。 單個自訂參數名不能超過64個字元。

Type

String

營運指令碼的語言類型。

取值:

  • RunBatScript:適用於Windows執行個體的Bat指令碼。

  • RunPowerShellScript:適用於Windows執行個體的PowerShell指令碼。

  • RunShellScript:適用於Linux執行個體的Shell指令碼 。

Frequency

String

周期任務的執行循環。

EnableParameter

Boolean

指令碼中是否包含自訂參數。

取值:

  • true:包含自訂參數。

  • false(預設值):不包含自訂參數。

InstanceIds

List

ECS執行個體ID列表。

最多指定20台ECS執行個體,且ECS執行個體的狀態必須是運行中。

KeepCommand

Boolean

執行完該指令碼後是否保留。

取值:

  • true:保留。可以通過InvokeCommand再次執行。會佔用雲助手指令碼的保有量配額。

  • false(預設值):不保留,執行完成後自動刪除,不佔用雲助手指令碼的保有量配額。

Sync

Boolean

是否同步調用。

取值:

  • true:同步調用。

  • false:非同步呼叫。

Tags

List

標籤。

最多支援添加20個標籤。更多資訊,請參見Tags屬性

RunAgainOn

List

再次執行命令的階段。

WindowsPasswordName

String

在Windows執行個體中執行命令的使用者的密碼名稱。

長度不得超過 255 個字元。

當您希望以非預設使用者(System)在 Windows 執行個體中執行命令時,需要同時傳入Username和該參數。為降低密碼泄露的風險,需要將密碼明文託管在營運編排服務的參數倉庫中,此處僅傳入密碼的名稱。更多資訊,請參見加密參數以及設定普通使用者執行雲助手命令

說明

當您使用 Linux 執行個體的 root 使用者或 Windows 執行個體的 System 使用者執行命令時,不需要傳遞該參數。

RepeatMode

String

設定命令執行的方式。

取值範圍:

  • Once:立即執行命令。

  • Period:定時執行命令。當該參數取值為Period時,必須同時指定Frequency參數。

  • NextRebootOnly:當執行個體下一次啟動時,自動執行命令。

  • EveryReboot:執行個體每一次啟動都將自動執行命令。

預設值:

  • 當不指定Frequency參數時,預設值為Once

  • 當指定Frequency參數時,無論是否已設定了該參數值,都將按照Period處理。

注意事項:

  • 您可以調用StopInvocation停止待執行的命令或定時執行的命令。

  • 當該參數取值Period或者EveryReboot時,您可以調用DescribeInvocationResults,然後指定IncludeHistory=true查看命令定時執行的記錄。

Launcher

String

指令碼執行的引導程式。

長度不能超過 1 KB。

ResourceGroupId

String

命令執行的資源群組ID。

當指定該參數時:

ContainerName

String

容器名稱。

注意事項:

  • 如果指定了該參數,雲助手將在執行個體的指定容器內執行指令碼。

  • 如果指定了該參數,僅支援在雲助手Agent版本不低於 2.2.3.344 的 Linux 執行個體內運行。

  • 如果指定了該參數,已指定的Username參數和WorkingDir參數將不會生效。僅支援通過容器預設使用者在容器的預設工作目錄下執行命令。詳細資料,請參見使用雲助手在容器內執行命令

  • 如果指定了該參數,在Linux容器中只支援執行Shell指令碼,不支援在指令碼開頭使用類似#!/usr/bin/python命令的形式指定指令碼內容的解譯器。詳細資料,請參見使用雲助手在容器內執行命令

ContainerId

String

容器ID。

僅支援64位16進位字串,允許存在docker://containerd://或者cri-o://首碼來明確指定的容器運行時。

注意事項:

  • 如果指定了該參數,雲助手將在執行個體的指定容器內執行指令碼。

  • 如果指定了該參數,僅支援在雲助手Agent版本不低於2.2.3.344的Linux執行個體內運行。

  • 如果指定了該參數,已指定的Username參數和WorkingDir參數將不會生效。僅支援通過容器預設使用者在容器的預設工作目錄下執行命令。詳細資料,請參見使用雲助手在容器內執行命令

  • 如果指定了該參數,在Linux容器中只支援執行Shell指令碼,不支援在指令碼開頭使用類似#!/usr/bin/python命令的形式指定指令碼內容的解譯器。詳細資料,請參見使用雲助手在容器內執行命令

Username

String

在ECS執行個體中執行命令的使用者名稱。

長度不得超過255個字元。

  • Linux系統的ECS執行個體,預設以root使用者執行命令。

  • Windows系統的ECS執行個體,預設以System使用者執行命令。

您也可以指定執行個體中已存在的其他使用者執行命令,以普通使用者執行雲助手命令更加安全。更多資訊,請參見設定普通使用者執行雲助手命令

Tags文法

"Tags": [
  {
    "Key": String,
    "Value": String
  }
]

Tags屬性

屬性名稱

類型

必須

允許更新

描述

約束

Key

String

標籤鍵。

長度為1~128個字元,不能以aliyunacs:開頭,不能包含http://或者https://

Value

String

標籤值。

長度為0~128個字元,不能以aliyunacs:開頭,不能包含http://或者https://

傳回值

Fn::GetAtt

  • CommandId:指令碼ID。

  • InvokeId:指令碼執行ID。

  • InvokeInstances:執行命令的執行個體列表。

  • InvokeResults:執行命令的結果。

樣本

ROSTemplateFormatVersion: '2015-09-01'
Parameters:
  InstanceId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Resources:
  RunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      CommandContent:
        Fn::Sub:
            |
            #!/bin/sh
            yum install -y tree
      Type: RunShellScript
      InstanceIds:
        - Ref: InstanceId
Outputs:
  CommandId:
    Description: The id of command created.
    Value:
      Fn::GetAtt:
        - RunCommand
        - CommandId
  InvokeId:
    Description: The invoke id of command.
    Value:
      Fn::GetAtt:
        - RunCommand
        - InvokeId
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Parameters": {
    "InstanceId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceId"
    }
  },
  "Resources": {
    "RunCommand": {
      "Type": "ALIYUN::ECS::RunCommand",
      "Properties": {
        "CommandContent": {
          "Fn::Sub": 
            "#!/bin/sh\nyum install -y tree\n"
        },
        "Type": "RunShellScript",
        "InstanceIds": [
          {
            "Ref": "InstanceId"
          }
        ]
      }
    }
  },
  "Outputs": {
    "CommandId": {
      "Description": "The id of command created.",
      "Value": {
        "Fn::GetAtt": [
          "RunCommand",
          "CommandId"
        ]
      }
    },
    "InvokeId": {
      "Description": "The invoke id of command.",
      "Value": {
        "Fn::GetAtt": [
          "RunCommand",
          "InvokeId"
        ]
      }
    }
  }
}

UpdatePolicy簡介

當我們使用ALIYUN::ECS::RunCommand為一組ECS執行個體執行指令碼後,需要對已執行指令碼的這組ECS進行配置批次更新時,可以使用UpdatePolicy屬性去完成對ECS::RunCommand配置更新策略的控制。UpdatePolicy屬性文法參考:

UpdatePolicy文法

"UpdatePolicy": {
  "RollingUpdate": Map
}

UpdatePolicy屬性

屬性名稱

類型

必須

允許更新

描述

約束

RollingUpdate

Map

控制更新已有的Command的策略。

詳見RollingUpdate屬性

RollingUpdate文法

"RollingUpdate": {
  "MaxBatchSize": Integer,
  "PauseTime": Integer
}

RollingUpdate屬性

屬性名稱

類型

必須

允許更新

描述

約束

MaxBatchSize

Integer

每個批次執行命令的ECS台數。

取值範圍:1~1000。

PauseTime

Integer

各個批次執行命令之間暫停時間(單位:秒)預設為0。

取值範圍:0~3600。

情境 1 :在已有ECS情境下執行命令RunCommand。

快速建立

ROSTemplateFormatVersion: '2015-09-01'
Resources:
  RunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      CommandContent: xxx
      Type: RunShellScript
      Sync: true
      InstanceIds:
        - i-2zxxxx
        - i-2zxxxx
        - i-2zxxxx
{
    "ROSTemplateFormatVersion": "2015-09-01",
    "Resources": {
        "RunCommand": {
            "Type": "ALIYUN::ECS::RunCommand",
            "Properties": {
                "CommandContent": "xxx",
                "Type": "RunShellScript",
                "Sync": true,
                "InstanceIds": [
                    "i-2zxxxx",
                    "i-2zxxxx",
                    "i-2zxxxx",
                ]
            }
        }
    }
}

建立資源棧成功後對已執行Command的ECS執行個體進行配置更新,更新時可以配置UpdatePolicy屬性。

ROSTemplateFormatVersion: '2015-09-01'
Resources:
  RunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      CommandContent: xxx
      Type: RunShellScript
      Sync: true
      InstanceIds:
        - i-2zxxxx
        - i-2zxxxx
        - i-2zxxxx
        - i-2zxxxx
        - i-2zxxxx
    UpdatePolicy:
      RollingUpdate:
        MaxBatchSize: 2
        PauseTime: 10
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Resources": {
    "RunCommand": {
      "Type": "ALIYUN::ECS::RunCommand",
      "Properties": {
        "CommandContent": "xxx",
        "Type": "RunShellScript",
        "Sync": true,
        "InstanceIds": [
          "i-2zxxxx",
          "i-2zxxxx",
          "i-2zxxxx",
          "i-2zxxxx",
          "i-2zxxxx"
        ]
      },
      "UpdatePolicy": {
        "RollingUpdate": {
          "MaxBatchSize": 2,
          "PauseTime": 10
        }
      }
    }
  }
}

指定MaxBatchSize=2。 更新前InstanceIds內包含3台ECS執行個體,更新後InstanceIds內包含5台ECS執行個體,在更新資源棧的過程中,原有的3台機器,會分2個批次(2/1)進行變更配置更新(原有的InstanceIds資訊會按照傳入的順序劃分批次)。新增的2台機器會被一次性統一執行Command。

情境 2 :建立ECS(Alibaba Cloud Linux 3)並部署Django環境

快速建立

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: 部署Django環境。
  en: Deploy the Django environment.
Parameters:
  ZoneId:
    Default: Null
    AssociationProperty: ALIYUN::ECS::Instance::ZoneId
    Required: true
    Type: String
    Label:
      zh-cn: 可用性區域
      en: Availability Zone
  InstanceType:
    AssociationPropertyMetadata:
      SystemDiskCategory: cloud_essd
      SpotStrategy: SpotAsPriceGo
      InstanceChargeType: PostPaid
      ZoneId: ${ZoneId}
    Default: Null
    Required: true
    Label:
      zh-cn: 執行個體類型
      en: Instance Type
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    Type: String
  InstancePassword:
    Description:
      zh-cn: 伺服器登入密碼,長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)
      en: Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
    Confirm: true
    Default: Null
    Type: String
    Label:
      zh-cn: 執行個體密碼
      en: Instance Password
    NoEcho: true
    AssociationProperty: ALIYUN::ECS::Instance::Password
    ConstraintDescription:
      zh-cn: 長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
  ImageId:
    AssociationPropertyMetadata:
      ValueLabelMapping:
        aliyun_3_x64_20G_alibase_20240528.vhd:
          zh-cn: Alibaba Cloud Linux 3
          en: Alibaba Cloud Linux 3
    Default: aliyun_3_x64_20G_alibase_20240528.vhd
    Required: true
    Label:
      zh-cn: 執行個體鏡像
      en: Image of Instance
    AllowedValues:
      - aliyun_3_x64_20G_alibase_20240528.vhd
    Type: String
Outputs: {}
Conditions: {}
Resources:
  SecurityGroupIngress_80:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      IpProtocol: tcp
      SecurityGroupId:
        Ref: SecurityGroup
      NicType: intranet
      SourceCidrIp: 0.0.0.0/0
      PortRange: 80/80
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupIngress:
        - PortRange: 80/80
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: '-1/-1'
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: icmp
      VpcId:
        Ref: Vpc
      SecurityGroupName: deploy_django_by_ros_sg
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      VpcName: deploy_django_by_ros_vpc
      CidrBlock: 192.168.0.0/16
  DeployDjango:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      Type: RunShellScript
      CommandContent:
        Fn::Sub: |-
          #!/bin/bash
          sudo yum -y install nginx python3-devel.x86_64


          sudo pip3 install Django uwsgi
          sudo mkdir /home/myblog && cd /home/myblog

          sudo /usr/local/bin/django-admin.py startproject uwsgi_project

          sudo sed -i 's/ALLOWED_HOSTS = \[\]/ALLOWED_HOSTS = \["*"\]/g' /home/myblog/uwsgi_project/uwsgi_project/settings.py
          sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
          sudo mv /etc/uwsgi.ini /etc/uwsgi.ini.bak

          cat << "EOF" > /etc/nginx/nginx.conf
          user nginx;
          worker_processes auto;
          error_log /var/log/nginx/error.log;
          pid /run/nginx.pid;
          # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
          include /usr/share/nginx/modules/*.conf;
          events {
            worker_connections 1024;
          }
          http {
            log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                              '$status $body_bytes_sent "$http_referer" '
                              '"$http_user_agent" "$http_x_forwarded_for"';
            access_log  /var/log/nginx/access.log  main;
            sendfile            on;
            tcp_nopush          on;
            tcp_nodelay         on;
            keepalive_timeout   65;
            types_hash_max_size 4096;
            include             /etc/nginx/mime.types;
            default_type        application/octet-stream;
            # Load modular configuration files from the /etc/nginx/conf.d directory.
            # See http://nginx.org/en/docs/ngx_core_module.html#include
            # for more information.
            include /etc/nginx/conf.d/*.conf;
            upstream django {
                server 127.0.0.1:8001; #具體連接埠必須與您uWSGI設定檔中定義的連接埠一致
            }
            server {
              listen       80; #設定的nginx訪問連接埠
              server_name  test;
              charset      utf-8;
              # Load configuration files for the default server block.
              include /etc/nginx/default.d/*.conf;
              location /static {
                autoindex on;
                alias /home/myblog/uwsgi_project/uwsgi_project/static; #具體目錄以您現場具體部署的目錄為準
              }
              location / {
                uwsgi_pass 127.0.0.1:8001;
                include uwsgi_params; #具體目錄以您現場具體部署的目錄為準
                include /etc/nginx/uwsgi_params; #具體目錄以您現場具體部署的目錄為準
                uwsgi_param UWSGI_SCRIPT iCourse.wsgi; #具體目錄以您現場具體部署的目錄為準
                uwsgi_param UWSGI_CHDIR /iCourse; #具體目錄以您現場具體部署的目錄為準
                index  index.html index.htm;
                client_max_body_size 35m;
                index index.html index.htm;
              }
              error_page 404 /404.html;
                location = /40x.html {
              }
              error_page 500 502 503 504 /50x.html;
                location = /50x.html {
              }
            }
          }      
          EOF

          cat << "EOF" > /etc/uwsgi.ini
          [uwsgi]
          socket = 127.0.0.1:8001
          chdir = /home/myblog/uwsgi_project/
          wsgi-file = uwsgi_project/wsgi.py
          processes = 4
          threads = 2
          vacuum = true
          buffer-size = 65536
          EOF

          cat << "EOF" > /etc/systemd/system/uwsgi.service
          [Unit]
          Description=uwsgi service
          After=network.target
          [Service]
          Type=simple
          User=nginx
          Group=nginx
          ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi.ini
          [Install]
          WantedBy=multi-user.target
          EOF
          sudo systemctl daemon-reload
          sudo systemctl enable nginx.service
          sudo systemctl restart nginx.service
          sudo systemctl enable uwsgi.service
          sudo systemctl restart uwsgi.service
      Sync: true
      InstanceIds:
        - Ref: EcsInstance
      Timeout: 3600
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      VSwitchName: deploy_django_by_ros_vsw
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
      ZoneId:
        Ref: ZoneId
  EcsInstance:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      SystemDiskCategory: cloud_essd
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId:
        Ref: ImageId
      InternetMaxBandwidthOut: 100
      SpotStrategy: SpotAsPriceGo
      VSwitchId:
        Ref: VSwitch
      Password:
        Ref: InstancePassword
      InstanceName: deploy_django_by_ros_ecs
      InstanceType:
        Ref: InstanceType
      ZoneId:
        Ref: ZoneId
      MaxAmount: 1
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - ZoneId
          - ImageId
          - InstanceType
          - InstancePassword
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": {
    "zh-cn": "部署Django環境。",
    "en": "Deploy the Django environment."
  },
  "Parameters": {
    "ZoneId": {
      "Default": null,
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Required": true,
      "Type": "String",
      "Label": {
        "zh-cn": "可用性區域",
        "en": "Availability Zone"
      }
    },
    "InstanceType": {
      "AssociationPropertyMetadata": {
        "SystemDiskCategory": "cloud_essd",
        "SpotStrategy": "SpotAsPriceGo",
        "InstanceChargeType": "PostPaid",
        "ZoneId": "${ZoneId}"
      },
      "Default": null,
      "Required": true,
      "Label": {
        "zh-cn": "執行個體類型",
        "en": "Instance Type"
      },
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "Type": "String"
    },
    "InstancePassword": {
      "Description": {
        "zh-cn": "伺服器登入密碼,長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)",
        "en": "Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
      },
      "Confirm": true,
      "Default": null,
      "Type": "String",
      "Label": {
        "zh-cn": "執行個體密碼",
        "en": "Instance Password"
      },
      "NoEcho": true,
      "AssociationProperty": "ALIYUN::ECS::Instance::Password",
      "ConstraintDescription": {
        "zh-cn": "長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)",
        "en": "Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
      }
    },
    "ImageId": {
      "AssociationPropertyMetadata": {
        "ValueLabelMapping": {
          "aliyun_3_x64_20G_alibase_20240528.vhd": {
            "zh-cn": "Alibaba Cloud Linux 3",
            "en": "Alibaba Cloud Linux 3"
          }
        }
      },
      "Default": "aliyun_3_x64_20G_alibase_20240528.vhd",
      "Required": true,
      "Label": {
        "zh-cn": "執行個體鏡像",
        "en": "Image of Instance"
      },
      "AllowedValues": [
        "aliyun_3_x64_20G_alibase_20240528.vhd"
      ],
      "Type": "String"
    }
  },
  "Outputs": {},
  "Conditions": {},
  "Resources": {
    "SecurityGroupIngress_80": {
      "Type": "ALIYUN::ECS::SecurityGroupIngress",
      "Properties": {
        "IpProtocol": "tcp",
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "NicType": "intranet",
        "SourceCidrIp": "0.0.0.0/0",
        "PortRange": "80/80"
      }
    },
    "SecurityGroup": {
      "Type": "ALIYUN::ECS::SecurityGroup",
      "Properties": {
        "SecurityGroupIngress": [
          {
            "PortRange": "80/80",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "-1/-1",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "icmp"
          }
        ],
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupName": "deploy_django_by_ros_sg"
      }
    },
    "Vpc": {
      "Type": "ALIYUN::ECS::VPC",
      "Properties": {
        "VpcName": "deploy_django_by_ros_vpc",
        "CidrBlock": "192.168.0.0/16"
      }
    },
    "DeployDjango": {
      "Type": "ALIYUN::ECS::RunCommand",
      "Properties": {
        "Type": "RunShellScript",
        "CommandContent": {
          "Fn::Sub": "#!/bin/bash\nsudo yum -y install nginx python3-devel.x86_64\n\n\nsudo pip3 install Django uwsgi\nsudo mkdir /home/myblog && cd /home/myblog\n\nsudo /usr/local/bin/django-admin.py startproject uwsgi_project\n\nsudo sed -i 's/ALLOWED_HOSTS = \\[\\]/ALLOWED_HOSTS = \\[\"*\"\\]/g' /home/myblog/uwsgi_project/uwsgi_project/settings.py\nsudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak\nsudo mv /etc/uwsgi.ini /etc/uwsgi.ini.bak\n\ncat << \"EOF\" > /etc/nginx/nginx.conf\nuser nginx;\nworker_processes auto;\nerror_log /var/log/nginx/error.log;\npid /run/nginx.pid;\n# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.\ninclude /usr/share/nginx/modules/*.conf;\nevents {\n  worker_connections 1024;\n}\nhttp {\n  log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\n                    '$status $body_bytes_sent \"$http_referer\" '\n                    '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n  access_log  /var/log/nginx/access.log  main;\n  sendfile            on;\n  tcp_nopush          on;\n  tcp_nodelay         on;\n  keepalive_timeout   65;\n  types_hash_max_size 4096;\n  include             /etc/nginx/mime.types;\n  default_type        application/octet-stream;\n  # Load modular configuration files from the /etc/nginx/conf.d directory.\n  # See http://nginx.org/en/docs/ngx_core_module.html#include\n  # for more information.\n  include /etc/nginx/conf.d/*.conf;\n  upstream django {\n      server 127.0.0.1:8001; #具體連接埠必須與您uWSGI設定檔中定義的連接埠一致\n  }\n  server {\n    listen       80; #設定的nginx訪問連接埠\n    server_name  test;\n    charset      utf-8;\n    # Load configuration files for the default server block.\n    include /etc/nginx/default.d/*.conf;\n    location /static {\n      autoindex on;\n      alias /home/myblog/uwsgi_project/uwsgi_project/static; #具體目錄以您現場具體部署的目錄為準\n    }\n    location / {\n      uwsgi_pass 127.0.0.1:8001;\n      include uwsgi_params; #具體目錄以您現場具體部署的目錄為準\n      include /etc/nginx/uwsgi_params; #具體目錄以您現場具體部署的目錄為準\n      uwsgi_param UWSGI_SCRIPT iCourse.wsgi; #具體目錄以您現場具體部署的目錄為準\n      uwsgi_param UWSGI_CHDIR /iCourse; #具體目錄以您現場具體部署的目錄為準\n      index  index.html index.htm;\n      client_max_body_size 35m;\n      index index.html index.htm;\n    }\n    error_page 404 /404.html;\n      location = /40x.html {\n    }\n    error_page 500 502 503 504 /50x.html;\n      location = /50x.html {\n    }\n  }\n}      \nEOF\n\ncat << \"EOF\" > /etc/uwsgi.ini\n[uwsgi]\nsocket = 127.0.0.1:8001\nchdir = /home/myblog/uwsgi_project/\nwsgi-file = uwsgi_project/wsgi.py\nprocesses = 4\nthreads = 2\nvacuum = true\nbuffer-size = 65536\nEOF\n\ncat << \"EOF\" > /etc/systemd/system/uwsgi.service\n[Unit]\nDescription=uwsgi service\nAfter=network.target\n[Service]\nType=simple\nUser=nginx\nGroup=nginx\nExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi.ini\n[Install]\nWantedBy=multi-user.target\nEOF\nsudo systemctl daemon-reload\nsudo systemctl enable nginx.service\nsudo systemctl restart nginx.service\nsudo systemctl enable uwsgi.service\nsudo systemctl restart uwsgi.service"
        },
        "Sync": true,
        "InstanceIds": [
          {
            "Ref": "EcsInstance"
          }
        ],
        "Timeout": 3600
      }
    },
    "VSwitch": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": "deploy_django_by_ros_vsw",
        "VpcId": {
          "Ref": "Vpc"
        },
        "CidrBlock": "192.168.0.0/24",
        "ZoneId": {
          "Ref": "ZoneId"
        }
      }
    },
    "EcsInstance": {
      "Type": "ALIYUN::ECS::InstanceGroup",
      "Properties": {
        "SystemDiskCategory": "cloud_essd",
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "ImageId": {
          "Ref": "ImageId"
        },
        "InternetMaxBandwidthOut": 100,
        "SpotStrategy": "SpotAsPriceGo",
        "VSwitchId": {
          "Ref": "VSwitch"
        },
        "Password": {
          "Ref": "InstancePassword"
        },
        "InstanceName": "deploy_django_by_ros_ecs",
        "InstanceType": {
          "Ref": "InstanceType"
        },
        "ZoneId": {
          "Ref": "ZoneId"
        },
        "MaxAmount": 1
      }
    }
  },
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "ParameterGroups": [
        {
          "Parameters": [
            "ZoneId",
            "ImageId",
            "InstanceType",
            "InstancePassword"
          ]
        }
      ]
    }
  }
}

情境 3 :ECS(Windows/Linux)配置IPv6地址,並自動分配公網IPv6頻寬。

快速建立

ROSTemplateFormatVersion: '2015-09-01'
Mappings: {}
Parameters:
  EcsInstanceId:
    AssociationPropertyMetadata:
      Status: Running
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - UseExisted
    Default: Null
    Required: true
    Label:
      zh-cn: ECS執行個體ID
      en: ECS Instance ID
    AssociationProperty: ALIYUN::ECS::Instance::InstanceId
    Type: String
  CommonName:
    Default: config-ipv6
    Type: String
  PublicIpv6Address:
    AssociationPropertyMetadata:
      ValueLabelMapping:
        Enable:
          zh-cn: 開通IPv6公網頻寬
          en: Enable IPv6 Internet Bandwidth
        Disable:
          zh-cn: 不開通IPv6公網頻寬
          en: Disable IPv6 Internet Bandwidth
    AllowedValues:
      - Enable
      - Disable
    Type: String
    Description:
      zh-cn: 預設情況下,為ECS執行個體分配的IPv6地址僅具有私網通訊能力,若您希望IPv6地址具有公網通訊能力, 則需開通IPv6公網頻寬。請從以上選項中選擇您的配置。
      en: By default, the IPv6 address assigned to the ECS instance can be used only for  communications over private networks. To allow communications over the Internet,  you must enable IPv6 Internet bandwidth. Select your configuration  from the preceding options.
    Label:
      zh-cn: 配置IPv6公網頻寬
      en: Configure IPv6 Internet Bandwidth
  InstancePassword:
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - CreateNew
    Description:
      zh-cn: 伺服器登入密碼,長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)
      en: Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
    Confirm: true
    Default: Null
    ConstraintDescription:
      zh-cn: 長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)
      en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
    Label:
      zh-cn: 執行個體密碼
      en: Instance Password
    NoEcho: true
    AssociationProperty: ALIYUN::ECS::Instance::Password
    Type: String
  ImageId:
    AssociationPropertyMetadata:
      IsSupportCloudinit: true
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - CreateNew
      SupportedImageOwnerAlias:
        - system
    Default: aliyun_3_9_x64_20G_alibase_20231219.vhd
    Required: true
    Label:
      zh-cn: 執行個體鏡像
      en: Image of Instance
    AssociationProperty: ALIYUN::ECS::Image::ImageId
    Type: String
  InstanceSource:
    Default: CreateNew
    AssociationPropertyMetadata:
      ValueLabelMapping:
        UseExisted:
          zh-cn: 選擇已有執行個體
          en: Select Existed Instance
        CreateNew:
          zh-cn: 建立新執行個體
          en: Create New Instance
    AllowedValues:
      - CreateNew
      - UseExisted
    Type: String
    Label:
      zh-cn: 執行個體來源
      en: Instance Source
  ZoneId:
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - CreateNew
      AutoSelectFirst: true
    Default: Null
    Required: true
    Label:
      zh-cn: 可用性區域
      en: Availability Zone
    AssociationProperty: ALIYUN::ECS::Instance::ZoneId
    Type: String
  Ipv6CidrBlockNumber:
    AssociationProperty: AutoCompleteInput
    AssociationPropertyMetadata:
      Length: 2
      CharacterClasses:
        - Class: number
          min: 1
    Type: Number
  InstanceType:
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - CreateNew
      SystemDiskCategory: cloud_essd
      SpotStrategy: SpotAsPriceGo
      InstanceChargeType: PostPaid
      ZoneId: ${ZoneId}
    Default: Null
    Required: true
    Label:
      zh-cn: 執行個體類型
      en: Instance Type
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    Type: String
Outputs:
  EcsLoginAddress:
    Description:
      zh-cn: ECS登入地址。
      en: Ecs login address.
    Value:
      Fn::Sub:
        - https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs&regionId=${ALIYUN::Region}&instanceId=${InstanceId}
        - InstanceId:
            Fn::If:
              - UseExistedInstance
              - Ref: EcsInstanceId
              - Ref: EcsInstance
Description:
  zh-cn: 建立ECS執行個體並配置IPv6地址,支援新建立或現有執行個體,自動分配公網IPv6頻寬。
  en: Create ECS instances and configure IPv6 addresses, supporting both new creations and existing instances, with automatic allocation of public IPv6 bandwidth.
Conditions:
  DsIpv6Addresses.IsBodyEmpty:
    Fn::Equals:
      - ''
      - ''
  CreateInstance:
    Fn::Equals:
      - Ref: InstanceSource
      - CreateNew
  DsIpv6Gateway.IsBodyEmpty:
    Fn::Equals:
      - ''
      - ''
  UseExistedInstance:
    Fn::Equals:
      - Ref: InstanceSource
      - UseExisted
  CreateAndEnableIpv6:
    Fn::And:
      - CreateInstance
      - Fn::Equals:
          - Ref: PublicIpv6Address
          - Enable
  DsIpv6Addresses.IsRPC:
    Fn::Not:
      Fn::TransformNamespace:
        - Condition
        - DsIpv6Addresses.
        - Fn::Contains:
            - - OSS
              - FC
              - SLS
              - CS
            - VPC
  DsIpv6Gateway.IsRPC:
    Fn::Not:
      Fn::TransformNamespace:
        - Condition
        - DsIpv6Gateway.
        - Fn::Contains:
            - - OSS
              - FC
              - SLS
              - CS
            - VPC
Resources:
  DsVsw:
    Type: DATASOURCE::VPC::VSwitch
    Properties:
      VSwitchId:
        Fn::Jq:
          - First
          - .[0].VswitchId
          - Fn::GetAtt:
              - DsEcs
              - Instances
    Condition: UseExistedInstance
  DsIpv6Addresses.Execution:
    Type: ALIYUN::OOS::Execution
    Properties:
      TemplateName:
        Ref: DsIpv6Addresses.Template
    Condition: UseExistedInstance
    Metadata:
      ALIYUN::ROS::Module:
        LogicalIdHierarchy: DsIpv6Addresses
        TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
  DsIpv6Gateway.Template:
    Type: ALIYUN::OOS::Template
    Properties:
      Content:
        Fn::Str:
          Fn::If:
            - DsIpv6Gateway.IsRPC
            - Outputs:
                Result:
                  Type: List
                  Value: '{{ ExecuteAPI.Result }}'
              FormatVersion: OOS-2019-06-01
              Tasks:
                - Action: ACS::ExecuteAPI
                  Outputs:
                    Result:
                      Type: List
                      ValueSelector: .
                  Name: ExecuteAPI
                  Properties:
                    API: DescribeIpv6Gateways
                    Service: VPC
                    Parameters:
                      VpcId:
                        Fn::Jq:
                          - First
                          - .[0].VpcId
                          - Fn::GetAtt:
                              - DsEcs
                              - Instances
                    AutoPaging: true
              Description: ROS Execute API
            - Outputs:
                Result:
                  Type: List
                  Value: '{{ ExecuteAPI.Result }}'
              FormatVersion: OOS-2019-06-01
              Tasks:
                - Action: ACS::ExecuteAPI
                  Outputs:
                    Result:
                      Type: List
                      ValueSelector: .
                  Name: ExecuteAPI
                  Properties:
                    Body:
                      Fn::If:
                        - DsIpv6Gateway.IsBodyEmpty
                        - Null
                        - ''
                    Parameters:
                      VpcId:
                        Fn::Jq:
                          - First
                          - .[0].VpcId
                          - Fn::GetAtt:
                              - DsEcs
                              - Instances
                    Service: VPC
                    URI: ''
                    AutoPaging: true
                    Headers: {}
                    API: DescribeIpv6Gateways
                    Method: GET
              Description: ROS Execute API
      TemplateName:
        Fn::Sub:
          - ${__auto_generated__DsIpv6Gateway__Parameter__Prefix}-template-${ALIYUN::StackId}
          - __auto_generated__DsIpv6Gateway__Parameter__Prefix: DescribeIpv6Gateways
    Condition: UseExistedInstance
    Metadata:
      ALIYUN::ROS::Module:
        LogicalIdHierarchy: DsIpv6Gateway
        TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
  ConfigureIPv6Address:
    Type: ALIYUN::ROS::Stack
    Properties:
      TemplateBody:
        ROSTemplateFormatVersion: '2015-09-01'
        Conditions:
          Windows:
            Fn::Equals:
              - windows
              - Ref: OsType
          Linux:
            Fn::Equals:
              - linux
              - Ref: OsType
        Resources:
          WindowsCommand:
            Type: ALIYUN::ECS::RunCommand
            Properties:
              CommandContent:
                Fn::Sub: |-
                  # powershell
                  Write-Output "Start"
                  $install_dir = "C:\Windows\system32"
                  $install_path = "$install_dir\ecs-utils-ipv6.exe"

                  $Is64Bit = [Environment]::Is64BitOperatingSystem
                  Write-Output "Is64BitOperatingSystem: $Is64Bit"

                  if(-not (Test-Path -Path $install_path)){
                      # download the tool
                      if ([Environment]::Is64BitOperatingSystem) {
                          $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/64/ecs-utils-ipv6.exe' 
                      } else {
                          $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/32/ecs-utils-ipv6.exe' 
                      }
                      Write-Output "Download ecs-utils-ipv6.exe form url $tool_url"
                      Invoke-WebRequest -uri $tool_url -OutFile $install_path
                      Unblock-File $install_path
                  }

                  # run the tool
                  Write-Output "Run ecs-utils-ipv6.exe"
                  $maxRetries = 10 
                  $retryInterval = 10 
                  $retryCount = 0 

                  while ($retryCount -lt $maxRetries) {
                      try {
                          Start-Process -FilePath "$install_path" -ArgumentList "--noenterkey" -NoNewWindow
                          Write-Output "Successfully!"
                          break
                      } catch {
                          Write-Error "run failed: $($_.Exception.Message). Start retry $($retryCount + 1)"
                          Start-Sleep -Seconds $retryInterval
                          $retryCount++  
                      }
                  }

                  if ($retryCount -eq $maxRetries) {
                      Write-Error "Failed!"
                  }
              Type: RunPowerShellScript
              Sync: true
              InstanceIds:
                - Ref: InstanceId
              Timeout: 3600
            Condition: Windows
            DependsOn: WaiteWindowsReady
          WaiteWindowsReady:
            Type: ALIYUN::ROS::Sleep
            Properties:
              CreateDuration: 300
            Condition: Windows
          LinuxCommand:
            Type: ALIYUN::ECS::RunCommand
            Properties:
              CommandContent:
                Fn::Sub: |-
                  #!/bin/bash

                  # script exit code:
                  # 0 - success
                  # 1 - unsupported system
                  # 2 - network not available
                  # 3 - failed to run ecs-utils-ipv6 tool
                  # 4 - failed to modify /etc/eni_utils/eni-function

                  function unsupported_system() {
                      log_fatal 1 "Unsupported System: $1"
                  }

                  function log_info() {
                      printf "%s [INFO] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
                  }

                  function log_error() {
                      printf "%s [ERROR] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
                  }

                  function log_fatal() {
                      printf "\n========================================================================\n"
                      printf "%s [FATAL] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
                      printf "\n========================================================================\n"
                      exit $1
                  }

                  function debug_exec(){
                      local cmd="$@"
                      log_info "$cmd"
                      eval "$cmd"
                      ret=$?
                      echo ""
                      log_info "$cmd, exit code: $ret"
                      return $ret
                  }

                  function check_network_available() {
                      log_info "ping ecs-image-utils.oss-cn-hangzhou.aliyuncs.com ..."
                      if ! debug_exec ping -c 4 ecs-image-utils.oss-cn-hangzhou.aliyuncs.com; then
                          log_fatal 2 "Could not connect to https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com"
                      fi
                  }

                  function run_ipv6_tool() {
                      log_info "run ecs-utils-ipv6 tool"
                      debug_exec chmod +x ./ecs-utils-ipv6
                      
                      if ! debug_exec ./ecs-utils-ipv6; then
                          log_fatal 3 "Failed to run ecs-utils-ipv6 tool"
                      fi
                  }

                  function check_multi_eni_util() {
                      log_info "check multi-nic-util config"
                      if test -f /sbin/eni-ifscan; then
                          
                          if ! debug_exec "sed -i 's/IPV6INIT=no/IPV6INIT=yes\n        DHCPV6C=yes/g' /etc/eni_utils/eni-function"; then
                              log_fatal 4 "Failed to modify /etc/eni_utils/eni-function"
                          fi
                      fi
                  }

                  log_info "System Information:"
                  if ! lsb_release -a; then
                      unsupported_system
                  fi;
                  echo ""
                  check_network_available

                  RHEL=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/rhel/ecs-utils-ipv6
                  Debian=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/debian/ecs-utils-ipv6
                  SLES=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/sles/ecs-utils-ipv6
                  FreeBSD=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/freebsd/ecs-utils-ipv6

                  linux=$(lsb_release -a | grep "Distributor ID:" | cut -d':' -f2 | cut -d '(' -f1 | xargs echo -n)
                  case $linux in
                      CentOS|RedHat|Fedora|Aliyun|AlibabaCloud|Fedora|AnolisOS) wget --timeout=10 -q -O ecs-utils-ipv6 $RHEL ;;
                      Debian|Ubuntu) wget --timeout=10 -q -O ecs-utils-ipv6 $Debian ;; 
                      SUSE|OpenSUSE) wget --timeout=10 -q -O ecs-utils-ipv6 $SLES ;;
                      FreeBSD) wget --timeout=10 -q  -O ecs-utils-ipv6 $FreeBSD ;;
                      *) unsupported_system $linux ;;
                  esac

                  run_ipv6_tool
                  check_multi_eni_util
              Type: RunShellScript
              Sync: true
              InstanceIds:
                - Ref: InstanceId
              Timeout: 3600
            Condition: Linux
        Parameters:
          OsType:
            Default: Null
            Type: String
          InstanceId:
            Type: String
      Parameters:
        OsType:
          Fn::Jq:
            - First
            - .[0].OSType
            - Fn::GetAtt:
                - DsEcs
                - Instances
        InstanceId:
          Fn::If:
            - UseExistedInstance
            - Ref: EcsInstanceId
            - Ref: EcsInstance
    DependsOn:
      - AssignIpv6Address
  SecurityGroup:
    Type: ALIYUN::ECS::SecurityGroup
    Properties:
      SecurityGroupIngress:
        - PortRange: 3389/3389
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: '-1/-1'
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: icmp
        - PortRange: '-1/-1'
          Ipv6SourceCidrIp: '::/0'
          IpProtocol: icmpv6
      VpcId:
        Ref: Vpc
      SecurityGroupName:
        Fn::Sub: ${CommonName}-sg
    Condition: CreateInstance
  AssignIpv6Address:
    Type: ALIYUN::ROS::Stack
    Properties:
      TemplateBody:
        ROSTemplateFormatVersion: '2015-09-01'
        Conditions:
          AssignIpv6Addresses:
            Fn::Equals:
              - Null
              - Ref: Ipv6AddressId
          EnableIpv6ForVpc:
            Fn::Equals:
              - Null
              - Ref: Ipv6GatewayId
          EnableIpv6ForVsw:
            Fn::Equals:
              - true
              - Fn::Contains:
                  - - Null
                    - ''
                  - Ref: VswIpv6Address
          Ipv6InternetBandwidth:
            Fn::And:
              - Fn::Equals:
                  - Fn::If:
                      - AssignIpv6Addresses
                      - Null
                      - ''
                  - Ref: Ipv6InternetBandwidthId
              - Fn::Equals:
                  - Ref: PublicIpv6Address
                  - Enable
        Resources:
          IpV6Address:
            Type: ALIYUN::ECS::AssignIpv6Addresses
            Properties:
              Ipv6AddressCount: 1
              NetworkInterfaceId:
                Ref: NetworkInterfaceId
            Condition: AssignIpv6Addresses
            DependsOn: OpenIPv6ForVsw
          Ipv6InternetBandwidth:
            Type: ALIYUN::VPC::Ipv6InternetBandwidth
            Properties:
              InternetChargeType: PayByTraffic
              Bandwidth: 1
              Ipv6AddressId:
                Fn::If:
                  - AssignIpv6Addresses
                  - Fn::Select:
                      - 0
                      - Fn::GetAtt:
                          - IpV6Address
                          - Ipv6AddressIds
                  - Ref: Ipv6AddressId
              Ipv6GatewayId:
                Fn::If:
                  - EnableIpv6ForVpc
                  - Ref: Ipv6Gateway
                  - Ref: Ipv6GatewayId
            Condition: Ipv6InternetBandwidth
            DependsOn: Sleep
          Sleep:
            Type: ALIYUN::ROS::Sleep
            Properties:
              CreateDuration: 60
            Condition: AssignIpv6Addresses
            DependsOn: IpV6Address
          OpenIPv6ForVsw:
            Version: default
            Type: MODULE::ACS::OOS::ExecuteAPI
            Properties:
              Prefix: open-ipv6-for-vsw
              API: ModifyVSwitchAttribute
              Method: POST
              Parameters:
                Ipv6CidrBlock:
                  Ref: Ipv6CidrBlockNumber
                VSwitchId:
                  Ref: VswId
                EnableIPv6: true
              Service: VPC
            Condition: EnableIpv6ForVsw
            DependsOn: Ipv6Gateway
          Ipv6Gateway:
            Type: ALIYUN::VPC::Ipv6Gateway
            Properties:
              VpcId:
                Ref: VpcId
            Condition: EnableIpv6ForVpc
            DependsOn: OpenIPv6ForVpc
          OpenIPv6ForVpc:
            Version: default
            Type: MODULE::ACS::OOS::ExecuteAPI
            Properties:
              Prefix: open-ipv6-for-vpc
              API: ModifyVpcAttribute
              Method: POST
              Parameters:
                VpcId:
                  Ref: VpcId
                EnableIPv6: true
              Service: VPC
            Condition: EnableIpv6ForVpc
        Parameters:
          VpcId:
            Type: String
          NetworkInterfaceId:
            Type: String
          Ipv6GatewayId:
            Default: Null
            Type: String
          VswId:
            Type: String
          PublicIpv6Address:
            Default: Disable
            Type: String
          Ipv6AddressId:
            Default: Null
            Type: String
          Ipv6InternetBandwidthId:
            Default: Null
            Type: String
          Ipv6CidrBlockNumber:
            Type: Number
          VswIpv6Address:
            Type: String
      Parameters:
        VpcId:
          Fn::Jq:
            - First
            - .[0].VpcId
            - Fn::GetAtt:
                - DsEcs
                - Instances
        NetworkInterfaceId:
          Fn::Select:
            - 0
            - Fn::GetAtt:
                - DsEni
                - NetworkInterfaceIds
        Ipv6GatewayId:
          Fn::Jq:
            - First
            - .[0].Ipv6Gateways.Ipv6Gateway[0].Ipv6GatewayId
            - Fn::If:
                - UseExistedInstance
                - Fn::Select:
                    - Result
                    - Fn::GetAtt:
                        - DsIpv6Gateway.Execution
                        - Outputs
                    - Null
                - Fn::Select:
                    - not_exist
                    - {}
                    - Null
                    - invalid output(Output) of module{DsIpv6Gateway, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
        VswId:
          Fn::Jq:
            - First
            - .[0].VswitchId
            - Fn::GetAtt:
                - DsEcs
                - Instances
        PublicIpv6Address:
          Ref: PublicIpv6Address
        Ipv6AddressId:
          Fn::Jq:
            - First
            - .[0].Ipv6Addresses.Ipv6Address[0].Ipv6AddressId
            - Fn::If:
                - UseExistedInstance
                - Fn::Select:
                    - Result
                    - Fn::GetAtt:
                        - DsIpv6Addresses.Execution
                        - Outputs
                    - Null
                - Fn::Select:
                    - not_exist
                    - {}
                    - Null
                    - invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
        Ipv6InternetBandwidthId:
          Fn::Jq:
            - First
            - .[0].Ipv6Addresses.Ipv6Address[0].Ipv6InternetBandwidth.Ipv6InternetBandwidthId
            - Fn::If:
                - UseExistedInstance
                - Fn::Select:
                    - Result
                    - Fn::GetAtt:
                        - DsIpv6Addresses.Execution
                        - Outputs
                    - Null
                - Fn::Select:
                    - not_exist
                    - {}
                    - Null
                    - invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
        Ipv6CidrBlockNumber:
          Ref: Ipv6CidrBlockNumber
        VswIpv6Address:
          Fn::GetAtt:
            - DsVsw
            - Ipv6CidrBlock
    Condition: UseExistedInstance
  SecurityGroupIngress:
    Type: ALIYUN::ECS::SecurityGroupIngress
    Properties:
      IpProtocol: icmpv6
      SecurityGroupId:
        Fn::Jq:
          - First
          - .[0].SecurityGroupIds[0]
          - Fn::GetAtt:
              - DsEcs
              - Instances
      NicType: intranet
      PortRange: '-1/-1'
      Ipv6SourceCidrIp: '::/0'
    Condition: UseExistedInstance
  Ipv6InternetBandwidth:
    Type: ALIYUN::VPC::Ipv6InternetBandwidth
    Properties:
      InternetChargeType: PayByTraffic
      Bandwidth: 1
      Ipv6AddressId:
        Fn::Jq:
          - First
          - .[0][0]
          - Fn::GetAtt:
              - EcsInstance
              - Ipv6AddressIds
      Ipv6GatewayId:
        Ref: Ipv6Gateway
    Condition: CreateAndEnableIpv6
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      EnableIpv6: true
      VpcName:
        Fn::Sub: ${CommonName}-vpc
      CidrBlock: 192.168.0.0/16
    Condition: CreateInstance
  DsEcs:
    Type: DATASOURCE::ECS::Instances
    Properties:
      InstanceIds:
        - Fn::If:
            - UseExistedInstance
            - Ref: EcsInstanceId
            - Ref: EcsInstance
  DsIpv6Addresses.Template:
    Type: ALIYUN::OOS::Template
    Properties:
      Content:
        Fn::Str:
          Fn::If:
            - DsIpv6Addresses.IsRPC
            - Outputs:
                Result:
                  Type: List
                  Value: '{{ ExecuteAPI.Result }}'
              FormatVersion: OOS-2019-06-01
              Tasks:
                - Action: ACS::ExecuteAPI
                  Outputs:
                    Result:
                      Type: List
                      ValueSelector: .
                  Name: ExecuteAPI
                  Properties:
                    API: DescribeIpv6Addresses
                    Service: VPC
                    Parameters:
                      AssociatedInstanceId:
                        Ref: EcsInstanceId
                    AutoPaging: true
              Description: ROS Execute API
            - Outputs:
                Result:
                  Type: List
                  Value: '{{ ExecuteAPI.Result }}'
              FormatVersion: OOS-2019-06-01
              Tasks:
                - Action: ACS::ExecuteAPI
                  Outputs:
                    Result:
                      Type: List
                      ValueSelector: .
                  Name: ExecuteAPI
                  Properties:
                    Body:
                      Fn::If:
                        - DsIpv6Addresses.IsBodyEmpty
                        - Null
                        - ''
                    Parameters:
                      AssociatedInstanceId:
                        Ref: EcsInstanceId
                    Service: VPC
                    URI: ''
                    AutoPaging: true
                    Headers: {}
                    API: DescribeIpv6Addresses
                    Method: GET
              Description: ROS Execute API
      TemplateName:
        Fn::Sub:
          - ${__auto_generated__DsIpv6Addresses__Parameter__Prefix}-template-${ALIYUN::StackId}
          - __auto_generated__DsIpv6Addresses__Parameter__Prefix: DescribeIpv6Addresses
    Condition: UseExistedInstance
    Metadata:
      ALIYUN::ROS::Module:
        LogicalIdHierarchy: DsIpv6Addresses
        TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
  VSwitch:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      VSwitchName:
        Fn::Sub: ${CommonName}-vsw
      Ipv6CidrBlock: 0
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.0.0/24
      ZoneId:
        Ref: ZoneId
    Condition: CreateInstance
  Ipv6Gateway:
    Type: ALIYUN::VPC::Ipv6Gateway
    Properties:
      VpcId:
        Ref: Vpc
    Condition: CreateInstance
    DependsOn:
      - VSwitch
  EcsInstance:
    Type: ALIYUN::ECS::InstanceGroup
    Properties:
      SystemDiskCategory: cloud_essd
      VpcId:
        Ref: Vpc
      Ipv6AddressCount: 1
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId:
        Ref: ImageId
      InternetMaxBandwidthOut: 100
      SpotStrategy: SpotAsPriceGo
      VSwitchId:
        Ref: VSwitch
      Password:
        Ref: InstancePassword
      InstanceName:
        Fn::Sub: ${CommonName}-ecs
      InstanceType:
        Ref: InstanceType
      ZoneId:
        Ref: ZoneId
      MaxAmount: 1
    Condition: CreateInstance
  DsEni:
    Type: DATASOURCE::ECS::NetworkInterfaces
    Properties:
      InstanceId:
        Ref: EcsInstanceId
      Type: Primary
    Condition: UseExistedInstance
  DsIpv6Gateway.Execution:
    Type: ALIYUN::OOS::Execution
    Properties:
      TemplateName:
        Ref: DsIpv6Gateway.Template
    Condition: UseExistedInstance
    Metadata:
      ALIYUN::ROS::Module:
        LogicalIdHierarchy: DsIpv6Gateway
        TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
Metadata:
  ALIYUN::ROS::Interface:
    ParameterGroups:
      - Parameters:
          - InstanceSource
          - ZoneId
          - ImageId
          - InstanceType
          - InstancePassword
          - EcsInstanceId
          - PublicIpv6Address
    Hidden:
      - CommonName
      - Ipv6CidrBlockNumber
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Mappings": {},
  "Parameters": {
    "EcsInstanceId": {
      "AssociationPropertyMetadata": {
        "Status": "Running",
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "UseExisted"
            ]
          }
        }
      },
      "Default": null,
      "Required": true,
      "Label": {
        "zh-cn": "ECS執行個體ID",
        "en": "ECS Instance ID"
      },
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceId",
      "Type": "String"
    },
    "CommonName": {
      "Default": "config-ipv6",
      "Type": "String"
    },
    "PublicIpv6Address": {
      "AssociationPropertyMetadata": {
        "ValueLabelMapping": {
          "Enable": {
            "zh-cn": "開通IPv6公網頻寬",
            "en": "Enable IPv6 Internet Bandwidth"
          },
          "Disable": {
            "zh-cn": "不開通IPv6公網頻寬",
            "en": "Disable IPv6 Internet Bandwidth"
          }
        }
      },
      "AllowedValues": [
        "Enable",
        "Disable"
      ],
      "Type": "String",
      "Description": {
        "zh-cn": "預設情況下,為ECS執行個體分配的IPv6地址僅具有私網通訊能力,若您希望IPv6地址具有公網通訊能力, 則需開通IPv6公網頻寬。請從以上選項中選擇您的配置。",
        "en": "By default, the IPv6 address assigned to the ECS instance can be used only for  communications over private networks. To allow communications over the Internet,  you must enable IPv6 Internet bandwidth. Select your configuration  from the preceding options."
      },
      "Label": {
        "zh-cn": "配置IPv6公網頻寬",
        "en": "Configure IPv6 Internet Bandwidth"
      }
    },
    "InstancePassword": {
      "AssociationPropertyMetadata": {
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "CreateNew"
            ]
          }
        }
      },
      "Description": {
        "zh-cn": "伺服器登入密碼,長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)",
        "en": "Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
      },
      "Confirm": true,
      "Default": null,
      "ConstraintDescription": {
        "zh-cn": "長度8-30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符號)",
        "en": "Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
      },
      "Label": {
        "zh-cn": "執行個體密碼",
        "en": "Instance Password"
      },
      "NoEcho": true,
      "AssociationProperty": "ALIYUN::ECS::Instance::Password",
      "Type": "String"
    },
    "ImageId": {
      "AssociationPropertyMetadata": {
        "IsSupportCloudinit": true,
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "CreateNew"
            ]
          }
        },
        "SupportedImageOwnerAlias": [
          "system"
        ]
      },
      "Default": "aliyun_3_9_x64_20G_alibase_20231219.vhd",
      "Required": true,
      "Label": {
        "zh-cn": "執行個體鏡像",
        "en": "Image of Instance"
      },
      "AssociationProperty": "ALIYUN::ECS::Image::ImageId",
      "Type": "String"
    },
    "InstanceSource": {
      "Default": "CreateNew",
      "AssociationPropertyMetadata": {
        "ValueLabelMapping": {
          "UseExisted": {
            "zh-cn": "選擇已有執行個體",
            "en": "Select Existed Instance"
          },
          "CreateNew": {
            "zh-cn": "建立新執行個體",
            "en": "Create New Instance"
          }
        }
      },
      "AllowedValues": [
        "CreateNew",
        "UseExisted"
      ],
      "Type": "String",
      "Label": {
        "zh-cn": "執行個體來源",
        "en": "Instance Source"
      }
    },
    "ZoneId": {
      "AssociationPropertyMetadata": {
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "CreateNew"
            ]
          }
        },
        "AutoSelectFirst": true
      },
      "Default": null,
      "Required": true,
      "Label": {
        "zh-cn": "可用性區域",
        "en": "Availability Zone"
      },
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Type": "String"
    },
    "Ipv6CidrBlockNumber": {
      "AssociationProperty": "AutoCompleteInput",
      "AssociationPropertyMetadata": {
        "Length": 2,
        "CharacterClasses": [
          {
            "Class": "number",
            "min": 1
          }
        ]
      },
      "Type": "Number"
    },
    "InstanceType": {
      "AssociationPropertyMetadata": {
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "CreateNew"
            ]
          }
        },
        "SystemDiskCategory": "cloud_essd",
        "SpotStrategy": "SpotAsPriceGo",
        "InstanceChargeType": "PostPaid",
        "ZoneId": "${ZoneId}"
      },
      "Default": null,
      "Required": true,
      "Label": {
        "zh-cn": "執行個體類型",
        "en": "Instance Type"
      },
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "Type": "String"
    }
  },
  "Outputs": {
    "EcsLoginAddress": {
      "Description": {
        "zh-cn": "ECS登入地址。",
        "en": "Ecs login address."
      },
      "Value": {
        "Fn::Sub": [
          "https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs&regionId=${ALIYUN::Region}&instanceId=${InstanceId}",
          {
            "InstanceId": {
              "Fn::If": [
                "UseExistedInstance",
                {
                  "Ref": "EcsInstanceId"
                },
                {
                  "Ref": "EcsInstance"
                }
              ]
            }
          }
        ]
      }
    }
  },
  "Description": {
    "zh-cn": "建立ECS執行個體並配置IPv6地址,支援新建立或現有執行個體,自動分配公網IPv6頻寬。",
    "en": "Create ECS instances and configure IPv6 addresses, supporting both new creations and existing instances, with automatic allocation of public IPv6 bandwidth."
  },
  "Conditions": {
    "DsIpv6Addresses.IsBodyEmpty": {
      "Fn::Equals": [
        "",
        ""
      ]
    },
    "CreateInstance": {
      "Fn::Equals": [
        {
          "Ref": "InstanceSource"
        },
        "CreateNew"
      ]
    },
    "DsIpv6Gateway.IsBodyEmpty": {
      "Fn::Equals": [
        "",
        ""
      ]
    },
    "UseExistedInstance": {
      "Fn::Equals": [
        {
          "Ref": "InstanceSource"
        },
        "UseExisted"
      ]
    },
    "CreateAndEnableIpv6": {
      "Fn::And": [
        "CreateInstance",
        {
          "Fn::Equals": [
            {
              "Ref": "PublicIpv6Address"
            },
            "Enable"
          ]
        }
      ]
    },
    "DsIpv6Addresses.IsRPC": {
      "Fn::Not": {
        "Fn::TransformNamespace": [
          "Condition",
          "DsIpv6Addresses.",
          {
            "Fn::Contains": [
              [
                "OSS",
                "FC",
                "SLS",
                "CS"
              ],
              "VPC"
            ]
          }
        ]
      }
    },
    "DsIpv6Gateway.IsRPC": {
      "Fn::Not": {
        "Fn::TransformNamespace": [
          "Condition",
          "DsIpv6Gateway.",
          {
            "Fn::Contains": [
              [
                "OSS",
                "FC",
                "SLS",
                "CS"
              ],
              "VPC"
            ]
          }
        ]
      }
    }
  },
  "Resources": {
    "DsVsw": {
      "Type": "DATASOURCE::VPC::VSwitch",
      "Properties": {
        "VSwitchId": {
          "Fn::Jq": [
            "First",
            ".[0].VswitchId",
            {
              "Fn::GetAtt": [
                "DsEcs",
                "Instances"
              ]
            }
          ]
        }
      },
      "Condition": "UseExistedInstance"
    },
    "DsIpv6Addresses.Execution": {
      "Type": "ALIYUN::OOS::Execution",
      "Properties": {
        "TemplateName": {
          "Ref": "DsIpv6Addresses.Template"
        }
      },
      "Condition": "UseExistedInstance",
      "Metadata": {
        "ALIYUN::ROS::Module": {
          "LogicalIdHierarchy": "DsIpv6Addresses",
          "TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
        }
      }
    },
    "DsIpv6Gateway.Template": {
      "Type": "ALIYUN::OOS::Template",
      "Properties": {
        "Content": {
          "Fn::Str": {
            "Fn::If": [
              "DsIpv6Gateway.IsRPC",
              {
                "Outputs": {
                  "Result": {
                    "Type": "List",
                    "Value": "{{ ExecuteAPI.Result }}"
                  }
                },
                "FormatVersion": "OOS-2019-06-01",
                "Tasks": [
                  {
                    "Action": "ACS::ExecuteAPI",
                    "Outputs": {
                      "Result": {
                        "Type": "List",
                        "ValueSelector": "."
                      }
                    },
                    "Name": "ExecuteAPI",
                    "Properties": {
                      "API": "DescribeIpv6Gateways",
                      "Service": "VPC",
                      "Parameters": {
                        "VpcId": {
                          "Fn::Jq": [
                            "First",
                            ".[0].VpcId",
                            {
                              "Fn::GetAtt": [
                                "DsEcs",
                                "Instances"
                              ]
                            }
                          ]
                        }
                      },
                      "AutoPaging": true
                    }
                  }
                ],
                "Description": "ROS Execute API"
              },
              {
                "Outputs": {
                  "Result": {
                    "Type": "List",
                    "Value": "{{ ExecuteAPI.Result }}"
                  }
                },
                "FormatVersion": "OOS-2019-06-01",
                "Tasks": [
                  {
                    "Action": "ACS::ExecuteAPI",
                    "Outputs": {
                      "Result": {
                        "Type": "List",
                        "ValueSelector": "."
                      }
                    },
                    "Name": "ExecuteAPI",
                    "Properties": {
                      "Body": {
                        "Fn::If": [
                          "DsIpv6Gateway.IsBodyEmpty",
                          null,
                          ""
                        ]
                      },
                      "Parameters": {
                        "VpcId": {
                          "Fn::Jq": [
                            "First",
                            ".[0].VpcId",
                            {
                              "Fn::GetAtt": [
                                "DsEcs",
                                "Instances"
                              ]
                            }
                          ]
                        }
                      },
                      "Service": "VPC",
                      "URI": "",
                      "AutoPaging": true,
                      "Headers": {},
                      "API": "DescribeIpv6Gateways",
                      "Method": "GET"
                    }
                  }
                ],
                "Description": "ROS Execute API"
              }
            ]
          }
        },
        "TemplateName": {
          "Fn::Sub": [
            "${__auto_generated__DsIpv6Gateway__Parameter__Prefix}-template-${ALIYUN::StackId}",
            {
              "__auto_generated__DsIpv6Gateway__Parameter__Prefix": "DescribeIpv6Gateways"
            }
          ]
        }
      },
      "Condition": "UseExistedInstance",
      "Metadata": {
        "ALIYUN::ROS::Module": {
          "LogicalIdHierarchy": "DsIpv6Gateway",
          "TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
        }
      }
    },
    "ConfigureIPv6Address": {
      "Type": "ALIYUN::ROS::Stack",
      "Properties": {
        "TemplateBody": {
          "ROSTemplateFormatVersion": "2015-09-01",
          "Conditions": {
            "Windows": {
              "Fn::Equals": [
                "windows",
                {
                  "Ref": "OsType"
                }
              ]
            },
            "Linux": {
              "Fn::Equals": [
                "linux",
                {
                  "Ref": "OsType"
                }
              ]
            }
          },
          "Resources": {
            "WindowsCommand": {
              "Type": "ALIYUN::ECS::RunCommand",
              "Properties": {
                "CommandContent": {
                  "Fn::Sub": "# powershell\nWrite-Output \"Start\"\n$install_dir = \"C:\\Windows\\system32\"\n$install_path = \"$install_dir\\ecs-utils-ipv6.exe\"\n\n$Is64Bit = [Environment]::Is64BitOperatingSystem\nWrite-Output \"Is64BitOperatingSystem: $Is64Bit\"\n\nif(-not (Test-Path -Path $install_path)){\n    # download the tool\n    if ([Environment]::Is64BitOperatingSystem) {\n        $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/64/ecs-utils-ipv6.exe' \n    } else {\n        $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/32/ecs-utils-ipv6.exe' \n    }\n    Write-Output \"Download ecs-utils-ipv6.exe form url $tool_url\"\n    Invoke-WebRequest -uri $tool_url -OutFile $install_path\n    Unblock-File $install_path\n}\n\n# run the tool\nWrite-Output \"Run ecs-utils-ipv6.exe\"\n$maxRetries = 10 \n$retryInterval = 10 \n$retryCount = 0 \n\nwhile ($retryCount -lt $maxRetries) {\n    try {\n        Start-Process -FilePath \"$install_path\" -ArgumentList \"--noenterkey\" -NoNewWindow\n        Write-Output \"Successfully!\"\n        break\n    } catch {\n        Write-Error \"run failed: $($_.Exception.Message). Start retry $($retryCount + 1)\"\n        Start-Sleep -Seconds $retryInterval\n        $retryCount++  \n    }\n}\n\nif ($retryCount -eq $maxRetries) {\n    Write-Error \"Failed!\"\n}"
                },
                "Type": "RunPowerShellScript",
                "Sync": true,
                "InstanceIds": [
                  {
                    "Ref": "InstanceId"
                  }
                ],
                "Timeout": 3600
              },
              "Condition": "Windows",
              "DependsOn": "WaiteWindowsReady"
            },
            "WaiteWindowsReady": {
              "Type": "ALIYUN::ROS::Sleep",
              "Properties": {
                "CreateDuration": 300
              },
              "Condition": "Windows"
            },
            "LinuxCommand": {
              "Type": "ALIYUN::ECS::RunCommand",
              "Properties": {
                "CommandContent": {
                  "Fn::Sub": "#!/bin/bash\n\n# script exit code:\n# 0 - success\n# 1 - unsupported system\n# 2 - network not available\n# 3 - failed to run ecs-utils-ipv6 tool\n# 4 - failed to modify /etc/eni_utils/eni-function\n\nfunction unsupported_system() {\n    log_fatal 1 \"Unsupported System: $1\"\n}\n\nfunction log_info() {\n    printf \"%s [INFO] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n}\n\nfunction log_error() {\n    printf \"%s [ERROR] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n}\n\nfunction log_fatal() {\n    printf \"\\n========================================================================\\n\"\n    printf \"%s [FATAL] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n    printf \"\\n========================================================================\\n\"\n    exit $1\n}\n\nfunction debug_exec(){\n    local cmd=\"$@\"\n    log_info \"$cmd\"\n    eval \"$cmd\"\n    ret=$?\n    echo \"\"\n    log_info \"$cmd, exit code: $ret\"\n    return $ret\n}\n\nfunction check_network_available() {\n    log_info \"ping ecs-image-utils.oss-cn-hangzhou.aliyuncs.com ...\"\n    if ! debug_exec ping -c 4 ecs-image-utils.oss-cn-hangzhou.aliyuncs.com; then\n        log_fatal 2 \"Could not connect to https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com\"\n    fi\n}\n\nfunction run_ipv6_tool() {\n    log_info \"run ecs-utils-ipv6 tool\"\n    debug_exec chmod +x ./ecs-utils-ipv6\n    \n    if ! debug_exec ./ecs-utils-ipv6; then\n        log_fatal 3 \"Failed to run ecs-utils-ipv6 tool\"\n    fi\n}\n\nfunction check_multi_eni_util() {\n    log_info \"check multi-nic-util config\"\n    if test -f /sbin/eni-ifscan; then\n        \n        if ! debug_exec \"sed -i 's/IPV6INIT=no/IPV6INIT=yes\\n        DHCPV6C=yes/g' /etc/eni_utils/eni-function\"; then\n            log_fatal 4 \"Failed to modify /etc/eni_utils/eni-function\"\n        fi\n    fi\n}\n\nlog_info \"System Information:\"\nif ! lsb_release -a; then\n    unsupported_system\nfi;\necho \"\"\ncheck_network_available\n\nRHEL=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/rhel/ecs-utils-ipv6\nDebian=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/debian/ecs-utils-ipv6\nSLES=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/sles/ecs-utils-ipv6\nFreeBSD=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/freebsd/ecs-utils-ipv6\n\nlinux=$(lsb_release -a | grep \"Distributor ID:\" | cut -d':' -f2 | cut -d '(' -f1 | xargs echo -n)\ncase $linux in\n    CentOS|RedHat|Fedora|Aliyun|AlibabaCloud|Fedora|AnolisOS) wget --timeout=10 -q -O ecs-utils-ipv6 $RHEL ;;\n    Debian|Ubuntu) wget --timeout=10 -q -O ecs-utils-ipv6 $Debian ;; \n    SUSE|OpenSUSE) wget --timeout=10 -q -O ecs-utils-ipv6 $SLES ;;\n    FreeBSD) wget --timeout=10 -q  -O ecs-utils-ipv6 $FreeBSD ;;\n    *) unsupported_system $linux ;;\nesac\n\nrun_ipv6_tool\ncheck_multi_eni_util"
                },
                "Type": "RunShellScript",
                "Sync": true,
                "InstanceIds": [
                  {
                    "Ref": "InstanceId"
                  }
                ],
                "Timeout": 3600
              },
              "Condition": "Linux"
            }
          },
          "Parameters": {
            "OsType": {
              "Default": null,
              "Type": "String"
            },
            "InstanceId": {
              "Type": "String"
            }
          }
        },
        "Parameters": {
          "OsType": {
            "Fn::Jq": [
              "First",
              ".[0].OSType",
              {
                "Fn::GetAtt": [
                  "DsEcs",
                  "Instances"
                ]
              }
            ]
          },
          "InstanceId": {
            "Fn::If": [
              "UseExistedInstance",
              {
                "Ref": "EcsInstanceId"
              },
              {
                "Ref": "EcsInstance"
              }
            ]
          }
        }
      },
      "DependsOn": [
        "AssignIpv6Address"
      ]
    },
    "SecurityGroup": {
      "Type": "ALIYUN::ECS::SecurityGroup",
      "Properties": {
        "SecurityGroupIngress": [
          {
            "PortRange": "3389/3389",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "-1/-1",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "icmp"
          },
          {
            "PortRange": "-1/-1",
            "Ipv6SourceCidrIp": "::/0",
            "IpProtocol": "icmpv6"
          }
        ],
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupName": {
          "Fn::Sub": "${CommonName}-sg"
        }
      },
      "Condition": "CreateInstance"
    },
    "AssignIpv6Address": {
      "Type": "ALIYUN::ROS::Stack",
      "Properties": {
        "TemplateBody": {
          "ROSTemplateFormatVersion": "2015-09-01",
          "Conditions": {
            "AssignIpv6Addresses": {
              "Fn::Equals": [
                null,
                {
                  "Ref": "Ipv6AddressId"
                }
              ]
            },
            "EnableIpv6ForVpc": {
              "Fn::Equals": [
                null,
                {
                  "Ref": "Ipv6GatewayId"
                }
              ]
            },
            "EnableIpv6ForVsw": {
              "Fn::Equals": [
                true,
                {
                  "Fn::Contains": [
                    [
                      null,
                      ""
                    ],
                    {
                      "Ref": "VswIpv6Address"
                    }
                  ]
                }
              ]
            },
            "Ipv6InternetBandwidth": {
              "Fn::And": [
                {
                  "Fn::Equals": [
                    {
                      "Fn::If": [
                        "AssignIpv6Addresses",
                        null,
                        ""
                      ]
                    },
                    {
                      "Ref": "Ipv6InternetBandwidthId"
                    }
                  ]
                },
                {
                  "Fn::Equals": [
                    {
                      "Ref": "PublicIpv6Address"
                    },
                    "Enable"
                  ]
                }
              ]
            }
          },
          "Resources": {
            "IpV6Address": {
              "Type": "ALIYUN::ECS::AssignIpv6Addresses",
              "Properties": {
                "Ipv6AddressCount": 1,
                "NetworkInterfaceId": {
                  "Ref": "NetworkInterfaceId"
                }
              },
              "Condition": "AssignIpv6Addresses",
              "DependsOn": "OpenIPv6ForVsw"
            },
            "Ipv6InternetBandwidth": {
              "Type": "ALIYUN::VPC::Ipv6InternetBandwidth",
              "Properties": {
                "InternetChargeType": "PayByTraffic",
                "Bandwidth": 1,
                "Ipv6AddressId": {
                  "Fn::If": [
                    "AssignIpv6Addresses",
                    {
                      "Fn::Select": [
                        0,
                        {
                          "Fn::GetAtt": [
                            "IpV6Address",
                            "Ipv6AddressIds"
                          ]
                        }
                      ]
                    },
                    {
                      "Ref": "Ipv6AddressId"
                    }
                  ]
                },
                "Ipv6GatewayId": {
                  "Fn::If": [
                    "EnableIpv6ForVpc",
                    {
                      "Ref": "Ipv6Gateway"
                    },
                    {
                      "Ref": "Ipv6GatewayId"
                    }
                  ]
                }
              },
              "Condition": "Ipv6InternetBandwidth",
              "DependsOn": "Sleep"
            },
            "Sleep": {
              "Type": "ALIYUN::ROS::Sleep",
              "Properties": {
                "CreateDuration": 60
              },
              "Condition": "AssignIpv6Addresses",
              "DependsOn": "IpV6Address"
            },
            "OpenIPv6ForVsw": {
              "Version": "default",
              "Type": "MODULE::ACS::OOS::ExecuteAPI",
              "Properties": {
                "Prefix": "open-ipv6-for-vsw",
                "API": "ModifyVSwitchAttribute",
                "Method": "POST",
                "Parameters": {
                  "Ipv6CidrBlock": {
                    "Ref": "Ipv6CidrBlockNumber"
                  },
                  "VSwitchId": {
                    "Ref": "VswId"
                  },
                  "EnableIPv6": true
                },
                "Service": "VPC"
              },
              "Condition": "EnableIpv6ForVsw",
              "DependsOn": "Ipv6Gateway"
            },
            "Ipv6Gateway": {
              "Type": "ALIYUN::VPC::Ipv6Gateway",
              "Properties": {
                "VpcId": {
                  "Ref": "VpcId"
                }
              },
              "Condition": "EnableIpv6ForVpc",
              "DependsOn": "OpenIPv6ForVpc"
            },
            "OpenIPv6ForVpc": {
              "Version": "default",
              "Type": "MODULE::ACS::OOS::ExecuteAPI",
              "Properties": {
                "Prefix": "open-ipv6-for-vpc",
                "API": "ModifyVpcAttribute",
                "Method": "POST",
                "Parameters": {
                  "VpcId": {
                    "Ref": "VpcId"
                  },
                  "EnableIPv6": true
                },
                "Service": "VPC"
              },
              "Condition": "EnableIpv6ForVpc"
            }
          },
          "Parameters": {
            "VpcId": {
              "Type": "String"
            },
            "NetworkInterfaceId": {
              "Type": "String"
            },
            "Ipv6GatewayId": {
              "Default": null,
              "Type": "String"
            },
            "VswId": {
              "Type": "String"
            },
            "PublicIpv6Address": {
              "Default": "Disable",
              "Type": "String"
            },
            "Ipv6AddressId": {
              "Default": null,
              "Type": "String"
            },
            "Ipv6InternetBandwidthId": {
              "Default": null,
              "Type": "String"
            },
            "Ipv6CidrBlockNumber": {
              "Type": "Number"
            },
            "VswIpv6Address": {
              "Type": "String"
            }
          }
        },
        "Parameters": {
          "VpcId": {
            "Fn::Jq": [
              "First",
              ".[0].VpcId",
              {
                "Fn::GetAtt": [
                  "DsEcs",
                  "Instances"
                ]
              }
            ]
          },
          "NetworkInterfaceId": {
            "Fn::Select": [
              0,
              {
                "Fn::GetAtt": [
                  "DsEni",
                  "NetworkInterfaceIds"
                ]
              }
            ]
          },
          "Ipv6GatewayId": {
            "Fn::Jq": [
              "First",
              ".[0].Ipv6Gateways.Ipv6Gateway[0].Ipv6GatewayId",
              {
                "Fn::If": [
                  "UseExistedInstance",
                  {
                    "Fn::Select": [
                      "Result",
                      {
                        "Fn::GetAtt": [
                          "DsIpv6Gateway.Execution",
                          "Outputs"
                        ]
                      },
                      null
                    ]
                  },
                  {
                    "Fn::Select": [
                      "not_exist",
                      {},
                      null,
                      "invalid output(Output) of module{DsIpv6Gateway, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
                    ]
                  }
                ]
              }
            ]
          },
          "VswId": {
            "Fn::Jq": [
              "First",
              ".[0].VswitchId",
              {
                "Fn::GetAtt": [
                  "DsEcs",
                  "Instances"
                ]
              }
            ]
          },
          "PublicIpv6Address": {
            "Ref": "PublicIpv6Address"
          },
          "Ipv6AddressId": {
            "Fn::Jq": [
              "First",
              ".[0].Ipv6Addresses.Ipv6Address[0].Ipv6AddressId",
              {
                "Fn::If": [
                  "UseExistedInstance",
                  {
                    "Fn::Select": [
                      "Result",
                      {
                        "Fn::GetAtt": [
                          "DsIpv6Addresses.Execution",
                          "Outputs"
                        ]
                      },
                      null
                    ]
                  },
                  {
                    "Fn::Select": [
                      "not_exist",
                      {},
                      null,
                      "invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
                    ]
                  }
                ]
              }
            ]
          },
          "Ipv6InternetBandwidthId": {
            "Fn::Jq": [
              "First",
              ".[0].Ipv6Addresses.Ipv6Address[0].Ipv6InternetBandwidth.Ipv6InternetBandwidthId",
              {
                "Fn::If": [
                  "UseExistedInstance",
                  {
                    "Fn::Select": [
                      "Result",
                      {
                        "Fn::GetAtt": [
                          "DsIpv6Addresses.Execution",
                          "Outputs"
                        ]
                      },
                      null
                    ]
                  },
                  {
                    "Fn::Select": [
                      "not_exist",
                      {},
                      null,
                      "invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
                    ]
                  }
                ]
              }
            ]
          },
          "Ipv6CidrBlockNumber": {
            "Ref": "Ipv6CidrBlockNumber"
          },
          "VswIpv6Address": {
            "Fn::GetAtt": [
              "DsVsw",
              "Ipv6CidrBlock"
            ]
          }
        }
      },
      "Condition": "UseExistedInstance"
    },
    "SecurityGroupIngress": {
      "Type": "ALIYUN::ECS::SecurityGroupIngress",
      "Properties": {
        "IpProtocol": "icmpv6",
        "SecurityGroupId": {
          "Fn::Jq": [
            "First",
            ".[0].SecurityGroupIds[0]",
            {
              "Fn::GetAtt": [
                "DsEcs",
                "Instances"
              ]
            }
          ]
        },
        "NicType": "intranet",
        "PortRange": "-1/-1",
        "Ipv6SourceCidrIp": "::/0"
      },
      "Condition": "UseExistedInstance"
    },
    "Ipv6InternetBandwidth": {
      "Type": "ALIYUN::VPC::Ipv6InternetBandwidth",
      "Properties": {
        "InternetChargeType": "PayByTraffic",
        "Bandwidth": 1,
        "Ipv6AddressId": {
          "Fn::Jq": [
            "First",
            ".[0][0]",
            {
              "Fn::GetAtt": [
                "EcsInstance",
                "Ipv6AddressIds"
              ]
            }
          ]
        },
        "Ipv6GatewayId": {
          "Ref": "Ipv6Gateway"
        }
      },
      "Condition": "CreateAndEnableIpv6"
    },
    "Vpc": {
      "Type": "ALIYUN::ECS::VPC",
      "Properties": {
        "EnableIpv6": true,
        "VpcName": {
          "Fn::Sub": "${CommonName}-vpc"
        },
        "CidrBlock": "192.168.0.0/16"
      },
      "Condition": "CreateInstance"
    },
    "DsEcs": {
      "Type": "DATASOURCE::ECS::Instances",
      "Properties": {
        "InstanceIds": [
          {
            "Fn::If": [
              "UseExistedInstance",
              {
                "Ref": "EcsInstanceId"
              },
              {
                "Ref": "EcsInstance"
              }
            ]
          }
        ]
      }
    },
    "DsIpv6Addresses.Template": {
      "Type": "ALIYUN::OOS::Template",
      "Properties": {
        "Content": {
          "Fn::Str": {
            "Fn::If": [
              "DsIpv6Addresses.IsRPC",
              {
                "Outputs": {
                  "Result": {
                    "Type": "List",
                    "Value": "{{ ExecuteAPI.Result }}"
                  }
                },
                "FormatVersion": "OOS-2019-06-01",
                "Tasks": [
                  {
                    "Action": "ACS::ExecuteAPI",
                    "Outputs": {
                      "Result": {
                        "Type": "List",
                        "ValueSelector": "."
                      }
                    },
                    "Name": "ExecuteAPI",
                    "Properties": {
                      "API": "DescribeIpv6Addresses",
                      "Service": "VPC",
                      "Parameters": {
                        "AssociatedInstanceId": {
                          "Ref": "EcsInstanceId"
                        }
                      },
                      "AutoPaging": true
                    }
                  }
                ],
                "Description": "ROS Execute API"
              },
              {
                "Outputs": {
                  "Result": {
                    "Type": "List",
                    "Value": "{{ ExecuteAPI.Result }}"
                  }
                },
                "FormatVersion": "OOS-2019-06-01",
                "Tasks": [
                  {
                    "Action": "ACS::ExecuteAPI",
                    "Outputs": {
                      "Result": {
                        "Type": "List",
                        "ValueSelector": "."
                      }
                    },
                    "Name": "ExecuteAPI",
                    "Properties": {
                      "Body": {
                        "Fn::If": [
                          "DsIpv6Addresses.IsBodyEmpty",
                          null,
                          ""
                        ]
                      },
                      "Parameters": {
                        "AssociatedInstanceId": {
                          "Ref": "EcsInstanceId"
                        }
                      },
                      "Service": "VPC",
                      "URI": "",
                      "AutoPaging": true,
                      "Headers": {},
                      "API": "DescribeIpv6Addresses",
                      "Method": "GET"
                    }
                  }
                ],
                "Description": "ROS Execute API"
              }
            ]
          }
        },
        "TemplateName": {
          "Fn::Sub": [
            "${__auto_generated__DsIpv6Addresses__Parameter__Prefix}-template-${ALIYUN::StackId}",
            {
              "__auto_generated__DsIpv6Addresses__Parameter__Prefix": "DescribeIpv6Addresses"
            }
          ]
        }
      },
      "Condition": "UseExistedInstance",
      "Metadata": {
        "ALIYUN::ROS::Module": {
          "LogicalIdHierarchy": "DsIpv6Addresses",
          "TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
        }
      }
    },
    "VSwitch": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": {
          "Fn::Sub": "${CommonName}-vsw"
        },
        "Ipv6CidrBlock": 0,
        "VpcId": {
          "Ref": "Vpc"
        },
        "CidrBlock": "192.168.0.0/24",
        "ZoneId": {
          "Ref": "ZoneId"
        }
      },
      "Condition": "CreateInstance"
    },
    "Ipv6Gateway": {
      "Type": "ALIYUN::VPC::Ipv6Gateway",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        }
      },
      "Condition": "CreateInstance",
      "DependsOn": [
        "VSwitch"
      ]
    },
    "EcsInstance": {
      "Type": "ALIYUN::ECS::InstanceGroup",
      "Properties": {
        "SystemDiskCategory": "cloud_essd",
        "VpcId": {
          "Ref": "Vpc"
        },
        "Ipv6AddressCount": 1,
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "ImageId": {
          "Ref": "ImageId"
        },
        "InternetMaxBandwidthOut": 100,
        "SpotStrategy": "SpotAsPriceGo",
        "VSwitchId": {
          "Ref": "VSwitch"
        },
        "Password": {
          "Ref": "InstancePassword"
        },
        "InstanceName": {
          "Fn::Sub": "${CommonName}-ecs"
        },
        "InstanceType": {
          "Ref": "InstanceType"
        },
        "ZoneId": {
          "Ref": "ZoneId"
        },
        "MaxAmount": 1
      },
      "Condition": "CreateInstance"
    },
    "DsEni": {
      "Type": "DATASOURCE::ECS::NetworkInterfaces",
      "Properties": {
        "InstanceId": {
          "Ref": "EcsInstanceId"
        },
        "Type": "Primary"
      },
      "Condition": "UseExistedInstance"
    },
    "DsIpv6Gateway.Execution": {
      "Type": "ALIYUN::OOS::Execution",
      "Properties": {
        "TemplateName": {
          "Ref": "DsIpv6Gateway.Template"
        }
      },
      "Condition": "UseExistedInstance",
      "Metadata": {
        "ALIYUN::ROS::Module": {
          "LogicalIdHierarchy": "DsIpv6Gateway",
          "TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
        }
      }
    }
  },
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "ParameterGroups": [
        {
          "Parameters": [
            "InstanceSource",
            "ZoneId",
            "ImageId",
            "InstanceType",
            "InstancePassword",
            "EcsInstanceId",
            "PublicIpv6Address"
          ]
        }
      ],
      "Hidden": [
        "CommonName",
        "Ipv6CidrBlockNumber"
      ]
    }
  }
}

更多樣本,請參考包含此資源的公用模板。