Todos los productos
Search
Centro de documentos

Resource Orchestration Service:ALIYUN::ECS::RunCommand

Última actualización: Sep 04, 2026

ALIYUN::ECS::RunCommand ejecuta un script de shell, PowerShell o Batch en una o más instancias ECS.

Sintaxis

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

Propiedades

Nombre de la propiedad

Tipo

Obligatorio

Actualizable

Descripción

Restricciones

Parameters

Map

No

Sí

Pares clave-valor para parámetros personalizados en el script. Por ejemplo, si el contenido del script es echo {{name}}, especifique {"name":"Jack"}. El parámetro reemplaza a name y produce echo Jack.

  • Admite un máximo de 10 parámetros personalizados.

  • Las claves no pueden ser cadenas vacías y admiten un máximo de 64 caracteres. Los valores pueden ser cadenas vacías.

  • La combinación de parámetros personalizados y contenido del script no puede superar los 16 KB después de la codificación Base64.

  • Los nombres de los parámetros personalizados deben ser un subconjunto de los parámetros definidos en el script.

  • Para los parámetros no especificados, utilice una cadena vacía.

Description

String

No

No

Descripción del script.

Todos los conjuntos de caracteres. Máximo de 512 caracteres.

Timeout

Integer

No

Sí

Tiempo de espera para la ejecución del script.

Unidad: segundos.

Valor predeterminado: 60.

Se produce un tiempo de espera cuando el script no se puede ejecutar debido a problemas de proceso, módulos faltantes o ausencia del agente de Cloud Assistant. Al agotarse el tiempo, el proceso del script finaliza forzosamente.

ContentEncoding

String

No

Sí

Método de codificación del contenido del script (CommandContent).

Valores:

  • Base64 (valor predeterminado): codificación Base64.

  • PlainText: sin codificación. Se transmite como texto plano.

Nota

Si introduce un valor incorrecto, el sistema lo trata como Base64.

Name

String

No

No

Nombre del script.

Todos los conjuntos de caracteres. Máximo de 128 caracteres.

WorkingDir

String

No

Sí

Directorio de trabajo del script en la instancia ECS.

Valores predeterminados:

  • Instancias Linux: /root

  • Instancias Windows: C:\Windows\System32\

CommandContent

String

Sí

Sí

Contenido del script en texto plano o codificado en Base64.

  • El contenido del script no puede superar los 16 KB después de la codificación Base64.

  • Si EnableParameter es true, los parámetros personalizados utilizan llaves dobles ({{}}). Los espacios y saltos de línea alrededor del nombre del parámetro dentro de {{}} se ignoran.

  • Máximo de 10 parámetros personalizados. Los nombres pueden contener letras, números, guiones (-) y guiones bajos (_), con un máximo de 64 caracteres cada uno.

Type

String

Sí

Sí

Tipo de lenguaje del script de operaciones y mantenimiento.

Valores:

  • RunBatScript: script Bat para instancias Windows.

  • RunPowerShellScript: script de PowerShell para instancias Windows.

  • RunShellScript: script de shell para instancias Linux.

Frequency

String

No

No

Intervalo de ejecución para tareas programadas.

Ninguna

EnableParameter

Boolean

No

Sí

Indica si el script utiliza parámetros personalizados.

Valores válidos:

  • true: incluye parámetros personalizados.

  • false (predeterminado): no incluye parámetros personalizados.

InstanceIds

List

Sí

Sí

Lista de ID de instancias ECS.

Especifique hasta 20 instancias ECS. Las instancias ECS deben estar en estado Running.

KeepCommand

Boolean

No

No

Indica si se conserva el script después de la ejecución.

Valores:

  • true: conserva el script para volver a ejecutarlo con InvokeCommand. Consume cuota de scripts de Cloud Assistant.

  • false (predeterminado): elimina el script después de la ejecución. No consume cuota de scripts de Cloud Assistant.

Sync

Boolean

No

No

Indica si la ejecución es síncrona.

Valores:

  • true: llamada síncrona.

  • false: invocación asíncrona.

Tags

List

No

Sí

Etiquetas.

Admite un máximo de 20 etiquetas. Para obtener más información, consulte Tags properties.

RunAgainOn

List

No

No

Etapa en la que se vuelve a ejecutar el comando.

Ninguna

WindowsPasswordName

String

No

No

Nombre de la contraseña del usuario que ejecuta comandos en instancias Windows.

La longitud no puede superar los 255 caracteres.

Para ejecutar comandos en instancias Windows como un usuario distinto al predeterminado (no System), especifique tanto Username como este parámetro. Almacene la contraseña en texto plano en el almacén de parámetros de OOS para evitar fugas y pase aquí únicamente el nombre de la contraseña. Encrypt parameters y Configure a regular user to execute Cloud Assistant commands.

Nota

Cuando ejecute comandos como usuario root en instancias Linux o como usuario System en instancias Windows, no especifique este parámetro.

RepeatMode

String

No

No

Modo de ejecución.

Valores:

  • Once: ejecuta el comando inmediatamente.

  • Period: ejecuta el comando en intervalos programados. Si este parámetro es Period, también debe especificar el parámetro Frequency.

  • NextRebootOnly: ejecuta automáticamente el comando en el siguiente inicio de la instancia.

  • EveryReboot: ejecuta automáticamente el comando cada vez que se inicia la instancia.

Valores predeterminados:

  • Si no especifica el parámetro Frequency, el valor predeterminado es Once.

  • Si especifica el parámetro Frequency, el sistema lo procesa como Period, independientemente de si establece el valor del parámetro.

Nota:

  • Llame a StopInvocation para detener comandos pendientes o programados.

  • Si este parámetro es Period o EveryReboot, llame a DescribeInvocationResults y especifique IncludeHistory=true para consultar el historial de ejecuciones de comandos programados.

Launcher

String

No

No

Programa de arranque para la ejecución del script.

La longitud no puede superar 1 KB.

ResourceGroupId

String

No

No

ID del resource group para la ejecución del comando.

Si especifica este parámetro:

  • La instancia ECS correspondiente a InstanceId debe pertenecer a este resource group.

  • También puede filtrar los resultados de ejecución de comandos por resource group. Llame a DescribeInvocations o DescribeInvocationResults.

ContainerName

String

No

No

Nombre del contenedor.

Nota:

  • Si especifica este parámetro, Cloud Assistant ejecuta el script en el contenedor especificado de la instancia.

  • Requiere instancias Linux con la versión 2.2.3.344 o posterior del agente de Cloud Assistant.

  • Si especifica este parámetro, Cloud Assistant ejecuta el script en el contenedor indicado. Los parámetros Username y WorkingDir no surten efecto. Los comandos se ejecutan como el usuario predeterminado del contenedor en el directorio de trabajo predeterminado. Execute commands in containers using Cloud Assistant.

  • Si especifica este parámetro, solo se admiten scripts de shell en contenedores Linux. No agregue un intérprete de scripts como #!/usr/bin/python al inicio. Execute commands in containers using Cloud Assistant.

ContainerId

String

No

No

ID del contenedor.

Solo admite cadenas hexadecimales de 64 bits. Puede especificar explícitamente el entorno de ejecución del contenedor mediante prefijos como docker://, containerd:// o cri-o://.

Nota:

  • Si especifica este parámetro, Cloud Assistant ejecuta el script en el contenedor especificado de la instancia.

  • Requiere instancias Linux con la versión 2.2.3.344 o posterior del agente de Cloud Assistant.

  • Si especifica este parámetro, Cloud Assistant ejecuta el script en el contenedor indicado. Los parámetros Username y WorkingDir no surten efecto. Los comandos se ejecutan como el usuario predeterminado del contenedor en el directorio de trabajo predeterminado. Execute commands in containers using Cloud Assistant.

  • Si especifica este parámetro, solo se admiten scripts de shell en contenedores Linux. No agregue un intérprete de scripts como #!/usr/bin/python al inicio. Execute commands in containers using Cloud Assistant.

Username

String

No

Sí

Nombre de usuario para ejecutar comandos en la instancia ECS.

La longitud no puede superar los 255 caracteres.

  • Las instancias ECS de Linux ejecutan comandos como usuario root de forma predeterminada.

  • Las instancias ECS de Windows ejecutan comandos como usuario System de forma predeterminada.

También puede especificar otros usuarios existentes en la instancia para ejecutar comandos. Ejecutar comandos de Cloud Assistant como usuario normal es más seguro. Configure a regular user to execute Cloud Assistant commands.

Sintaxis de Tags

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

Propiedades de Tags

Nombre de la propiedad

Tipo

Obligatorio

Actualizable

Descripción

Restricciones

Key

String

Sí

No

Clave de la etiqueta.

La longitud es de 1 a 128 caracteres. No puede comenzar con aliyun ni con acs:, y no puede contener http:// ni https://.

Value

String

No

No

Valor de la etiqueta.

La longitud es de 0 a 128 caracteres. No puede comenzar con aliyun ni con acs:, y no puede contener http:// ni https://.

Valores de retorno

Fn::GetAtt

  • CommandId: ID del script.

  • InvokeId: ID de la ejecución del script.

  • InvokeInstances: lista de instancias que ejecutaron el comando.

  • InvokeResults: resultados de la ejecución del comando.

Ejemplos

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

Descripción general de UpdatePolicy

Después de ejecutar un script en instancias ECS mediante ALIYUN::ECS::RunCommand, utilice UpdatePolicy para controlar cómo se actualiza la configuración del comando durante las actualizaciones por lotes de instancias.

Sintaxis de UpdatePolicy

"UpdatePolicy": {
  "RollingUpdate": Map
}

Propiedades de UpdatePolicy

Nombre de la propiedad

Tipo

Obligatorio

Actualizable

Descripción

Restricciones

RollingUpdate

Map

No

Sí

Controla la estrategia para actualizar comandos existentes.

Para obtener más detalles, consulte RollingUpdate properties.

Sintaxis de RollingUpdate

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

Propiedades de RollingUpdate

Nombre de la propiedad

Tipo

Obligatorio

Actualizable

Descripción

Restricciones

MaxBatchSize

Integer

Sí

Sí

Número de instancias ECS por lote para la ejecución del comando.

Rango de valores: de 1 a 1000.

PauseTime

Integer

No

Sí

Tiempo de pausa (en segundos) entre lotes. Valor predeterminado: 0.

Rango de valores: de 0 a 3600.

Escenario 1: ejecutar RunCommand en instancias ECS existentes.

Creación rápida

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

Después de crear la pila, actualice las configuraciones de las instancias ECS. Configure la propiedad UpdatePolicy durante la actualización.

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

Establezca MaxBatchSize en 2. Antes de la actualización, InstanceIds contiene tres instancias ECS. Después de la actualización, InstanceIds contiene cinco instancias. Durante la actualización de la pila, las tres instancias originales pasan por Upgrade/Downgrade en dos lotes (2 y 1), procesadas en el orden listado. Las dos nuevas instancias ejecutan el comando simultáneamente.

Escenario 2: crear una instancia ECS (Alibaba Cloud Linux 3) y desplegar un entorno Django.

Creación rápida

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

Escenario 3: configurar direcciones IPv6 para instancias ECS (Windows/Linux) y asignar automáticamente ancho de banda IPv6 de Internet.

Creación rápida

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

Para obtener más ejemplos, consulte las plantillas públicas que contienen este recurso.