Tipe resource ALIYUN::ECS::RunCommand mengeksekusi skrip Shell, PowerShell, atau Batch pada satu atau beberapa Instance ECS.
Sintaks
{
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"Parameters": Map,
"Description": String,
"Timeout": Integer,
"ContentEncoding": String,
"Name": String,
"WorkingDir": String,
"CommandContent": String,
"Type": String,
"Frequency": String,
"EnableParameter": Boolean,
"InstanceIds": List,
"KeepCommand": Boolean,
"Sync": Boolean,
"Tags": List,
"RunAgainOn": List,
"WindowsPasswordName": String,
"RepeatMode": String,
"ResourceGroupId": String,
"Launcher": String,
"ContainerName": String,
"ContainerId": String,
"Username": String
}
}
Properti
|
Property Name |
Type |
Required |
Updatable |
Description |
Constraints |
|
Parameters |
Map |
No |
Yes |
Pasangan key-value untuk parameter kustom jika skrip memuatnya. Misalnya, jika konten skrip adalah `echo {{name}}`, tentukan `{"name":"Jack"}` menggunakan properti Parameters. Parameter kustom secara otomatis menggantikan variabel `name`, sehingga menghasilkan skrip baru yang mengeksekusi `echo Jack`. |
|
|
Description |
String |
No |
No |
Deskripsi skrip. |
Mendukung semua set karakter. Panjangnya tidak boleh melebihi 512 karakter. |
|
Timeout |
Integer |
No |
Yes |
Batas waktu eksekusi skrip. |
Unit: detik. Nilai default: 60. Timeout terjadi jika skrip tidak dapat dijalankan karena masalah proses, modul yang hilang, atau Cloud Assistant Agent yang tidak tersedia. Setelah timeout, proses skrip dihentikan secara paksa. |
|
ContentEncoding |
String |
No |
Yes |
Metode pengkodean untuk konten skrip (CommandContent). |
Nilai:
Catatan
Jika Anda memasukkan nilai yang salah, sistem akan memperlakukannya sebagai Base64. |
|
Name |
String |
No |
No |
Nama skrip. |
Mendukung semua set karakter. Panjangnya tidak boleh melebihi 128 karakter. |
|
WorkingDir |
String |
No |
Yes |
Direktori kerja untuk skrip pada Instance ECS. |
Nilai default:
|
|
CommandContent |
String |
Yes |
Yes |
Konten skrip dalam bentuk teks biasa atau yang telah dikodekan Base64. |
|
|
Type |
String |
Yes |
Yes |
Jenis bahasa skrip O&M. |
Nilai:
|
|
Frequency |
String |
No |
No |
Interval eksekusi untuk tugas yang dipicu otomatis. |
None |
|
EnableParameter |
Boolean |
No |
Yes |
Menunjukkan apakah skrip berisi parameter kustom. |
Nilai valid:
|
|
InstanceIds |
List |
Yes |
Yes |
Daftar ID Instance ECS. |
Tentukan maksimal 20 Instance ECS. Instance ECS tersebut harus dalam status Berjalan. |
|
KeepCommand |
Boolean |
No |
No |
Menunjukkan apakah skrip disimpan setelah eksekusi. |
Nilai:
|
|
Sync |
Boolean |
No |
No |
Menunjukkan apakah akan menggunakan panggilan sinkron. |
Nilai:
|
|
Tags |
List |
No |
Yes |
Tag. |
Mendukung maksimal 20 tag. Untuk informasi selengkapnya, lihat Properti Tags. |
|
RunAgainOn |
List |
No |
No |
Tahap untuk mengeksekusi perintah lagi. |
None |
|
WindowsPasswordName |
String |
No |
No |
Nama kata sandi untuk pengguna yang mengeksekusi perintah pada instance Windows. |
Panjangnya tidak boleh melebihi 255 karakter. Jika Anda ingin mengeksekusi perintah pada instance Windows sebagai pengguna non-default (System), masukkan parameter Catatan
Saat mengeksekusi perintah sebagai pengguna root pada instance Linux atau pengguna System pada instance Windows, jangan masukkan parameter ini. |
|
RepeatMode |
String |
No |
No |
Menetapkan metode eksekusi perintah. |
Nilai:
Nilai default:
Catatan:
|
|
Launcher |
String |
No |
No |
Program bootstrap untuk eksekusi skrip. |
Panjangnya tidak boleh melebihi 1 KB. |
|
ResourceGroupId |
String |
No |
No |
ID kelompok sumber daya untuk eksekusi perintah. |
Jika Anda menentukan parameter ini:
|
|
ContainerName |
String |
No |
No |
Nama Kontainer. |
Catatan:
|
|
ContainerId |
String |
No |
No |
ID Kontainer. |
Hanya mendukung string heksadesimal 64-bit. Anda dapat menentukan runtime kontainer secara eksplisit menggunakan awalan seperti Catatan:
|
|
Username |
String |
No |
Yes |
Username untuk mengeksekusi perintah pada Instance ECS. |
Panjangnya tidak boleh melebihi 255 karakter.
Anda juga dapat menentukan pengguna lain yang ada pada instance untuk mengeksekusi perintah. Mengeksekusi perintah Cloud Assistant sebagai pengguna reguler lebih aman. Untuk informasi selengkapnya, lihat Konfigurasi pengguna reguler untuk mengeksekusi perintah Cloud Assistant. |
Sintaks Tags
"Tags": [
{
"Key": String,
"Value": String
}
]
Properti Tags
|
Property Name |
Type |
Required |
Updatable |
Description |
Constraints |
|
Key |
String |
Yes |
No |
Kunci tag. |
Panjangnya 1 hingga 128 karakter. Tidak boleh diawali dengan |
|
Value |
String |
No |
No |
Nilai tag. |
Panjangnya 0 hingga 128 karakter. Tidak boleh diawali dengan |
Nilai kembalian
Fn::GetAtt
-
CommandId: ID skrip.
-
InvokeId: ID eksekusi skrip.
-
InvokeInstances: Daftar instance yang mengeksekusi perintah.
-
InvokeResults: Hasil eksekusi perintah.
Contoh
ROSTemplateFormatVersion: '2015-09-01'
Parameters:
InstanceId:
Type: String
AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Resources:
RunCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent:
Fn::Sub:
|
#!/bin/sh
yum install -y tree
Type: RunShellScript
InstanceIds:
- Ref: InstanceId
Outputs:
CommandId:
Description: The id of command created.
Value:
Fn::GetAtt:
- RunCommand
- CommandId
InvokeId:
Description: The invoke id of command.
Value:
Fn::GetAtt:
- RunCommand
- InvokeId
{
"ROSTemplateFormatVersion": "2015-09-01",
"Parameters": {
"InstanceId": {
"Type": "String",
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceId"
}
},
"Resources": {
"RunCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": {
"Fn::Sub":
"#!/bin/sh\nyum install -y tree\n"
},
"Type": "RunShellScript",
"InstanceIds": [
{
"Ref": "InstanceId"
}
]
}
}
},
"Outputs": {
"CommandId": {
"Description": "The id of command created.",
"Value": {
"Fn::GetAtt": [
"RunCommand",
"CommandId"
]
}
},
"InvokeId": {
"Description": "The invoke id of command.",
"Value": {
"Fn::GetAtt": [
"RunCommand",
"InvokeId"
]
}
}
}
}Ikhtisar UpdatePolicy
Setelah mengeksekusi skrip pada sekelompok Instance ECS menggunakan ALIYUN::ECS::RunCommand, Anda dapat menggunakan properti UpdatePolicy untuk mengontrol cara konfigurasi ECS::RunCommand diperbarui saat memperbarui konfigurasi instance tersebut secara batch. Untuk sintaksis properti UpdatePolicy, lihat bagian berikut.
Sintaks UpdatePolicy
"UpdatePolicy": {
"RollingUpdate": Map
}
Properti UpdatePolicy
|
Property Name |
Type |
Required |
Updatable |
Description |
Constraints |
|
RollingUpdate |
Map |
No |
Yes |
Mengontrol strategi untuk memperbarui perintah yang ada. |
Untuk detailnya, lihat Properti RollingUpdate. |
Sintaks RollingUpdate
"RollingUpdate": {
"MaxBatchSize": Integer,
"PauseTime": Integer
}
Properti RollingUpdate
|
Property Name |
Type |
Required |
Updatable |
Description |
Constraints |
|
MaxBatchSize |
Integer |
Yes |
Yes |
Jumlah Instance ECS yang mengeksekusi perintah dalam setiap batch. |
Rentang nilai: 1 hingga 1000. |
|
PauseTime |
Integer |
No |
Yes |
Waktu jeda (unit: detik) antara eksekusi perintah untuk setiap batch. Nilai default adalah 0. |
Rentang nilai: 0 hingga 3600. |
Skenario 1: Eksekusi RunCommand pada Instance ECS yang sudah ada.
ROSTemplateFormatVersion: '2015-09-01'
Resources:
RunCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent: xxx
Type: RunShellScript
Sync: true
InstanceIds:
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
{
"ROSTemplateFormatVersion": "2015-09-01",
"Resources": {
"RunCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": "xxx",
"Type": "RunShellScript",
"Sync": true,
"InstanceIds": [
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx"
]
}
}
}
}Setelah stack berhasil dibuat, perbarui konfigurasi Instance ECS tempat perintah dieksekusi dan konfigurasikan properti UpdatePolicy selama pembaruan tersebut.
ROSTemplateFormatVersion: '2015-09-01'
Resources:
RunCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent: xxx
Type: RunShellScript
Sync: true
InstanceIds:
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
UpdatePolicy:
RollingUpdate:
MaxBatchSize: 2
PauseTime: 10
{
"ROSTemplateFormatVersion": "2015-09-01",
"Resources": {
"RunCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": "xxx",
"Type": "RunShellScript",
"Sync": true,
"InstanceIds": [
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx"
]
},
"UpdatePolicy": {
"RollingUpdate": {
"MaxBatchSize": 2,
"PauseTime": 10
}
}
}
}
}Tetapkan MaxBatchSize ke 2. Sebelum pembaruan, InstanceIds berisi tiga Instance ECS. Setelah pembaruan, InstanceIds berisi lima Instance ECS. Selama pembaruan stack, tiga instance awal menjalani Upgrade/Downgrade dalam dua batch (2 dan 1). Sistem memproses InstanceIds awal sesuai urutan yang ditentukan. Dua instance baru mengeksekusi perintah secara bersamaan.
Skenario 2: Buat Instance ECS (Alibaba Cloud Linux 3) dan terapkan lingkungan Django.
ROSTemplateFormatVersion: '2015-09-01'
Description: Deploy the Django environment.
Parameters:
ZoneId:
Default: Null
AssociationProperty: ALIYUN::ECS::Instance::ZoneId
Required: true
Type: String
Label: Availability Zone
InstanceType:
AssociationPropertyMetadata:
SystemDiskCategory: cloud_essd
SpotStrategy: SpotAsPriceGo
InstanceChargeType: PostPaid
ZoneId: ${ZoneId}
Default: Null
Required: true
Label: Instance Type
AssociationProperty: ALIYUN::ECS::Instance::InstanceType
Type: String
InstancePassword:
Description: Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
Confirm: true
Default: Null
Type: String
Label: Instance Password
NoEcho: true
AssociationProperty: ALIYUN::ECS::Instance::Password
ConstraintDescription: Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
ImageId:
AssociationPropertyMetadata:
ValueLabelMapping:
aliyun_3_x64_20G_alibase_20240528.vhd: Alibaba Cloud Linux 3
Default: aliyun_3_x64_20G_alibase_20240528.vhd
Required: true
Label: Image of Instance
AllowedValues:
- aliyun_3_x64_20G_alibase_20240528.vhd
Type: String
Outputs: {}
Conditions: {}
Resources:
SecurityGroupIngress_80:
Type: ALIYUN::ECS::SecurityGroupIngress
Properties:
IpProtocol: tcp
SecurityGroupId:
Ref: SecurityGroup
NicType: intranet
SourceCidrIp: 0.0.0.0/0
PortRange: 80/80
SecurityGroup:
Type: ALIYUN::ECS::SecurityGroup
Properties:
SecurityGroupIngress:
- PortRange: 80/80
SourceCidrIp: 0.0.0.0/0
IpProtocol: tcp
- PortRange: '-1/-1'
SourceCidrIp: 0.0.0.0/0
IpProtocol: icmp
VpcId:
Ref: Vpc
SecurityGroupName: deploy_django_by_ros_sg
Vpc:
Type: ALIYUN::ECS::VPC
Properties:
VpcName: deploy_django_by_ros_vpc
CidrBlock: 192.168.0.0/16
DeployDjango:
Type: ALIYUN::ECS::RunCommand
Properties:
Type: RunShellScript
CommandContent:
Fn::Sub: |-
#!/bin/bash
sudo yum -y install nginx python3-devel.x86_64
sudo pip3 install Django uwsgi
sudo mkdir /home/myblog && cd /home/myblog
sudo /usr/local/bin/django-admin.py startproject uwsgi_project
sudo sed -i 's/ALLOWED_HOSTS = \[\]/ALLOWED_HOSTS = \["*"\]/g' /home/myblog/uwsgi_project/uwsgi_project/settings.py
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sudo mv /etc/uwsgi.ini /etc/uwsgi.ini.bak
cat << "EOF" > /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
upstream django {
server 127.0.0.1:8001; # The specific port must match the port defined in your uWSGI configuration file
}
server {
listen 80; # The NGINX access port
server_name test;
charset utf-8;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location /static {
autoindex on;
alias /home/myblog/uwsgi_project/uwsgi_project/static; # The specific directory depends on your actual deployment directory
}
location / {
uwsgi_pass 127.0.0.1:8001;
include uwsgi_params; # The specific directory depends on your actual deployment directory
include /etc/nginx/uwsgi_params; # The specific directory depends on your actual deployment directory
uwsgi_param UWSGI_SCRIPT iCourse.wsgi; # The specific directory depends on your actual deployment directory
uwsgi_param UWSGI_CHDIR /iCourse; # The specific directory depends on your actual deployment directory
index index.html index.htm;
client_max_body_size 35m;
index index.html index.htm;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
EOF
cat << "EOF" > /etc/uwsgi.ini
[uwsgi]
socket = 127.0.0.1:8001
chdir = /home/myblog/uwsgi_project/
wsgi-file = uwsgi_project/wsgi.py
processes = 4
threads = 2
vacuum = true
buffer-size = 65536
EOF
cat << "EOF" > /etc/systemd/system/uwsgi.service
[Unit]
Description=uwsgi service
After=network.target
[Service]
Type=simple
User=nginx
Group=nginx
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi.ini
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable nginx.service
sudo systemctl restart nginx.service
sudo systemctl enable uwsgi.service
sudo systemctl restart uwsgi.service
Sync: true
InstanceIds:
- Ref: EcsInstance
Timeout: 3600
VSwitch:
Type: ALIYUN::ECS::VSwitch
Properties:
VSwitchName: deploy_django_by_ros_vsw
VpcId:
Ref: Vpc
CidrBlock: 192.168.0.0/24
ZoneId:
Ref: ZoneId
EcsInstance:
Type: ALIYUN::ECS::InstanceGroup
Properties:
SystemDiskCategory: cloud_essd
VpcId:
Ref: Vpc
SecurityGroupId:
Ref: SecurityGroup
ImageId:
Ref: ImageId
InternetMaxBandwidthOut: 100
SpotStrategy: SpotAsPriceGo
VSwitchId:
Ref: VSwitch
Password:
Ref: InstancePassword
InstanceName: deploy_django_by_ros_ecs
InstanceType:
Ref: InstanceType
ZoneId:
Ref: ZoneId
MaxAmount: 1
Metadata:
ALIYUN::ROS::Interface:
ParameterGroups:
- Parameters:
- ZoneId
- ImageId
- InstanceType
- InstancePassword
{
"ROSTemplateFormatVersion": "2015-09-01",
"Description": "Deploy the Django environment.",
"Parameters": {
"ZoneId": {
"Default": null,
"AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
"Required": true,
"Type": "String",
"Label": "Availability Zone"
},
"InstanceType": {
"AssociationPropertyMetadata": {
"SystemDiskCategory": "cloud_essd",
"SpotStrategy": "SpotAsPriceGo",
"InstanceChargeType": "PostPaid",
"ZoneId": "${ZoneId}"
},
"Default": null,
"Required": true,
"Label": "Instance Type",
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
"Type": "String"
},
"InstancePassword": {
"Description": "Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
"Confirm": true,
"Default": null,
"Type": "String",
"Label": "Instance Password",
"NoEcho": true,
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"ConstraintDescription": "Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/"
},
"ImageId": {
"AssociationPropertyMetadata": {
"ValueLabelMapping": {
"aliyun_3_x64_20G_alibase_20240528.vhd": "Alibaba Cloud Linux 3"
}
},
"Default": "aliyun_3_x64_20G_alibase_20240528.vhd",
"Required": true,
"Label": "Image of Instance",
"AllowedValues": [
"aliyun_3_x64_20G_alibase_20240528.vhd"
],
"Type": "String"
}
},
"Outputs": {},
"Conditions": {},
"Resources": {
"SecurityGroupIngress_80": {
"Type": "ALIYUN::ECS::SecurityGroupIngress",
"Properties": {
"IpProtocol": "tcp",
"SecurityGroupId": {
"Ref": "SecurityGroup"
},
"NicType": "intranet",
"SourceCidrIp": "0.0.0.0/0",
"PortRange": "80/80"
}
},
"SecurityGroup": {
"Type": "ALIYUN::ECS::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [
{
"PortRange": "80/80",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "tcp"
},
{
"PortRange": "-1/-1",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "icmp"
}
],
"VpcId": {
"Ref": "Vpc"
},
"SecurityGroupName": "deploy_django_by_ros_sg"
}
},
"Vpc": {
"Type": "ALIYUN::ECS::VPC",
"Properties": {
"VpcName": "deploy_django_by_ros_vpc",
"CidrBlock": "192.168.0.0/16"
}
},
"DeployDjango": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"Type": "RunShellScript",
"CommandContent": {
"Fn::Sub": "#!/bin/bash\nsudo yum -y install nginx python3-devel.x86_64\n\n\nsudo pip3 install Django uwsgi\nsudo mkdir /home/myblog && cd /home/myblog\n\nsudo /usr/local/bin/django-admin.py startproject uwsgi_project\n\nsudo sed -i 's/ALLOWED_HOSTS = \\[\\]/ALLOWED_HOSTS = \\[\"*\"\\]/g' /home/myblog/uwsgi_project/uwsgi_project/settings.py\nsudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak\nsudo mv /etc/uwsgi.ini /etc/uwsgi.ini.bak\n\ncat << \"EOF\" > /etc/nginx/nginx.conf\nuser nginx;\nworker_processes auto;\nerror_log /var/log/nginx/error.log;\npid /run/nginx.pid;\n# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.\ninclude /usr/share/nginx/modules/*.conf;\nevents {\n worker_connections 1024;\n}\nhttp {\n log_format main '$remote_addr - $remote_user [$time_local] \"$request\" '\n '$status $body_bytes_sent \"$http_referer\" '\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n access_log /var/log/nginx/access.log main;\n sendfile on;\n tcp_nopush on;\n tcp_nodelay on;\n keepalive_timeout 65;\n types_hash_max_size 4096;\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n # Load modular configuration files from the /etc/nginx/conf.d directory.\n # See http://nginx.org/en/docs/ngx_core_module.html#include\n # for more information.\n include /etc/nginx/conf.d/*.conf;\n upstream django {\n server 127.0.0.1:8001; # The specific port must match the port defined in your uWSGI configuration file\n }\n server {\n listen 80; # The NGINX access port\n server_name test;\n charset utf-8;\n # Load configuration files for the default server block.\n include /etc/nginx/default.d/*.conf;\n location /static {\n autoindex on;\n alias /home/myblog/uwsgi_project/uwsgi_project/static; # The specific directory depends on your actual deployment directory\n }\n location / {\n uwsgi_pass 127.0.0.1:8001;\n include uwsgi_params; # The specific directory depends on your actual deployment directory\n include /etc/nginx/uwsgi_params; # The specific directory depends on your actual deployment directory\n uwsgi_param UWSGI_SCRIPT iCourse.wsgi; # The specific directory depends on your actual deployment directory\n uwsgi_param UWSGI_CHDIR /iCourse; # The specific directory depends on your actual deployment directory\n index index.html index.htm;\n client_max_body_size 35m;\n index index.html index.htm;\n }\n error_page 404 /404.html;\n location = /40x.html {\n }\n error_page 500 502 503 504 /50x.html;\n location = /50x.html {\n }\n }\n} \nEOF\n\ncat << \"EOF\" > /etc/uwsgi.ini\n[uwsgi]\nsocket = 127.0.0.1:8001\nchdir = /home/myblog/uwsgi_project/\nwsgi-file = uwsgi_project/wsgi.py\nprocesses = 4\nthreads = 2\nvacuum = true\nbuffer-size = 65536\nEOF\n\ncat << \"EOF\" > /etc/systemd/system/uwsgi.service\n[Unit]\nDescription=uwsgi service\nAfter=network.target\n[Service]\nType=simple\nUser=nginx\nGroup=nginx\nExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi.ini\n[Install]\nWantedBy=multi-user.target\nEOF\nsudo systemctl daemon-reload\nsudo systemctl enable nginx.service\nsudo systemctl restart nginx.service\nsudo systemctl enable uwsgi.service\nsudo systemctl restart uwsgi.service"
},
"Sync": true,
"InstanceIds": [
{
"Ref": "EcsInstance"
}
],
"Timeout": 3600
}
},
"VSwitch": {
"Type": "ALIYUN::ECS::VSwitch",
"Properties": {
"VSwitchName": "deploy_django_by_ros_vsw",
"VpcId": {
"Ref": "Vpc"
},
"CidrBlock": "192.168.0.0/24",
"ZoneId": {
"Ref": "ZoneId"
}
}
},
"EcsInstance": {
"Type": "ALIYUN::ECS::InstanceGroup",
"Properties": {
"SystemDiskCategory": "cloud_essd",
"VpcId": {
"Ref": "Vpc"
},
"SecurityGroupId": {
"Ref": "SecurityGroup"
},
"ImageId": {
"Ref": "ImageId"
},
"InternetMaxBandwidthOut": 100,
"SpotStrategy": "SpotAsPriceGo",
"VSwitchId": {
"Ref": "VSwitch"
},
"Password": {
"Ref": "InstancePassword"
},
"InstanceName": "deploy_django_by_ros_ecs",
"InstanceType": {
"Ref": "InstanceType"
},
"ZoneId": {
"Ref": "ZoneId"
},
"MaxAmount": 1
}
}
},
"Metadata": {
"ALIYUN::ROS::Interface": {
"ParameterGroups": [
{
"Parameters": [
"ZoneId",
"ImageId",
"InstanceType",
"InstancePassword"
]
}
]
}
}
}Skenario 3: Konfigurasi alamat IPv6 untuk Instance ECS (Windows/Linux) dan alokasikan bandwidth Internet IPv6 publik secara otomatis.
ROSTemplateFormatVersion: '2015-09-01'
Mappings: {}
Parameters:
EcsInstanceId:
AssociationPropertyMetadata:
Status: Running
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- UseExisted
Default: Null
Required: true
Label: ECS Instance ID
AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Type: String
CommonName:
Default: config-ipv6
Type: String
PublicIpv6Address:
AssociationPropertyMetadata:
ValueLabelMapping:
Enable: Enable IPv6 Internet Bandwidth
Disable: Disable IPv6 Internet Bandwidth
AllowedValues:
- Enable
- Disable
Type: String
Description: By default, the IPv6 address assigned to the ECS instance can be used only for communications over private networks. To allow communications over the Internet, you must enable IPv6 Internet bandwidth. Select your configuration from the preceding options.
Label: Configure IPv6 Internet Bandwidth
InstancePassword:
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
Description: Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
Confirm: true
Default: Null
ConstraintDescription: Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
Label: Instance Password
NoEcho: true
AssociationProperty: ALIYUN::ECS::Instance::Password
Type: String
ImageId:
AssociationPropertyMetadata:
IsSupportCloudinit: true
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
SupportedImageOwnerAlias:
- system
Default: aliyun_3_9_x64_20G_alibase_20231219.vhd
Required: true
Label: Image of Instance
AssociationProperty: ALIYUN::ECS::Image::ImageId
Type: String
InstanceSource:
Default: CreateNew
AssociationPropertyMetadata:
ValueLabelMapping:
UseExisted: Select Existing Instance
CreateNew: Create New Instance
AllowedValues:
- CreateNew
- UseExisted
Type: String
Label: Instance Source
ZoneId:
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
AutoSelectFirst: true
Default: Null
Required: true
Label: Availability Zone
AssociationProperty: ALIYUN::ECS::Instance::ZoneId
Type: String
Ipv6CidrBlockNumber:
AssociationProperty: AutoCompleteInput
AssociationPropertyMetadata:
Length: 2
CharacterClasses:
- Class: number
min: 1
Type: Number
InstanceType:
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
SystemDiskCategory: cloud_essd
SpotStrategy: SpotAsPriceGo
InstanceChargeType: PostPaid
ZoneId: ${ZoneId}
Default: Null
Required: true
Label: Instance Type
AssociationProperty: ALIYUN::ECS::Instance::InstanceType
Type: String
Outputs:
EcsLoginAddress:
Description: ECS logon address.
Value:
Fn::Sub:
- https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs®ionId=${ALIYUN::Region}&instanceId=${InstanceId}
- InstanceId:
Fn::If:
- UseExistedInstance
- Ref: EcsInstanceId
- Ref: EcsInstance
Description: Create ECS instances and configure IPv6 addresses, supporting both new creations and existing instances, with automatic allocation of public IPv6 bandwidth.
Conditions:
DsIpv6Addresses.IsBodyEmpty:
Fn::Equals:
- ''
- ''
CreateInstance:
Fn::Equals:
- Ref: InstanceSource
- CreateNew
DsIpv6Gateway.IsBodyEmpty:
Fn::Equals:
- ''
- ''
UseExistedInstance:
Fn::Equals:
- Ref: InstanceSource
- UseExisted
CreateAndEnableIpv6:
Fn::And:
- CreateInstance
- Fn::Equals:
- Ref: PublicIpv6Address
- Enable
DsIpv6Addresses.IsRPC:
Fn::Not:
Fn::TransformNamespace:
- Condition
- DsIpv6Addresses.
- Fn::Contains:
- - OSS
- FC
- SLS
- CS
- VPC
DsIpv6Gateway.IsRPC:
Fn::Not:
Fn::TransformNamespace:
- Condition
- DsIpv6Gateway.
- Fn::Contains:
- - OSS
- FC
- SLS
- CS
- VPC
Resources:
DsVsw:
Type: DATASOURCE::VPC::VSwitch
Properties:
VSwitchId:
Fn::Jq:
- First
- .[0].VswitchId
- Fn::GetAtt:
- DsEcs
- Instances
Condition: UseExistedInstance
DsIpv6Addresses.Execution:
Type: ALIYUN::OOS::Execution
Properties:
TemplateName:
Ref: DsIpv6Addresses.Template
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Addresses
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
DsIpv6Gateway.Template:
Type: ALIYUN::OOS::Template
Properties:
Content:
Fn::Str:
Fn::If:
- DsIpv6Gateway.IsRPC
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
API: DescribeIpv6Gateways
Service: VPC
Parameters:
VpcId:
Fn::Jq:
- First
- .[0].VpcId
- Fn::GetAtt:
- DsEcs
- Instances
AutoPaging: true
Description: ROS Execute API
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
Body:
Fn::If:
- DsIpv6Gateway.IsBodyEmpty
- Null
- ''
Parameters:
VpcId:
Fn::Jq:
- First
- .[0].VpcId
- Fn::GetAtt:
- DsEcs
- Instances
Service: VPC
URI: ''
AutoPaging: true
Headers: {}
API: DescribeIpv6Gateways
Method: GET
Description: ROS Execute API
TemplateName:
Fn::Sub:
- ${__auto_generated__DsIpv6Gateway__Parameter__Prefix}-template-${ALIYUN::StackId}
- __auto_generated__DsIpv6Gateway__Parameter__Prefix: DescribeIpv6Gateways
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Gateway
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
ConfigureIPv6Address:
Type: ALIYUN::ROS::Stack
Properties:
TemplateBody:
ROSTemplateFormatVersion: '2015-09-01'
Conditions:
Windows:
Fn::Equals:
- windows
- Ref: OsType
Linux:
Fn::Equals:
- linux
- Ref: OsType
Resources:
WindowsCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent:
Fn::Sub: |-
# powershell
Write-Output "Start"
$install_dir = "C:\Windows\system32"
$install_path = "$install_dir\ecs-utils-ipv6.exe"
$Is64Bit = [Environment]::Is64BitOperatingSystem
Write-Output "Is64BitOperatingSystem: $Is64Bit"
if(-not (Test-Path -Path $install_path)){
# download the tool
if ([Environment]::Is64BitOperatingSystem) {
$tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/64/ecs-utils-ipv6.exe'
} else {
$tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/32/ecs-utils-ipv6.exe'
}
Write-Output "Download ecs-utils-ipv6.exe form url $tool_url"
Invoke-WebRequest -uri $tool_url -OutFile $install_path
Unblock-File $install_path
}
# run the tool
Write-Output "Run ecs-utils-ipv6.exe"
$maxRetries = 10
$retryInterval = 10
$retryCount = 0
while ($retryCount -lt $maxRetries) {
try {
Start-Process -FilePath "$install_path" -ArgumentList "--noenterkey" -NoNewWindow
Write-Output "Successfully!"
break
} catch {
Write-Error "run failed: $($_.Exception.Message). Start retry $($retryCount + 1)"
Start-Sleep -Seconds $retryInterval
$retryCount++
}
}
if ($retryCount -eq $maxRetries) {
Write-Error "Failed!"
}
Type: RunPowerShellScript
Sync: true
InstanceIds:
- Ref: InstanceId
Timeout: 3600
Condition: Windows
DependsOn: WaiteWindowsReady
WaiteWindowsReady:
Type: ALIYUN::ROS::Sleep
Properties:
CreateDuration: 300
Condition: Windows
LinuxCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent:
Fn::Sub: |-
#!/bin/bash
# script exit code:
# 0 - success
# 1 - unsupported system
# 2 - network not available
# 3 - failed to run ecs-utils-ipv6 tool
# 4 - failed to modify /etc/eni_utils/eni-function
function unsupported_system() {
log_fatal 1 "Unsupported System: $1"
}
function log_info() {
printf "%s [INFO] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
function log_error() {
printf "%s [ERROR] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
function log_fatal() {
printf "\n========================================================================\n"
printf "%s [FATAL] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
printf "\n========================================================================\n"
exit $1
}
function debug_exec(){
local cmd="$@"
log_info "$cmd"
eval "$cmd"
ret=$?
echo ""
log_info "$cmd, exit code: $ret"
return $ret
}
function check_network_available() {
log_info "ping ecs-image-utils.oss-cn-hangzhou.aliyuncs.com ..."
if ! debug_exec ping -c 4 ecs-image-utils.oss-cn-hangzhou.aliyuncs.com; then
log_fatal 2 "Could not connect to https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com"
fi
}
function run_ipv6_tool() {
log_info "run ecs-utils-ipv6 tool"
debug_exec chmod +x ./ecs-utils-ipv6
if ! debug_exec ./ecs-utils-ipv6; then
log_fatal 3 "Failed to run ecs-utils-ipv6 tool"
fi
}
function check_multi_eni_util() {
log_info "check multi-nic-util config"
if test -f /sbin/eni-ifscan; then
if ! debug_exec "sed -i 's/IPV6INIT=no/IPV6INIT=yes\n DHCPV6C=yes/g' /etc/eni_utils/eni-function"; then
log_fatal 4 "Failed to modify /etc/eni_utils/eni-function"
fi
fi
}
log_info "System Information:"
if ! lsb_release -a; then
unsupported_system
fi;
echo ""
check_network_available
RHEL=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/rhel/ecs-utils-ipv6
Debian=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/debian/ecs-utils-ipv6
SLES=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/sles/ecs-utils-ipv6
FreeBSD=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/freebsd/ecs-utils-ipv6
linux=$(lsb_release -a | grep "Distributor ID:" | cut -d':' -f2 | cut -d '(' -f1 | xargs echo -n)
case $linux in
CentOS|RedHat|Fedora|Aliyun|AlibabaCloud|Fedora|AnolisOS) wget --timeout=10 -q -O ecs-utils-ipv6 $RHEL ;;
Debian|Ubuntu) wget --timeout=10 -q -O ecs-utils-ipv6 $Debian ;;
SUSE|OpenSUSE) wget --timeout=10 -q -O ecs-utils-ipv6 $SLES ;;
FreeBSD) wget --timeout=10 -q -O ecs-utils-ipv6 $FreeBSD ;;
*) unsupported_system $linux ;;
esac
run_ipv6_tool
check_multi_eni_util
Type: RunShellScript
Sync: true
InstanceIds:
- Ref: InstanceId
Timeout: 3600
Condition: Linux
Parameters:
OsType:
Default: Null
Type: String
InstanceId:
Type: String
Parameters:
OsType:
Fn::Jq:
- First
- .[0].OSType
- Fn::GetAtt:
- DsEcs
- Instances
InstanceId:
Fn::If:
- UseExistedInstance
- Ref: EcsInstanceId
- Ref: EcsInstance
DependsOn:
- AssignIpv6Address
SecurityGroup:
Type: ALIYUN::ECS::SecurityGroup
Properties:
SecurityGroupIngress:
- PortRange: 3389/3389
SourceCidrIp: 0.0.0.0/0
IpProtocol: tcp
- PortRange: '-1/-1'
SourceCidrIp: 0.0.0.0/0
IpProtocol: icmp
- PortRange: '-1/-1'
Ipv6SourceCidrIp: '::/0'
IpProtocol: icmpv6
VpcId:
Ref: Vpc
SecurityGroupName:
Fn::Sub: ${CommonName}-sg
Condition: CreateInstance
AssignIpv6Address:
Type: ALIYUN::ROS::Stack
Properties:
TemplateBody:
ROSTemplateFormatVersion: '2015-09-01'
Conditions:
AssignIpv6Addresses:
Fn::Equals:
- Null
- Ref: Ipv6AddressId
EnableIpv6ForVpc:
Fn::Equals:
- Null
- Ref: Ipv6GatewayId
EnableIpv6ForVsw:
Fn::Equals:
- true
- Fn::Contains:
- - Null
- ''
- Ref: VswIpv6Address
Ipv6InternetBandwidth:
Fn::And:
- Fn::Equals:
- Fn::If:
- AssignIpv6Addresses
- Null
- ''
- Ref: Ipv6InternetBandwidthId
- Fn::Equals:
- Ref: PublicIpv6Address
- Enable
Resources:
IpV6Address:
Type: ALIYUN::ECS::AssignIpv6Addresses
Properties:
Ipv6AddressCount: 1
NetworkInterfaceId:
Ref: NetworkInterfaceId
Condition: AssignIpv6Addresses
DependsOn: OpenIPv6ForVsw
Ipv6InternetBandwidth:
Type: ALIYUN::VPC::Ipv6InternetBandwidth
Properties:
InternetChargeType: PayByTraffic
Bandwidth: 1
Ipv6AddressId:
Fn::If:
- AssignIpv6Addresses
- Fn::Select:
- 0
- Fn::GetAtt:
- IpV6Address
- Ipv6AddressIds
- Ref: Ipv6AddressId
Ipv6GatewayId:
Fn::If:
- EnableIpv6ForVpc
- Ref: Ipv6Gateway
- Ref: Ipv6GatewayId
Condition: Ipv6InternetBandwidth
DependsOn: Sleep
Sleep:
Type: ALIYUN::ROS::Sleep
Properties:
CreateDuration: 60
Condition: AssignIpv6Addresses
DependsOn: IpV6Address
OpenIPv6ForVsw:
Version: default
Type: MODULE::ACS::OOS::ExecuteAPI
Properties:
Prefix: open-ipv6-for-vsw
API: ModifyVSwitchAttribute
Method: POST
Parameters:
Ipv6CidrBlock:
Ref: Ipv6CidrBlockNumber
VSwitchId:
Ref: VswId
EnableIPv6: true
Service: VPC
Condition: EnableIpv6ForVsw
DependsOn: Ipv6Gateway
Ipv6Gateway:
Type: ALIYUN::VPC::Ipv6Gateway
Properties:
VpcId:
Ref: VpcId
Condition: EnableIpv6ForVpc
DependsOn: OpenIPv6ForVpc
OpenIPv6ForVpc:
Version: default
Type: MODULE::ACS::OOS::ExecuteAPI
Properties:
Prefix: open-ipv6-for-vpc
API: ModifyVpcAttribute
Method: POST
Parameters:
VpcId:
Ref: VpcId
EnableIPv6: true
Service: VPC
Condition: EnableIpv6ForVpc
Parameters:
VpcId:
Type: String
NetworkInterfaceId:
Type: String
Ipv6GatewayId:
Default: Null
Type: String
VswId:
Type: String
PublicIpv6Address:
Default: Disable
Type: String
Ipv6AddressId:
Default: Null
Type: String
Ipv6InternetBandwidthId:
Default: Null
Type: String
Ipv6CidrBlockNumber:
Type: Number
VswIpv6Address:
Type: String
Parameters:
VpcId:
Fn::Jq:
- First
- .[0].VpcId
- Fn::GetAtt:
- DsEcs
- Instances
NetworkInterfaceId:
Fn::Select:
- 0
- Fn::GetAtt:
- DsEni
- NetworkInterfaceIds
Ipv6GatewayId:
Fn::Jq:
- First
- .[0].Ipv6Gateways.Ipv6Gateway[0].Ipv6GatewayId
- Fn::If:
- UseExistedInstance
- Fn::Select:
- Result
- Fn::GetAtt:
- DsIpv6Gateway.Execution
- Outputs
- Null
- Fn::Select:
- not_exist
- {}
- Null
- invalid output(Output) of module{DsIpv6Gateway, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
VswId:
Fn::Jq:
- First
- .[0].VswitchId
- Fn::GetAtt:
- DsEcs
- Instances
PublicIpv6Address:
Ref: PublicIpv6Address
Ipv6AddressId:
Fn::Jq:
- First
- .[0].Ipv6Addresses.Ipv6Address[0].Ipv6AddressId
- Fn::If:
- UseExistedInstance
- Fn::Select:
- Result
- Fn::GetAtt:
- DsIpv6Addresses.Execution
- Outputs
- Null
- Fn::Select:
- not_exist
- {}
- Null
- invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
Ipv6InternetBandwidthId:
Fn::Jq:
- First
- .[0].Ipv6Addresses.Ipv6Address[0].Ipv6InternetBandwidth.Ipv6InternetBandwidthId
- Fn::If:
- UseExistedInstance
- Fn::Select:
- Result
- Fn::GetAtt:
- DsIpv6Addresses.Execution
- Outputs
- Null
- Fn::Select:
- not_exist
- {}
- Null
- invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
Ipv6CidrBlockNumber:
Ref: Ipv6CidrBlockNumber
VswIpv6Address:
Fn::GetAtt:
- DsVsw
- Ipv6CidrBlock
Condition: UseExistedInstance
SecurityGroupIngress:
Type: ALIYUN::ECS::SecurityGroupIngress
Properties:
IpProtocol: icmpv6
SecurityGroupId:
Fn::Jq:
- First
- .[0].SecurityGroupIds[0]
- Fn::GetAtt:
- DsEcs
- Instances
NicType: intranet
PortRange: '-1/-1'
Ipv6SourceCidrIp: '::/0'
Condition: UseExistedInstance
Ipv6InternetBandwidth:
Type: ALIYUN::VPC::Ipv6InternetBandwidth
Properties:
InternetChargeType: PayByTraffic
Bandwidth: 1
Ipv6AddressId:
Fn::Jq:
- First
- .[0][0]
- Fn::GetAtt:
- EcsInstance
- Ipv6AddressIds
Ipv6GatewayId:
Ref: Ipv6Gateway
Condition: CreateAndEnableIpv6
Vpc:
Type: ALIYUN::ECS::VPC
Properties:
EnableIpv6: true
VpcName:
Fn::Sub: ${CommonName}-vpc
CidrBlock: 192.168.0.0/16
Condition: CreateInstance
DsEcs:
Type: DATASOURCE::ECS::Instances
Properties:
InstanceIds:
- Fn::If:
- UseExistedInstance
- Ref: EcsInstanceId
- Ref: EcsInstance
DsIpv6Addresses.Template:
Type: ALIYUN::OOS::Template
Properties:
Content:
Fn::Str:
Fn::If:
- DsIpv6Addresses.IsRPC
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
API: DescribeIpv6Addresses
Service: VPC
Parameters:
AssociatedInstanceId:
Ref: EcsInstanceId
AutoPaging: true
Description: ROS Execute API
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
Body:
Fn::If:
- DsIpv6Addresses.IsBodyEmpty
- Null
- ''
Parameters:
AssociatedInstanceId:
Ref: EcsInstanceId
Service: VPC
URI: ''
AutoPaging: true
Headers: {}
API: DescribeIpv6Addresses
Method: GET
Description: ROS Execute API
TemplateName:
Fn::Sub:
- ${__auto_generated__DsIpv6Addresses__Parameter__Prefix}-template-${ALIYUN::StackId}
- __auto_generated__DsIpv6Addresses__Parameter__Prefix: DescribeIpv6Addresses
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Addresses
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
VSwitch:
Type: ALIYUN::ECS::VSwitch
Properties:
VSwitchName:
Fn::Sub: ${CommonName}-vsw
Ipv6CidrBlock: 0
VpcId:
Ref: Vpc
CidrBlock: 192.168.0.0/24
ZoneId:
Ref: ZoneId
Condition: CreateInstance
Ipv6Gateway:
Type: ALIYUN::VPC::Ipv6Gateway
Properties:
VpcId:
Ref: Vpc
Condition: CreateInstance
DependsOn:
- VSwitch
EcsInstance:
Type: ALIYUN::ECS::InstanceGroup
Properties:
SystemDiskCategory: cloud_essd
VpcId:
Ref: Vpc
Ipv6AddressCount: 1
SecurityGroupId:
Ref: SecurityGroup
ImageId:
Ref: ImageId
InternetMaxBandwidthOut: 100
SpotStrategy: SpotAsPriceGo
VSwitchId:
Ref: VSwitch
Password:
Ref: InstancePassword
InstanceName:
Fn::Sub: ${CommonName}-ecs
InstanceType:
Ref: InstanceType
ZoneId:
Ref: ZoneId
MaxAmount: 1
Condition: CreateInstance
DsEni:
Type: DATASOURCE::ECS::NetworkInterfaces
Properties:
InstanceId:
Ref: EcsInstanceId
Type: Primary
Condition: UseExistedInstance
DsIpv6Gateway.Execution:
Type: ALIYUN::OOS::Execution
Properties:
TemplateName:
Ref: DsIpv6Gateway.Template
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Gateway
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
Metadata:
ALIYUN::ROS::Interface:
ParameterGroups:
- Parameters:
- InstanceSource
- ZoneId
- ImageId
- InstanceType
- InstancePassword
- EcsInstanceId
- PublicIpv6Address
Hidden:
- CommonName
- Ipv6CidrBlockNumber
{
"ROSTemplateFormatVersion": "2015-09-01",
"Mappings": {},
"Parameters": {
"EcsInstanceId": {
"AssociationPropertyMetadata": {
"Status": "Running",
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"UseExisted"
]
}
}
},
"Default": null,
"Required": true,
"Label": "ECS Instance ID",
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceId",
"Type": "String"
},
"CommonName": {
"Default": "config-ipv6",
"Type": "String"
},
"PublicIpv6Address": {
"AssociationPropertyMetadata": {
"ValueLabelMapping": {
"Enable": "Enable IPv6 Internet Bandwidth",
"Disable": "Disable IPv6 Internet Bandwidth"
}
},
"AllowedValues": [
"Enable",
"Disable"
],
"Type": "String",
"Description": "By default, the IPv6 address assigned to the ECS instance can be used only for communications over private networks. To allow communications over the Internet, you must enable IPv6 Internet bandwidth. Select your configuration from the preceding options.",
"Label": "Configure IPv6 Internet Bandwidth"
},
"InstancePassword": {
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
}
},
"Description": "Server logon password. Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
"Confirm": true,
"Default": null,
"ConstraintDescription": "Length 8-30. Must contain three of the following: uppercase letters, lowercase letters, numbers, or special characters such as ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
"Label": "Instance Password",
"NoEcho": true,
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"Type": "String"
},
"ImageId": {
"AssociationPropertyMetadata": {
"IsSupportCloudinit": true,
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
},
"SupportedImageOwnerAlias": [
"system"
]
},
"Default": "aliyun_3_9_x64_20G_alibase_20231219.vhd",
"Required": true,
"Label": "Image of Instance",
"AssociationProperty": "ALIYUN::ECS::Image::ImageId",
"Type": "String"
},
"InstanceSource": {
"Default": "CreateNew",
"AssociationPropertyMetadata": {
"ValueLabelMapping": {
"UseExisted": "Select Existing Instance",
"CreateNew": "Create New Instance"
}
},
"AllowedValues": [
"CreateNew",
"UseExisted"
],
"Type": "String",
"Label": "Instance Source"
},
"ZoneId": {
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
},
"AutoSelectFirst": true
},
"Default": null,
"Required": true,
"Label": "Availability Zone",
"AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
"Type": "String"
},
"Ipv6CidrBlockNumber": {
"AssociationProperty": "AutoCompleteInput",
"AssociationPropertyMetadata": {
"Length": 2,
"CharacterClasses": [
{
"Class": "number",
"min": 1
}
]
},
"Type": "Number"
},
"InstanceType": {
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
},
"SystemDiskCategory": "cloud_essd",
"SpotStrategy": "SpotAsPriceGo",
"InstanceChargeType": "PostPaid",
"ZoneId": "${ZoneId}"
},
"Default": null,
"Required": true,
"Label": "Instance Type",
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
"Type": "String"
}
},
"Outputs": {
"EcsLoginAddress": {
"Description": "ECS logon address.",
"Value": {
"Fn::Sub": [
"https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs®ionId=${ALIYUN::Region}&instanceId=${InstanceId}",
{
"InstanceId": {
"Fn::If": [
"UseExistedInstance",
{
"Ref": "EcsInstanceId"
},
{
"Ref": "EcsInstance"
}
]
}
}
]
}
}
},
"Description": "Create ECS instances and configure IPv6 addresses, supporting both new creations and existing instances, with automatic allocation of public IPv6 bandwidth.",
"Conditions": {
"DsIpv6Addresses.IsBodyEmpty": {
"Fn::Equals": [
"",
""
]
},
"CreateInstance": {
"Fn::Equals": [
{
"Ref": "InstanceSource"
},
"CreateNew"
]
},
"DsIpv6Gateway.IsBodyEmpty": {
"Fn::Equals": [
"",
""
]
},
"UseExistedInstance": {
"Fn::Equals": [
{
"Ref": "InstanceSource"
},
"UseExisted"
]
},
"CreateAndEnableIpv6": {
"Fn::And": [
"CreateInstance",
{
"Fn::Equals": [
{
"Ref": "PublicIpv6Address"
},
"Enable"
]
}
]
},
"DsIpv6Addresses.IsRPC": {
"Fn::Not": {
"Fn::TransformNamespace": [
"Condition",
"DsIpv6Addresses.",
{
"Fn::Contains": [
[
"OSS",
"FC",
"SLS",
"CS"
],
"VPC"
]
}
]
}
},
"DsIpv6Gateway.IsRPC": {
"Fn::Not": {
"Fn::TransformNamespace": [
"Condition",
"DsIpv6Gateway.",
{
"Fn::Contains": [
[
"OSS",
"FC",
"SLS",
"CS"
],
"VPC"
]
}
]
}
}
},
"Resources": {
"DsVsw": {
"Type": "DATASOURCE::VPC::VSwitch",
"Properties": {
"VSwitchId": {
"Fn::Jq": [
"First",
".[0].VswitchId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
}
},
"Condition": "UseExistedInstance"
},
"DsIpv6Addresses.Execution": {
"Type": "ALIYUN::OOS::Execution",
"Properties": {
"TemplateName": {
"Ref": "DsIpv6Addresses.Template"
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Addresses",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
},
"DsIpv6Gateway.Template": {
"Type": "ALIYUN::OOS::Template",
"Properties": {
"Content": {
"Fn::Str": {
"Fn::If": [
"DsIpv6Gateway.IsRPC",
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"API": "DescribeIpv6Gateways",
"Service": "VPC",
"Parameters": {
"VpcId": {
"Fn::Jq": [
"First",
".[0].VpcId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
}
},
"AutoPaging": true
}
}
],
"Description": "ROS Execute API"
},
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"Body": {
"Fn::If": [
"DsIpv6Gateway.IsBodyEmpty",
null,
""
]
},
"Parameters": {
"VpcId": {
"Fn::Jq": [
"First",
".[0].VpcId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
}
},
"Service": "VPC",
"URI": "",
"AutoPaging": true,
"Headers": {},
"API": "DescribeIpv6Gateways",
"Method": "GET"
}
}
],
"Description": "ROS Execute API"
}
]
}
},
"TemplateName": {
"Fn::Sub": [
"${__auto_generated__DsIpv6Gateway__Parameter__Prefix}-template-${ALIYUN::StackId}",
{
"__auto_generated__DsIpv6Gateway__Parameter__Prefix": "DescribeIpv6Gateways"
}
]
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Gateway",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
},
"ConfigureIPv6Address": {
"Type": "ALIYUN::ROS::Stack",
"Properties": {
"TemplateBody": {
"ROSTemplateFormatVersion": "2015-09-01",
"Conditions": {
"Windows": {
"Fn::Equals": [
"windows",
{
"Ref": "OsType"
}
]
},
"Linux": {
"Fn::Equals": [
"linux",
{
"Ref": "OsType"
}
]
}
},
"Resources": {
"WindowsCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": {
"Fn::Sub": "# powershell\nWrite-Output \"Start\"\n$install_dir = \"C:\\Windows\\system32\"\n$install_path = \"$install_dir\\ecs-utils-ipv6.exe\"\n\n$Is64Bit = [Environment]::Is64BitOperatingSystem\nWrite-Output \"Is64BitOperatingSystem: $Is64Bit\"\n\nif(-not (Test-Path -Path $install_path)){\n # download the tool\n if ([Environment]::Is64BitOperatingSystem) {\n $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/64/ecs-utils-ipv6.exe' \n } else {\n $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/32/ecs-utils-ipv6.exe' \n }\n Write-Output \"Download ecs-utils-ipv6.exe form url $tool_url\"\n Invoke-WebRequest -uri $tool_url -OutFile $install_path\n Unblock-File $install_path\n}\n\n# run the tool\nWrite-Output \"Run ecs-utils-ipv6.exe\"\n$maxRetries = 10 \n$retryInterval = 10 \n$retryCount = 0 \n\nwhile ($retryCount -lt $maxRetries) {\n try {\n Start-Process -FilePath \"$install_path\" -ArgumentList \"--noenterkey\" -NoNewWindow\n Write-Output \"Successfully!\"\n break\n } catch {\n Write-Error \"run failed: $($_.Exception.Message). Start retry $($retryCount + 1)\"\n Start-Sleep -Seconds $retryInterval\n $retryCount++ \n }\n}\n\nif ($retryCount -eq $maxRetries) {\n Write-Error \"Failed!\"\n}"
},
"Type": "RunPowerShellScript",
"Sync": true,
"InstanceIds": [
{
"Ref": "InstanceId"
}
],
"Timeout": 3600
},
"Condition": "Windows",
"DependsOn": "WaiteWindowsReady"
},
"WaiteWindowsReady": {
"Type": "ALIYUN::ROS::Sleep",
"Properties": {
"CreateDuration": 300
},
"Condition": "Windows"
},
"LinuxCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": {
"Fn::Sub": "#!/bin/bash\n\n# script exit code:\n# 0 - success\n# 1 - unsupported system\n# 2 - network not available\n# 3 - failed to run ecs-utils-ipv6 tool\n# 4 - failed to modify /etc/eni_utils/eni-function\n\nfunction unsupported_system() {\n log_fatal 1 \"Unsupported System: $1\"\n}\n\nfunction log_info() {\n printf \"%s [INFO] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n}\n\nfunction log_error() {\n printf \"%s [ERROR] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n}\n\nfunction log_fatal() {\n printf \"\\n========================================================================\\n\"\n printf \"%s [FATAL] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n printf \"\\n========================================================================\\n\"\n exit $1\n}\n\nfunction debug_exec(){\n local cmd=\"$@\"\n log_info \"$cmd\"\n eval \"$cmd\"\n ret=$?\n echo \"\"\n log_info \"$cmd, exit code: $ret\"\n return $ret\n}\n\nfunction check_network_available() {\n log_info \"ping ecs-image-utils.oss-cn-hangzhou.aliyuncs.com ...\"\n if ! debug_exec ping -c 4 ecs-image-utils.oss-cn-hangzhou.aliyuncs.com; then\n log_fatal 2 \"Could not connect to https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com\"\n fi\n}\n\nfunction run_ipv6_tool() {\n log_info \"run ecs-utils-ipv6 tool\"\n debug_exec chmod +x ./ecs-utils-ipv6\n \n if ! debug_exec ./ecs-utils-ipv6; then\n log_fatal 3 \"Failed to run ecs-utils-ipv6 tool\"\n fi\n}\n\nfunction check_multi_eni_util() {\n log_info \"check multi-nic-util config\"\n if test -f /sbin/eni-ifscan; then\n \n if ! debug_exec \"sed -i 's/IPV6INIT=no/IPV6INIT=yes\\n DHCPV6C=yes/g' /etc/eni_utils/eni-function\"; then\n log_fatal 4 \"Failed to modify /etc/eni_utils/eni-function\"\n fi\n fi\n}\n\nlog_info \"System Information:\"\nif ! lsb_release -a; then\n unsupported_system\nfi;\necho \"\"\ncheck_network_available\n\nRHEL=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/rhel/ecs-utils-ipv6\nDebian=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/debian/ecs-utils-ipv6\nSLES=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/sles/ecs-utils-ipv6\nFreeBSD=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/freebsd/ecs-utils-ipv6\n\nlinux=$(lsb_release -a | grep \"Distributor ID:\" | cut -d':' -f2 | cut -d '(' -f1 | xargs echo -n)\ncase $linux in\n CentOS|RedHat|Fedora|Aliyun|AlibabaCloud|Fedora|AnolisOS) wget --timeout=10 -q -O ecs-utils-ipv6 $RHEL ;;\n Debian|Ubuntu) wget --timeout=10 -q -O ecs-utils-ipv6 $Debian ;;\n SUSE|OpenSUSE) wget --timeout=10 -q -O ecs-utils-ipv6 $SLES ;;\n FreeBSD) wget --timeout=10 -q -O ecs-utils-ipv6 $FreeBSD ;;\n *) unsupported_system $linux ;;\nesac\n\nrun_ipv6_tool\ncheck_multi_eni_util"
},
"Type": "RunShellScript",
"Sync": true,
"InstanceIds": [
{
"Ref": "InstanceId"
}
],
"Timeout": 3600
},
"Condition": "Linux"
}
},
"Parameters": {
"OsType": {
"Default": null,
"Type": "String"
},
"InstanceId": {
"Type": "String"
}
}
},
"Parameters": {
"OsType": {
"Fn::Jq": [
"First",
".[0].OSType",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"InstanceId": {
"Fn::If": [
"UseExistedInstance",
{
"Ref": "EcsInstanceId"
},
{
"Ref": "EcsInstance"
}
]
}
}
},
"DependsOn": [
"AssignIpv6Address"
]
},
"SecurityGroup": {
"Type": "ALIYUN::ECS::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [
{
"PortRange": "3389/3389",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "tcp"
},
{
"PortRange": "-1/-1",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "icmp"
},
{
"PortRange": "-1/-1",
"Ipv6SourceCidrIp": "::/0",
"IpProtocol": "icmpv6"
}
],
"VpcId": {
"Ref": "Vpc"
},
"SecurityGroupName": {
"Fn::Sub": "${CommonName}-sg"
}
},
"Condition": "CreateInstance"
},
"AssignIpv6Address": {
"Type": "ALIYUN::ROS::Stack",
"Properties": {
"TemplateBody": {
"ROSTemplateFormatVersion": "2015-09-01",
"Conditions": {
"AssignIpv6Addresses": {
"Fn::Equals": [
null,
{
"Ref": "Ipv6AddressId"
}
]
},
"EnableIpv6ForVpc": {
"Fn::Equals": [
null,
{
"Ref": "Ipv6GatewayId"
}
]
},
"EnableIpv6ForVsw": {
"Fn::Equals": [
true,
{
"Fn::Contains": [
[
null,
""
],
{
"Ref": "VswIpv6Address"
}
]
}
]
},
"Ipv6InternetBandwidth": {
"Fn::And": [
{
"Fn::Equals": [
{
"Fn::If": [
"AssignIpv6Addresses",
null,
""
]
},
{
"Ref": "Ipv6InternetBandwidthId"
}
]
},
{
"Fn::Equals": [
{
"Ref": "PublicIpv6Address"
},
"Enable"
]
}
]
}
},
"Resources": {
"IpV6Address": {
"Type": "ALIYUN::ECS::AssignIpv6Addresses",
"Properties": {
"Ipv6AddressCount": 1,
"NetworkInterfaceId": {
"Ref": "NetworkInterfaceId"
}
},
"Condition": "AssignIpv6Addresses",
"DependsOn": "OpenIPv6ForVsw"
},
"Ipv6InternetBandwidth": {
"Type": "ALIYUN::VPC::Ipv6InternetBandwidth",
"Properties": {
"InternetChargeType": "PayByTraffic",
"Bandwidth": 1,
"Ipv6AddressId": {
"Fn::If": [
"AssignIpv6Addresses",
{
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"IpV6Address",
"Ipv6AddressIds"
]
}
]
},
{
"Ref": "Ipv6AddressId"
}
]
},
"Ipv6GatewayId": {
"Fn::If": [
"EnableIpv6ForVpc",
{
"Ref": "Ipv6Gateway"
},
{
"Ref": "Ipv6GatewayId"
}
]
}
},
"Condition": "Ipv6InternetBandwidth",
"DependsOn": "Sleep"
},
"Sleep": {
"Type": "ALIYUN::ROS::Sleep",
"Properties": {
"CreateDuration": 60
},
"Condition": "AssignIpv6Addresses",
"DependsOn": "IpV6Address"
},
"OpenIPv6ForVsw": {
"Version": "default",
"Type": "MODULE::ACS::OOS::ExecuteAPI",
"Properties": {
"Prefix": "open-ipv6-for-vsw",
"API": "ModifyVSwitchAttribute",
"Method": "POST",
"Parameters": {
"Ipv6CidrBlock": {
"Ref": "Ipv6CidrBlockNumber"
},
"VSwitchId": {
"Ref": "VswId"
},
"EnableIPv6": true
},
"Service": "VPC"
},
"Condition": "EnableIpv6ForVsw",
"DependsOn": "Ipv6Gateway"
},
"Ipv6Gateway": {
"Type": "ALIYUN::VPC::Ipv6Gateway",
"Properties": {
"VpcId": {
"Ref": "VpcId"
}
},
"Condition": "EnableIpv6ForVpc",
"DependsOn": "OpenIPv6ForVpc"
},
"OpenIPv6ForVpc": {
"Version": "default",
"Type": "MODULE::ACS::OOS::ExecuteAPI",
"Properties": {
"Prefix": "open-ipv6-for-vpc",
"API": "ModifyVpcAttribute",
"Method": "POST",
"Parameters": {
"VpcId": {
"Ref": "VpcId"
},
"EnableIPv6": true
},
"Service": "VPC"
},
"Condition": "EnableIpv6ForVpc"
}
},
"Parameters": {
"VpcId": {
"Type": "String"
},
"NetworkInterfaceId": {
"Type": "String"
},
"Ipv6GatewayId": {
"Default": null,
"Type": "String"
},
"VswId": {
"Type": "String"
},
"PublicIpv6Address": {
"Default": "Disable",
"Type": "String"
},
"Ipv6AddressId": {
"Default": null,
"Type": "String"
},
"Ipv6InternetBandwidthId": {
"Default": null,
"Type": "String"
},
"Ipv6CidrBlockNumber": {
"Type": "Number"
},
"VswIpv6Address": {
"Type": "String"
}
}
},
"Parameters": {
"VpcId": {
"Fn::Jq": [
"First",
".[0].VpcId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"NetworkInterfaceId": {
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"DsEni",
"NetworkInterfaceIds"
]
}
]
},
"Ipv6GatewayId": {
"Fn::Jq": [
"First",
".[0].Ipv6Gateways.Ipv6Gateway[0].Ipv6GatewayId",
{
"Fn::If": [
"UseExistedInstance",
{
"Fn::Select": [
"Result",
{
"Fn::GetAtt": [
"DsIpv6Gateway.Execution",
"Outputs"
]
},
null
]
},
{
"Fn::Select": [
"not_exist",
{},
null,
"invalid output(Output) of module{DsIpv6Gateway, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
]
}
]
}
]
},
"VswId": {
"Fn::Jq": [
"First",
".[0].VswitchId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"PublicIpv6Address": {
"Ref": "PublicIpv6Address"
},
"Ipv6AddressId": {
"Fn::Jq": [
"First",
".[0].Ipv6Addresses.Ipv6Address[0].Ipv6AddressId",
{
"Fn::If": [
"UseExistedInstance",
{
"Fn::Select": [
"Result",
{
"Fn::GetAtt": [
"DsIpv6Addresses.Execution",
"Outputs"
]
},
null
]
},
{
"Fn::Select": [
"not_exist",
{},
null,
"invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
]
}
]
}
]
},
"Ipv6InternetBandwidthId": {
"Fn::Jq": [
"First",
".[0].Ipv6Addresses.Ipv6Address[0].Ipv6InternetBandwidth.Ipv6InternetBandwidthId",
{
"Fn::If": [
"UseExistedInstance",
{
"Fn::Select": [
"Result",
{
"Fn::GetAtt": [
"DsIpv6Addresses.Execution",
"Outputs"
]
},
null
]
},
{
"Fn::Select": [
"not_exist",
{},
null,
"invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
]
}
]
}
]
},
"Ipv6CidrBlockNumber": {
"Ref": "Ipv6CidrBlockNumber"
},
"VswIpv6Address": {
"Fn::GetAtt": [
"DsVsw",
"Ipv6CidrBlock"
]
}
}
},
"Condition": "UseExistedInstance"
},
"SecurityGroupIngress": {
"Type": "ALIYUN::ECS::SecurityGroupIngress",
"Properties": {
"IpProtocol": "icmpv6",
"SecurityGroupId": {
"Fn::Jq": [
"First",
".[0].SecurityGroupIds[0]",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"NicType": "intranet",
"PortRange": "-1/-1",
"Ipv6SourceCidrIp": "::/0"
},
"Condition": "UseExistedInstance"
},
"Ipv6InternetBandwidth": {
"Type": "ALIYUN::VPC::Ipv6InternetBandwidth",
"Properties": {
"InternetChargeType": "PayByTraffic",
"Bandwidth": 1,
"Ipv6AddressId": {
"Fn::Jq": [
"First",
".[0][0]",
{
"Fn::GetAtt": [
"EcsInstance",
"Ipv6AddressIds"
]
}
]
},
"Ipv6GatewayId": {
"Ref": "Ipv6Gateway"
}
},
"Condition": "CreateAndEnableIpv6"
},
"Vpc": {
"Type": "ALIYUN::ECS::VPC",
"Properties": {
"EnableIpv6": true,
"VpcName": {
"Fn::Sub": "${CommonName}-vpc"
},
"CidrBlock": "192.168.0.0/16"
},
"Condition": "CreateInstance"
},
"DsEcs": {
"Type": "DATASOURCE::ECS::Instances",
"Properties": {
"InstanceIds": [
{
"Fn::If": [
"UseExistedInstance",
{
"Ref": "EcsInstanceId"
},
{
"Ref": "EcsInstance"
}
]
}
]
}
},
"DsIpv6Addresses.Template": {
"Type": "ALIYUN::OOS::Template",
"Properties": {
"Content": {
"Fn::Str": {
"Fn::If": [
"DsIpv6Addresses.IsRPC",
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"API": "DescribeIpv6Addresses",
"Service": "VPC",
"Parameters": {
"AssociatedInstanceId": {
"Ref": "EcsInstanceId"
}
},
"AutoPaging": true
}
}
],
"Description": "ROS Execute API"
},
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"Body": {
"Fn::If": [
"DsIpv6Addresses.IsBodyEmpty",
null,
""
]
},
"Parameters": {
"AssociatedInstanceId": {
"Ref": "EcsInstanceId"
}
},
"Service": "VPC",
"URI": "",
"AutoPaging": true,
"Headers": {},
"API": "DescribeIpv6Addresses",
"Method": "GET"
}
}
],
"Description": "ROS Execute API"
}
]
}
},
"TemplateName": {
"Fn::Sub": [
"${__auto_generated__DsIpv6Addresses__Parameter__Prefix}-template-${ALIYUN::StackId}",
{
"__auto_generated__DsIpv6Addresses__Parameter__Prefix": "DescribeIpv6Addresses"
}
]
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Addresses",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
},
"VSwitch": {
"Type": "ALIYUN::ECS::VSwitch",
"Properties": {
"VSwitchName": {
"Fn::Sub": "${CommonName}-vsw"
},
"Ipv6CidrBlock": 0,
"VpcId": {
"Ref": "Vpc"
},
"CidrBlock": "192.168.0.0/24",
"ZoneId": {
"Ref": "ZoneId"
}
},
"Condition": "CreateInstance"
},
"Ipv6Gateway": {
"Type": "ALIYUN::VPC::Ipv6Gateway",
"Properties": {
"VpcId": {
"Ref": "Vpc"
}
},
"Condition": "CreateInstance",
"DependsOn": [
"VSwitch"
]
},
"EcsInstance": {
"Type": "ALIYUN::ECS::InstanceGroup",
"Properties": {
"SystemDiskCategory": "cloud_essd",
"VpcId": {
"Ref": "Vpc"
},
"Ipv6AddressCount": 1,
"SecurityGroupId": {
"Ref": "SecurityGroup"
},
"ImageId": {
"Ref": "ImageId"
},
"InternetMaxBandwidthOut": 100,
"SpotStrategy": "SpotAsPriceGo",
"VSwitchId": {
"Ref": "VSwitch"
},
"Password": {
"Ref": "InstancePassword"
},
"InstanceName": {
"Fn::Sub": "${CommonName}-ecs"
},
"InstanceType": {
"Ref": "InstanceType"
},
"ZoneId": {
"Ref": "ZoneId"
},
"MaxAmount": 1
},
"Condition": "CreateInstance"
},
"DsEni": {
"Type": "DATASOURCE::ECS::NetworkInterfaces",
"Properties": {
"InstanceId": {
"Ref": "EcsInstanceId"
},
"Type": "Primary"
},
"Condition": "UseExistedInstance"
},
"DsIpv6Gateway.Execution": {
"Type": "ALIYUN::OOS::Execution",
"Properties": {
"TemplateName": {
"Ref": "DsIpv6Gateway.Template"
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Gateway",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
}
},
"Metadata": {
"ALIYUN::ROS::Interface": {
"ParameterGroups": [
{
"Parameters": [
"InstanceSource",
"ZoneId",
"ImageId",
"InstanceType",
"InstancePassword",
"EcsInstanceId",
"PublicIpv6Address"
]
}
],
"Hidden": [
"CommonName",
"Ipv6CidrBlockNumber"
]
}
}
}Untuk contoh lainnya, lihat templat publik yang berisi resource ini.