全部产品
Search
文档中心

Resource Orchestration Service:ALIYUN::ECS::RunCommand

更新时间:Feb 07, 2026

Tipe resource ALIYUN::ECS::RunCommand mengeksekusi skrip Shell, PowerShell, atau Batch pada satu atau beberapa Instance ECS.

Sintaks

{
  "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
  }
}

Properti

Property Name

Type

Required

Updatable

Description

Constraints

Parameters

Map

No

Yes

Pasangan key-value untuk parameter kustom jika skrip memuatnya. Misalnya, jika konten skrip adalah `echo {{name}}`, tentukan `{"name":"Jack"}` menggunakan properti Parameters. Parameter kustom secara otomatis menggantikan variabel `name`, sehingga menghasilkan skrip baru yang mengeksekusi `echo Jack`.

  • Mendukung maksimal 10 parameter kustom.

  • Kunci tidak boleh berupa string kosong dan mendukung maksimal 64 karakter. Nilai dapat berupa string kosong.

  • Panjang gabungan parameter kustom dan konten skrip asli tidak boleh melebihi 16 KB setelah pengkodean Base64.

  • Himpunan nama parameter kustom harus merupakan subset dari himpunan parameter yang ditentukan saat membuat skrip.

  • Untuk parameter yang tidak ditentukan, gunakan string kosong.

Description

String

No

No

Deskripsi skrip.

Mendukung semua set karakter. Panjangnya tidak boleh melebihi 512 karakter.

Timeout

Integer

No

Yes

Batas waktu eksekusi skrip.

Unit: detik.

Nilai default: 60.

Timeout terjadi jika skrip tidak dapat dijalankan karena masalah proses, modul yang hilang, atau Cloud Assistant Agent yang tidak tersedia. Setelah timeout, proses skrip dihentikan secara paksa.

ContentEncoding

String

No

Yes

Metode pengkodean untuk konten skrip (CommandContent).

Nilai:

  • Base64 (nilai default): Pengkodean Base64.

  • PlainText: Tanpa pengkodean. Dikirim sebagai teks biasa.

Catatan

Jika Anda memasukkan nilai yang salah, sistem akan memperlakukannya sebagai Base64.

Name

String

No

No

Nama skrip.

Mendukung semua set karakter. Panjangnya tidak boleh melebihi 128 karakter.

WorkingDir

String

No

Yes

Direktori kerja untuk skrip pada Instance ECS.

Nilai default:

  • Instance Linux: /root

  • Instance Windows: C:\Windows\System32\

CommandContent

String

Yes

Yes

Konten skrip dalam bentuk teks biasa atau yang telah dikodekan Base64.

  • Konten skrip tidak boleh melebihi 16 KB setelah pengkodean Base64.

  • Jika `EnableParameter` bernilai true, aktifkan parameter kustom dalam konten skrip. Tulis parameter kustom di dalam tanda kurung kurawal ganda (`{{}}`). Spasi dan jeda baris di sekitar nama parameter dalam tanda kurung kurawal ganda (`{{}}`) diabaikan.

  • Jumlah parameter kustom tidak boleh melebihi 10. Nama parameter kustom dapat berisi huruf Inggris, angka, tanda hubung (-), dan garis bawah (_). Satu nama parameter kustom tidak boleh melebihi 64 karakter.

Type

String

Yes

Yes

Jenis bahasa skrip O&M.

Nilai:

  • RunBatScript: Skrip Bat untuk instance Windows.

  • RunPowerShellScript: Skrip PowerShell untuk instance Windows.

  • RunShellScript: Skrip Shell untuk instance Linux.

Frequency

String

No

No

Interval eksekusi untuk tugas yang dipicu otomatis.

None

EnableParameter

Boolean

No

Yes

Menunjukkan apakah skrip berisi parameter kustom.

Nilai valid:

  • true: Sertakan parameter kustom.

  • false (default): Jangan sertakan parameter kustom.

InstanceIds

List

Yes

Yes

Daftar ID Instance ECS.

Tentukan maksimal 20 Instance ECS. Instance ECS tersebut harus dalam status Berjalan.

KeepCommand

Boolean

No

No

Menunjukkan apakah skrip disimpan setelah eksekusi.

Nilai:

  • true: Simpan skrip. Anda dapat mengeksekusinya lagi menggunakan InvokeCommand. Ini akan mengonsumsi kuota untuk skrip Cloud Assistant.

  • false (nilai default): Jangan simpan skrip. Skrip akan dihapus secara otomatis setelah eksekusi dan tidak mengonsumsi kuota untuk skrip Cloud Assistant.

Sync

Boolean

No

No

Menunjukkan apakah akan menggunakan panggilan sinkron.

Nilai:

  • true: Panggilan sinkron.

  • false: Pemanggilan asinkron.

Tags

List

No

Yes

Tag.

Mendukung maksimal 20 tag. Untuk informasi selengkapnya, lihat Properti Tags.

RunAgainOn

List

No

No

Tahap untuk mengeksekusi perintah lagi.

None

WindowsPasswordName

String

No

No

Nama kata sandi untuk pengguna yang mengeksekusi perintah pada instance Windows.

Panjangnya tidak boleh melebihi 255 karakter.

Jika Anda ingin mengeksekusi perintah pada instance Windows sebagai pengguna non-default (System), masukkan parameter Username dan parameter ini. Untuk mengurangi ancaman kebocoran kata sandi, simpan kata sandi teks biasa di repositori parameter layanan orkestrasi. Di sini, cukup masukkan nama kata sandi. Untuk informasi selengkapnya, lihat Enkripsi parameter dan Konfigurasi pengguna reguler untuk mengeksekusi perintah Cloud Assistant.

Catatan

Saat mengeksekusi perintah sebagai pengguna root pada instance Linux atau pengguna System pada instance Windows, jangan masukkan parameter ini.

RepeatMode

String

No

No

Menetapkan metode eksekusi perintah.

Nilai:

  • Once: Eksekusi perintah segera.

  • Period: Eksekusi perintah pada interval terjadwal. Jika parameter ini diatur ke Period, Anda juga harus menentukan parameter Frequency.

  • NextRebootOnly: Secara otomatis mengeksekusi perintah saat instance mulai berikutnya.

  • EveryReboot: Secara otomatis mengeksekusi perintah setiap kali instance dimulai.

Nilai default:

  • Jika Anda tidak menentukan parameter Frequency, nilai default-nya adalah Once.

  • Jika Anda menentukan parameter Frequency, sistem akan memprosesnya sebagai Period, terlepas dari nilai yang Anda tetapkan.

Catatan:

  • Anda dapat memanggil StopInvocation untuk menghentikan perintah yang tertunda atau terjadwal.

  • Jika parameter ini diatur ke Period atau EveryReboot, panggil DescribeInvocationResults dan tentukan IncludeHistory=true untuk melihat riwayat eksekusi perintah terjadwal.

Launcher

String

No

No

Program bootstrap untuk eksekusi skrip.

Panjangnya tidak boleh melebihi 1 KB.

ResourceGroupId

String

No

No

ID kelompok sumber daya untuk eksekusi perintah.

Jika Anda menentukan parameter ini:

ContainerName

String

No

No

Nama Kontainer.

Catatan:

  • Jika Anda menentukan parameter ini, Cloud Assistant akan mengeksekusi skrip di dalam kontainer yang ditentukan pada instance.

  • Jika Anda menentukan parameter ini, skrip hanya berjalan pada instance Linux dengan Cloud Assistant Agent versi 2.2.3.344 atau lebih baru.

  • Jika Anda menentukan parameter ini, parameter Username dan WorkingDir yang Anda tentukan tidak berlaku. Perintah hanya dieksekusi melalui pengguna default kontainer di direktori kerja default kontainer. Untuk detailnya, lihat Eksekusi perintah di dalam kontainer menggunakan Cloud Assistant.

  • Jika Anda menentukan parameter ini, hanya skrip Shell yang didukung di Kontainer Linux. Jangan tentukan interpreter konten skrip menggunakan perintah seperti #!/usr/bin/python di awal skrip. Untuk detailnya, lihat Eksekusi perintah di dalam kontainer menggunakan Cloud Assistant.

ContainerId

String

No

No

ID Kontainer.

Hanya mendukung string heksadesimal 64-bit. Anda dapat menentukan runtime kontainer secara eksplisit menggunakan awalan seperti docker://, containerd://, atau cri-o://.

Catatan:

  • Jika Anda menentukan parameter ini, Cloud Assistant akan mengeksekusi skrip di dalam kontainer yang ditentukan pada instance.

  • Jika Anda menentukan parameter ini, skrip hanya berjalan pada instance Linux dengan Cloud Assistant Agent versi 2.2.3.344 atau lebih baru.

  • Jika Anda menentukan parameter ini, parameter Username dan WorkingDir yang Anda tentukan tidak berlaku. Perintah hanya dieksekusi melalui pengguna default kontainer di direktori kerja default kontainer. Untuk detailnya, lihat Eksekusi perintah di dalam kontainer menggunakan Cloud Assistant.

  • Jika Anda menentukan parameter ini, hanya skrip Shell yang didukung di Kontainer Linux. Jangan tentukan interpreter konten skrip menggunakan perintah seperti #!/usr/bin/python di awal skrip. Untuk detailnya, lihat Eksekusi perintah di dalam kontainer menggunakan Cloud Assistant.

Username

String

No

Yes

Username untuk mengeksekusi perintah pada Instance ECS.

Panjangnya tidak boleh melebihi 255 karakter.

  • Instance ECS Linux mengeksekusi perintah sebagai pengguna root secara default.

  • Instance ECS Windows mengeksekusi perintah sebagai pengguna System secara default.

Anda juga dapat menentukan pengguna lain yang ada pada instance untuk mengeksekusi perintah. Mengeksekusi perintah Cloud Assistant sebagai pengguna reguler lebih aman. Untuk informasi selengkapnya, lihat Konfigurasi pengguna reguler untuk mengeksekusi perintah Cloud Assistant.

Sintaks Tags

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

Properti Tags

Property Name

Type

Required

Updatable

Description

Constraints

Key

String

Yes

No

Kunci tag.

Panjangnya 1 hingga 128 karakter. Tidak boleh diawali dengan aliyun atau acs:, dan tidak boleh mengandung http:// atau https://.

Value

String

No

No

Nilai tag.

Panjangnya 0 hingga 128 karakter. Tidak boleh diawali dengan aliyun atau acs:, dan tidak boleh mengandung http:// atau https://.

Nilai kembalian

Fn::GetAtt

  • CommandId: ID skrip.

  • InvokeId: ID eksekusi skrip.

  • InvokeInstances: Daftar instance yang mengeksekusi perintah.

  • InvokeResults: Hasil eksekusi perintah.

Contoh

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"
        ]
      }
    }
  }
}

Ikhtisar UpdatePolicy

Setelah mengeksekusi skrip pada sekelompok Instance ECS menggunakan ALIYUN::ECS::RunCommand, Anda dapat menggunakan properti UpdatePolicy untuk mengontrol cara konfigurasi ECS::RunCommand diperbarui saat memperbarui konfigurasi instance tersebut secara batch. Untuk sintaksis properti UpdatePolicy, lihat bagian berikut.

Sintaks UpdatePolicy

"UpdatePolicy": {
  "RollingUpdate": Map
}

Properti UpdatePolicy

Property Name

Type

Required

Updatable

Description

Constraints

RollingUpdate

Map

No

Yes

Mengontrol strategi untuk memperbarui perintah yang ada.

Untuk detailnya, lihat Properti RollingUpdate.

Sintaks RollingUpdate

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

Properti RollingUpdate

Property Name

Type

Required

Updatable

Description

Constraints

MaxBatchSize

Integer

Yes

Yes

Jumlah Instance ECS yang mengeksekusi perintah dalam setiap batch.

Rentang nilai: 1 hingga 1000.

PauseTime

Integer

No

Yes

Waktu jeda (unit: detik) antara eksekusi perintah untuk setiap batch. Nilai default adalah 0.

Rentang nilai: 0 hingga 3600.

Skenario 1: Eksekusi RunCommand pada Instance ECS yang sudah ada.

Buat cepat

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"
                ]
            }
        }
    }
}

Setelah stack berhasil dibuat, perbarui konfigurasi Instance ECS tempat perintah dieksekusi dan konfigurasikan properti UpdatePolicy selama pembaruan tersebut.

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
        }
      }
    }
  }
}

Tetapkan MaxBatchSize ke 2. Sebelum pembaruan, InstanceIds berisi tiga Instance ECS. Setelah pembaruan, InstanceIds berisi lima Instance ECS. Selama pembaruan stack, tiga instance awal menjalani Upgrade/Downgrade dalam dua batch (2 dan 1). Sistem memproses InstanceIds awal sesuai urutan yang ditentukan. Dua instance baru mengeksekusi perintah secara bersamaan.

Skenario 2: Buat Instance ECS (Alibaba Cloud Linux 3) dan terapkan lingkungan Django.

Buat cepat

ROSTemplateFormatVersion: '2015-09-01'
Description: Deploy the Django environment.
Parameters:
  ZoneId:
    Default: Null
    AssociationProperty: ALIYUN::ECS::Instance::ZoneId
    Required: true
    Type: String
    Label: Availability Zone
  InstanceType:
    AssociationPropertyMetadata:
      SystemDiskCategory: cloud_essd
      SpotStrategy: SpotAsPriceGo
      InstanceChargeType: PostPaid
      ZoneId: ${ZoneId}
    Default: Null
    Required: true
    Label: Instance Type
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    Type: String
  InstancePassword:
    Description: Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
    Confirm: true
    Default: Null
    Type: String
    Label: Instance Password
    NoEcho: true
    AssociationProperty: ALIYUN::ECS::Instance::Password
    ConstraintDescription: Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
  ImageId:
    AssociationPropertyMetadata:
      ValueLabelMapping:
        aliyun_3_x64_20G_alibase_20240528.vhd: Alibaba Cloud Linux 3
    Default: aliyun_3_x64_20G_alibase_20240528.vhd
    Required: true
    Label: 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; # The specific port must match the port defined in your uWSGI configuration file
            }
            server {
              listen       80; # The NGINX access port
              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; # The specific directory depends on your actual deployment directory
              }
              location / {
                uwsgi_pass 127.0.0.1:8001;
                include uwsgi_params; # The specific directory depends on your actual deployment directory
                include /etc/nginx/uwsgi_params; # The specific directory depends on your actual deployment directory
                uwsgi_param UWSGI_SCRIPT iCourse.wsgi; # The specific directory depends on your actual deployment directory
                uwsgi_param UWSGI_CHDIR /iCourse; # The specific directory depends on your actual deployment directory
                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": "Deploy the Django environment.",
  "Parameters": {
    "ZoneId": {
      "Default": null,
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Required": true,
      "Type": "String",
      "Label": "Availability Zone"
    },
    "InstanceType": {
      "AssociationPropertyMetadata": {
        "SystemDiskCategory": "cloud_essd",
        "SpotStrategy": "SpotAsPriceGo",
        "InstanceChargeType": "PostPaid",
        "ZoneId": "${ZoneId}"
      },
      "Default": null,
      "Required": true,
      "Label": "Instance Type",
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "Type": "String"
    },
    "InstancePassword": {
      "Description": "Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
      "Confirm": true,
      "Default": null,
      "Type": "String",
      "Label": "Instance Password",
      "NoEcho": true,
      "AssociationProperty": "ALIYUN::ECS::Instance::Password",
      "ConstraintDescription": "Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/"
    },
    "ImageId": {
      "AssociationPropertyMetadata": {
        "ValueLabelMapping": {
          "aliyun_3_x64_20G_alibase_20240528.vhd": "Alibaba Cloud Linux 3"
        }
      },
      "Default": "aliyun_3_x64_20G_alibase_20240528.vhd",
      "Required": true,
      "Label": "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; # The specific port must match the port defined in your uWSGI configuration file\n  }\n  server {\n    listen       80; # The NGINX access port\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; # The specific directory depends on your actual deployment directory\n    }\n    location / {\n      uwsgi_pass 127.0.0.1:8001;\n      include uwsgi_params; # The specific directory depends on your actual deployment directory\n      include /etc/nginx/uwsgi_params; # The specific directory depends on your actual deployment directory\n      uwsgi_param UWSGI_SCRIPT iCourse.wsgi; # The specific directory depends on your actual deployment directory\n      uwsgi_param UWSGI_CHDIR /iCourse; # The specific directory depends on your actual deployment directory\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"
          ]
        }
      ]
    }
  }
}

Skenario 3: Konfigurasi alamat IPv6 untuk Instance ECS (Windows/Linux) dan alokasikan bandwidth Internet IPv6 publik secara otomatis.

Buat cepat

ROSTemplateFormatVersion: '2015-09-01'
Mappings: {}
Parameters:
  EcsInstanceId:
    AssociationPropertyMetadata:
      Status: Running
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - UseExisted
    Default: Null
    Required: true
    Label: ECS Instance ID
    AssociationProperty: ALIYUN::ECS::Instance::InstanceId
    Type: String
  CommonName:
    Default: config-ipv6
    Type: String
  PublicIpv6Address:
    AssociationPropertyMetadata:
      ValueLabelMapping:
        Enable: Enable IPv6 Internet Bandwidth
        Disable: Disable IPv6 Internet Bandwidth
    AllowedValues:
      - Enable
      - Disable
    Type: String
    Description: 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: Configure IPv6 Internet Bandwidth
  InstancePassword:
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - CreateNew
    Description: Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
    Confirm: true
    Default: Null
    ConstraintDescription: Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
    Label: 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: Image of Instance
    AssociationProperty: ALIYUN::ECS::Image::ImageId
    Type: String
  InstanceSource:
    Default: CreateNew
    AssociationPropertyMetadata:
      ValueLabelMapping:
        UseExisted: Select Existing Instance
        CreateNew: Create New Instance
    AllowedValues:
      - CreateNew
      - UseExisted
    Type: String
    Label: Instance Source
  ZoneId:
    AssociationPropertyMetadata:
      Visible:
        Condition:
          Fn::Equals:
            - ${InstanceSource}
            - CreateNew
      AutoSelectFirst: true
    Default: Null
    Required: true
    Label: 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: Instance Type
    AssociationProperty: ALIYUN::ECS::Instance::InstanceType
    Type: String
Outputs:
  EcsLoginAddress:
    Description: ECS logon 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: 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": "ECS Instance ID",
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceId",
      "Type": "String"
    },
    "CommonName": {
      "Default": "config-ipv6",
      "Type": "String"
    },
    "PublicIpv6Address": {
      "AssociationPropertyMetadata": {
        "ValueLabelMapping": {
          "Enable": "Enable IPv6 Internet Bandwidth",
          "Disable": "Disable IPv6 Internet Bandwidth"
        }
      },
      "AllowedValues": [
        "Enable",
        "Disable"
      ],
      "Type": "String",
      "Description": "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": "Configure IPv6 Internet Bandwidth"
    },
    "InstancePassword": {
      "AssociationPropertyMetadata": {
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "CreateNew"
            ]
          }
        }
      },
      "Description": "Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
      "Confirm": true,
      "Default": null,
      "ConstraintDescription": "Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
      "Label": "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": "Image of Instance",
      "AssociationProperty": "ALIYUN::ECS::Image::ImageId",
      "Type": "String"
    },
    "InstanceSource": {
      "Default": "CreateNew",
      "AssociationPropertyMetadata": {
        "ValueLabelMapping": {
          "UseExisted": "Select Existing Instance",
          "CreateNew": "Create New Instance"
        }
      },
      "AllowedValues": [
        "CreateNew",
        "UseExisted"
      ],
      "Type": "String",
      "Label": "Instance Source"
    },
    "ZoneId": {
      "AssociationPropertyMetadata": {
        "Visible": {
          "Condition": {
            "Fn::Equals": [
              "${InstanceSource}",
              "CreateNew"
            ]
          }
        },
        "AutoSelectFirst": true
      },
      "Default": null,
      "Required": true,
      "Label": "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": "Instance Type",
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "Type": "String"
    }
  },
  "Outputs": {
    "EcsLoginAddress": {
      "Description": "ECS logon 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": "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"
      ]
    }
  }
}

Untuk contoh lainnya, lihat templat publik yang berisi resource ini.