ALIYUN::ECS::RunCommand类型用于在一台或多台ECS实例中执行一段Shell、PowerShell或者Bat类型的脚本。
语法
{
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"Parameters": Map,
"Description": String,
"Timeout": Integer,
"ContentEncoding": String,
"Name": String,
"WorkingDir": String,
"CommandContent": String,
"Type": String,
"Frequency": String,
"EnableParameter": Boolean,
"InstanceIds": List,
"KeepCommand": Boolean,
"Sync": Boolean,
"Tags": List,
"RunAgainOn": List,
"WindowsPasswordName": String,
"RepeatMode": String,
"ResourceGroupId": String,
"Launcher": String,
"ContainerName": String,
"ContainerId": String,
"Username": String
}
}
属性
|
属性名称 |
类型 |
必须 |
允许更新 |
描述 |
约束 |
|
Parameters |
Map |
否 |
是 |
脚本中包含自定义参数时,执行脚本时指定的自定义参数的键值对。例如:脚本内容为echo {{name}},则可以通过Parameters参数指定键值对{"name":"Jack"}。自定义参数将自动替换变量值name,得到一条新的脚本,实际执行的是echo Jack。 |
|
|
Description |
String |
否 |
否 |
脚本描述。 |
支持全字符集,长度不超过512个字符。 |
|
Timeout |
Integer |
否 |
是 |
执行脚本的超时时间。 |
单位:秒。 默认值:60。 当因为进程原因、缺失模块、缺失云助手客户端等原因无法运行脚本时,会出现超时现象。超时后,会强制终止脚本进程。 |
|
ContentEncoding |
String |
否 |
是 |
脚本内容(CommandContent)的编码方式。 |
取值:
说明
当您错填值时,会被当作Base64处理。 |
|
Name |
String |
否 |
否 |
脚本名称。 |
支持全字符集,长度不超过128个字符。 |
|
WorkingDir |
String |
否 |
是 |
脚本在ECS实例中的运行目录。 |
默认值:
|
|
CommandContent |
String |
是 |
是 |
脚本的明文内容或者Base64编码后的内容。 |
|
|
Type |
String |
是 |
是 |
运维脚本的语言类型。 |
取值:
|
|
Frequency |
String |
否 |
否 |
周期任务的执行周期。 |
无 |
|
EnableParameter |
Boolean |
否 |
是 |
脚本中是否包含自定义参数。 |
取值:
|
|
InstanceIds |
List |
是 |
是 |
ECS实例ID列表。 |
最多指定20台ECS实例,且ECS实例的状态必须是运行中。 |
|
KeepCommand |
Boolean |
否 |
否 |
执行完该脚本后是否保留。 |
取值:
|
|
Sync |
Boolean |
否 |
否 |
是否同步调用。 |
取值:
|
|
Tags |
List |
否 |
是 |
标签。 |
最多支持添加20个标签。更多信息,请参见Tags属性。 |
|
RunAgainOn |
List |
否 |
否 |
再次执行命令的阶段。 |
无 |
|
WindowsPasswordName |
String |
否 |
否 |
在Windows实例中执行命令的用户的密码名称。 |
长度不得超过 255 个字符。 当您希望以非默认用户(System)在 Windows 实例中执行命令时,需要同时传入 说明
当您使用 Linux 实例的 root 用户或 Windows 实例的 System 用户执行命令时,不需要传递该参数。 |
|
RepeatMode |
String |
否 |
否 |
设置命令执行的方式。 |
取值范围:
默认值:
注意事项:
|
|
Launcher |
String |
否 |
否 |
脚本执行的引导程序。 |
长度不能超过 1 KB。 |
|
ResourceGroupId |
String |
否 |
否 |
命令执行的资源组ID。 |
当指定该参数时:
|
|
ContainerName |
String |
否 |
否 |
容器名称。 |
注意事项:
|
|
ContainerId |
String |
否 |
否 |
容器ID。 |
仅支持64位16进制字符串,允许存在 注意事项:
|
|
Username |
String |
否 |
是 |
在ECS实例中执行命令的用户名。 |
长度不得超过255个字符。
您也可以指定实例中已存在的其他用户执行命令,以普通用户执行云助手命令更加安全。更多信息,请参见设置普通用户执行云助手命令。 |
Tags语法
"Tags": [
{
"Key": String,
"Value": String
}
]
Tags属性
|
属性名称 |
类型 |
必须 |
允许更新 |
描述 |
约束 |
|
Key |
String |
是 |
否 |
标签键。 |
长度为1~128个字符,不能以 |
|
Value |
String |
否 |
否 |
标签值。 |
长度为0~128个字符,不能以 |
返回值
Fn::GetAtt
-
CommandId:脚本ID。
-
InvokeId:脚本执行ID。
-
InvokeInstances:执行命令的实例列表。
-
InvokeResults:执行命令的结果。
示例
ROSTemplateFormatVersion: '2015-09-01'
Parameters:
InstanceId:
Type: String
AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Resources:
RunCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent:
Fn::Sub:
|
#!/bin/sh
yum install -y tree
Type: RunShellScript
InstanceIds:
- Ref: InstanceId
Outputs:
CommandId:
Description: The id of command created.
Value:
Fn::GetAtt:
- RunCommand
- CommandId
InvokeId:
Description: The invoke id of command.
Value:
Fn::GetAtt:
- RunCommand
- InvokeId
{
"ROSTemplateFormatVersion": "2015-09-01",
"Parameters": {
"InstanceId": {
"Type": "String",
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceId"
}
},
"Resources": {
"RunCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": {
"Fn::Sub":
"#!/bin/sh\nyum install -y tree\n"
},
"Type": "RunShellScript",
"InstanceIds": [
{
"Ref": "InstanceId"
}
]
}
}
},
"Outputs": {
"CommandId": {
"Description": "The id of command created.",
"Value": {
"Fn::GetAtt": [
"RunCommand",
"CommandId"
]
}
},
"InvokeId": {
"Description": "The invoke id of command.",
"Value": {
"Fn::GetAtt": [
"RunCommand",
"InvokeId"
]
}
}
}
}UpdatePolicy简介
当我们使用ALIYUN::ECS::RunCommand为一组ECS实例执行脚本后,需要对已执行脚本的这组ECS进行配置批量更新时,可以使用UpdatePolicy属性去完成对ECS::RunCommand配置更新策略的控制。UpdatePolicy属性语法参考:
UpdatePolicy语法
"UpdatePolicy": {
"RollingUpdate": Map
}
UpdatePolicy属性
|
属性名称 |
类型 |
必须 |
允许更新 |
描述 |
约束 |
|
RollingUpdate |
Map |
否 |
是 |
控制更新已有的Command的策略。 |
RollingUpdate语法
"RollingUpdate": {
"MaxBatchSize": Integer,
"PauseTime": Integer
}
RollingUpdate属性
|
属性名称 |
类型 |
必须 |
允许更新 |
描述 |
约束 |
|
MaxBatchSize |
Integer |
是 |
是 |
每个批次执行命令的ECS台数。 |
取值范围:1~1000。 |
|
PauseTime |
Integer |
否 |
是 |
各个批次执行命令之间暂停的时间(单位:秒)默认为0。 |
取值范围:0~3600。 |
场景 1 :在已有ECS场景下执行命令RunCommand。
ROSTemplateFormatVersion: '2015-09-01'
Resources:
RunCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent: xxx
Type: RunShellScript
Sync: true
InstanceIds:
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
{
"ROSTemplateFormatVersion": "2015-09-01",
"Resources": {
"RunCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": "xxx",
"Type": "RunShellScript",
"Sync": true,
"InstanceIds": [
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx",
]
}
}
}
}创建资源栈成功后对已执行Command的ECS实例进行配置更新,更新时可以配置UpdatePolicy属性。
ROSTemplateFormatVersion: '2015-09-01'
Resources:
RunCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent: xxx
Type: RunShellScript
Sync: true
InstanceIds:
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
- i-2zxxxx
UpdatePolicy:
RollingUpdate:
MaxBatchSize: 2
PauseTime: 10
{
"ROSTemplateFormatVersion": "2015-09-01",
"Resources": {
"RunCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": "xxx",
"Type": "RunShellScript",
"Sync": true,
"InstanceIds": [
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx",
"i-2zxxxx"
]
},
"UpdatePolicy": {
"RollingUpdate": {
"MaxBatchSize": 2,
"PauseTime": 10
}
}
}
}
}指定MaxBatchSize=2。 更新前InstanceIds内包含3台ECS实例,更新后InstanceIds内包含5台ECS实例,在更新资源栈的过程中,原有的3台机器,会分2个批次(2/1)进行变配更新(原有的InstanceIds信息会按照传入的顺序划分批次)。新增的2台机器会被一次性统一执行Command。
场景 2 :新建ECS(Alibaba Cloud Linux 3)并部署Django环境。
ROSTemplateFormatVersion: '2015-09-01'
Description:
zh-cn: 部署Django环境。
en: Deploy the Django environment.
Parameters:
ZoneId:
Default: Null
AssociationProperty: ALIYUN::ECS::Instance::ZoneId
Required: true
Type: String
Label:
zh-cn: 可用区
en: Availability Zone
InstanceType:
AssociationPropertyMetadata:
SystemDiskCategory: cloud_essd
SpotStrategy: SpotAsPriceGo
InstanceChargeType: PostPaid
ZoneId: ${ZoneId}
Default: Null
Required: true
Label:
zh-cn: 实例类型
en: Instance Type
AssociationProperty: ALIYUN::ECS::Instance::InstanceType
Type: String
InstancePassword:
Description:
zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)
en: Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
Confirm: true
Default: Null
Type: String
Label:
zh-cn: 实例密码
en: Instance Password
NoEcho: true
AssociationProperty: ALIYUN::ECS::Instance::Password
ConstraintDescription:
zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)
en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
ImageId:
AssociationPropertyMetadata:
ValueLabelMapping:
aliyun_3_x64_20G_alibase_20240528.vhd:
zh-cn: Alibaba Cloud Linux 3
en: Alibaba Cloud Linux 3
Default: aliyun_3_x64_20G_alibase_20240528.vhd
Required: true
Label:
zh-cn: 实例镜像
en: Image of Instance
AllowedValues:
- aliyun_3_x64_20G_alibase_20240528.vhd
Type: String
Outputs: {}
Conditions: {}
Resources:
SecurityGroupIngress_80:
Type: ALIYUN::ECS::SecurityGroupIngress
Properties:
IpProtocol: tcp
SecurityGroupId:
Ref: SecurityGroup
NicType: intranet
SourceCidrIp: 0.0.0.0/0
PortRange: 80/80
SecurityGroup:
Type: ALIYUN::ECS::SecurityGroup
Properties:
SecurityGroupIngress:
- PortRange: 80/80
SourceCidrIp: 0.0.0.0/0
IpProtocol: tcp
- PortRange: '-1/-1'
SourceCidrIp: 0.0.0.0/0
IpProtocol: icmp
VpcId:
Ref: Vpc
SecurityGroupName: deploy_django_by_ros_sg
Vpc:
Type: ALIYUN::ECS::VPC
Properties:
VpcName: deploy_django_by_ros_vpc
CidrBlock: 192.168.0.0/16
DeployDjango:
Type: ALIYUN::ECS::RunCommand
Properties:
Type: RunShellScript
CommandContent:
Fn::Sub: |-
#!/bin/bash
sudo yum -y install nginx python3-devel.x86_64
sudo pip3 install Django uwsgi
sudo mkdir /home/myblog && cd /home/myblog
sudo /usr/local/bin/django-admin.py startproject uwsgi_project
sudo sed -i 's/ALLOWED_HOSTS = \[\]/ALLOWED_HOSTS = \["*"\]/g' /home/myblog/uwsgi_project/uwsgi_project/settings.py
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sudo mv /etc/uwsgi.ini /etc/uwsgi.ini.bak
cat << "EOF" > /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
upstream django {
server 127.0.0.1:8001; #具体端口必须与您uWSGI配置文件中定义的端口一致
}
server {
listen 80; #设置的nginx访问端口
server_name test;
charset utf-8;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location /static {
autoindex on;
alias /home/myblog/uwsgi_project/uwsgi_project/static; #具体目录以您现场具体部署的目录为准
}
location / {
uwsgi_pass 127.0.0.1:8001;
include uwsgi_params; #具体目录以您现场具体部署的目录为准
include /etc/nginx/uwsgi_params; #具体目录以您现场具体部署的目录为准
uwsgi_param UWSGI_SCRIPT iCourse.wsgi; #具体目录以您现场具体部署的目录为准
uwsgi_param UWSGI_CHDIR /iCourse; #具体目录以您现场具体部署的目录为准
index index.html index.htm;
client_max_body_size 35m;
index index.html index.htm;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
EOF
cat << "EOF" > /etc/uwsgi.ini
[uwsgi]
socket = 127.0.0.1:8001
chdir = /home/myblog/uwsgi_project/
wsgi-file = uwsgi_project/wsgi.py
processes = 4
threads = 2
vacuum = true
buffer-size = 65536
EOF
cat << "EOF" > /etc/systemd/system/uwsgi.service
[Unit]
Description=uwsgi service
After=network.target
[Service]
Type=simple
User=nginx
Group=nginx
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi.ini
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable nginx.service
sudo systemctl restart nginx.service
sudo systemctl enable uwsgi.service
sudo systemctl restart uwsgi.service
Sync: true
InstanceIds:
- Ref: EcsInstance
Timeout: 3600
VSwitch:
Type: ALIYUN::ECS::VSwitch
Properties:
VSwitchName: deploy_django_by_ros_vsw
VpcId:
Ref: Vpc
CidrBlock: 192.168.0.0/24
ZoneId:
Ref: ZoneId
EcsInstance:
Type: ALIYUN::ECS::InstanceGroup
Properties:
SystemDiskCategory: cloud_essd
VpcId:
Ref: Vpc
SecurityGroupId:
Ref: SecurityGroup
ImageId:
Ref: ImageId
InternetMaxBandwidthOut: 100
SpotStrategy: SpotAsPriceGo
VSwitchId:
Ref: VSwitch
Password:
Ref: InstancePassword
InstanceName: deploy_django_by_ros_ecs
InstanceType:
Ref: InstanceType
ZoneId:
Ref: ZoneId
MaxAmount: 1
Metadata:
ALIYUN::ROS::Interface:
ParameterGroups:
- Parameters:
- ZoneId
- ImageId
- InstanceType
- InstancePassword
{
"ROSTemplateFormatVersion": "2015-09-01",
"Description": {
"zh-cn": "部署Django环境。",
"en": "Deploy the Django environment."
},
"Parameters": {
"ZoneId": {
"Default": null,
"AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
"Required": true,
"Type": "String",
"Label": {
"zh-cn": "可用区",
"en": "Availability Zone"
}
},
"InstanceType": {
"AssociationPropertyMetadata": {
"SystemDiskCategory": "cloud_essd",
"SpotStrategy": "SpotAsPriceGo",
"InstanceChargeType": "PostPaid",
"ZoneId": "${ZoneId}"
},
"Default": null,
"Required": true,
"Label": {
"zh-cn": "实例类型",
"en": "Instance Type"
},
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
"Type": "String"
},
"InstancePassword": {
"Description": {
"zh-cn": "服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)",
"en": "Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
},
"Confirm": true,
"Default": null,
"Type": "String",
"Label": {
"zh-cn": "实例密码",
"en": "Instance Password"
},
"NoEcho": true,
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"ConstraintDescription": {
"zh-cn": "长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)",
"en": "Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
}
},
"ImageId": {
"AssociationPropertyMetadata": {
"ValueLabelMapping": {
"aliyun_3_x64_20G_alibase_20240528.vhd": {
"zh-cn": "Alibaba Cloud Linux 3",
"en": "Alibaba Cloud Linux 3"
}
}
},
"Default": "aliyun_3_x64_20G_alibase_20240528.vhd",
"Required": true,
"Label": {
"zh-cn": "实例镜像",
"en": "Image of Instance"
},
"AllowedValues": [
"aliyun_3_x64_20G_alibase_20240528.vhd"
],
"Type": "String"
}
},
"Outputs": {},
"Conditions": {},
"Resources": {
"SecurityGroupIngress_80": {
"Type": "ALIYUN::ECS::SecurityGroupIngress",
"Properties": {
"IpProtocol": "tcp",
"SecurityGroupId": {
"Ref": "SecurityGroup"
},
"NicType": "intranet",
"SourceCidrIp": "0.0.0.0/0",
"PortRange": "80/80"
}
},
"SecurityGroup": {
"Type": "ALIYUN::ECS::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [
{
"PortRange": "80/80",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "tcp"
},
{
"PortRange": "-1/-1",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "icmp"
}
],
"VpcId": {
"Ref": "Vpc"
},
"SecurityGroupName": "deploy_django_by_ros_sg"
}
},
"Vpc": {
"Type": "ALIYUN::ECS::VPC",
"Properties": {
"VpcName": "deploy_django_by_ros_vpc",
"CidrBlock": "192.168.0.0/16"
}
},
"DeployDjango": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"Type": "RunShellScript",
"CommandContent": {
"Fn::Sub": "#!/bin/bash\nsudo yum -y install nginx python3-devel.x86_64\n\n\nsudo pip3 install Django uwsgi\nsudo mkdir /home/myblog && cd /home/myblog\n\nsudo /usr/local/bin/django-admin.py startproject uwsgi_project\n\nsudo sed -i 's/ALLOWED_HOSTS = \\[\\]/ALLOWED_HOSTS = \\[\"*\"\\]/g' /home/myblog/uwsgi_project/uwsgi_project/settings.py\nsudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak\nsudo mv /etc/uwsgi.ini /etc/uwsgi.ini.bak\n\ncat << \"EOF\" > /etc/nginx/nginx.conf\nuser nginx;\nworker_processes auto;\nerror_log /var/log/nginx/error.log;\npid /run/nginx.pid;\n# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.\ninclude /usr/share/nginx/modules/*.conf;\nevents {\n worker_connections 1024;\n}\nhttp {\n log_format main '$remote_addr - $remote_user [$time_local] \"$request\" '\n '$status $body_bytes_sent \"$http_referer\" '\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n access_log /var/log/nginx/access.log main;\n sendfile on;\n tcp_nopush on;\n tcp_nodelay on;\n keepalive_timeout 65;\n types_hash_max_size 4096;\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n # Load modular configuration files from the /etc/nginx/conf.d directory.\n # See http://nginx.org/en/docs/ngx_core_module.html#include\n # for more information.\n include /etc/nginx/conf.d/*.conf;\n upstream django {\n server 127.0.0.1:8001; #具体端口必须与您uWSGI配置文件中定义的端口一致\n }\n server {\n listen 80; #设置的nginx访问端口\n server_name test;\n charset utf-8;\n # Load configuration files for the default server block.\n include /etc/nginx/default.d/*.conf;\n location /static {\n autoindex on;\n alias /home/myblog/uwsgi_project/uwsgi_project/static; #具体目录以您现场具体部署的目录为准\n }\n location / {\n uwsgi_pass 127.0.0.1:8001;\n include uwsgi_params; #具体目录以您现场具体部署的目录为准\n include /etc/nginx/uwsgi_params; #具体目录以您现场具体部署的目录为准\n uwsgi_param UWSGI_SCRIPT iCourse.wsgi; #具体目录以您现场具体部署的目录为准\n uwsgi_param UWSGI_CHDIR /iCourse; #具体目录以您现场具体部署的目录为准\n index index.html index.htm;\n client_max_body_size 35m;\n index index.html index.htm;\n }\n error_page 404 /404.html;\n location = /40x.html {\n }\n error_page 500 502 503 504 /50x.html;\n location = /50x.html {\n }\n }\n} \nEOF\n\ncat << \"EOF\" > /etc/uwsgi.ini\n[uwsgi]\nsocket = 127.0.0.1:8001\nchdir = /home/myblog/uwsgi_project/\nwsgi-file = uwsgi_project/wsgi.py\nprocesses = 4\nthreads = 2\nvacuum = true\nbuffer-size = 65536\nEOF\n\ncat << \"EOF\" > /etc/systemd/system/uwsgi.service\n[Unit]\nDescription=uwsgi service\nAfter=network.target\n[Service]\nType=simple\nUser=nginx\nGroup=nginx\nExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi.ini\n[Install]\nWantedBy=multi-user.target\nEOF\nsudo systemctl daemon-reload\nsudo systemctl enable nginx.service\nsudo systemctl restart nginx.service\nsudo systemctl enable uwsgi.service\nsudo systemctl restart uwsgi.service"
},
"Sync": true,
"InstanceIds": [
{
"Ref": "EcsInstance"
}
],
"Timeout": 3600
}
},
"VSwitch": {
"Type": "ALIYUN::ECS::VSwitch",
"Properties": {
"VSwitchName": "deploy_django_by_ros_vsw",
"VpcId": {
"Ref": "Vpc"
},
"CidrBlock": "192.168.0.0/24",
"ZoneId": {
"Ref": "ZoneId"
}
}
},
"EcsInstance": {
"Type": "ALIYUN::ECS::InstanceGroup",
"Properties": {
"SystemDiskCategory": "cloud_essd",
"VpcId": {
"Ref": "Vpc"
},
"SecurityGroupId": {
"Ref": "SecurityGroup"
},
"ImageId": {
"Ref": "ImageId"
},
"InternetMaxBandwidthOut": 100,
"SpotStrategy": "SpotAsPriceGo",
"VSwitchId": {
"Ref": "VSwitch"
},
"Password": {
"Ref": "InstancePassword"
},
"InstanceName": "deploy_django_by_ros_ecs",
"InstanceType": {
"Ref": "InstanceType"
},
"ZoneId": {
"Ref": "ZoneId"
},
"MaxAmount": 1
}
}
},
"Metadata": {
"ALIYUN::ROS::Interface": {
"ParameterGroups": [
{
"Parameters": [
"ZoneId",
"ImageId",
"InstanceType",
"InstancePassword"
]
}
]
}
}
}场景 3 :ECS(Windows/Linux)配置IPv6地址,并自动分配公网IPv6带宽。
ROSTemplateFormatVersion: '2015-09-01'
Mappings: {}
Parameters:
EcsInstanceId:
AssociationPropertyMetadata:
Status: Running
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- UseExisted
Default: Null
Required: true
Label:
zh-cn: ECS实例ID
en: ECS Instance ID
AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Type: String
CommonName:
Default: config-ipv6
Type: String
PublicIpv6Address:
AssociationPropertyMetadata:
ValueLabelMapping:
Enable:
zh-cn: 开通IPv6公网带宽
en: Enable IPv6 Internet Bandwidth
Disable:
zh-cn: 不开通IPv6公网带宽
en: Disable IPv6 Internet Bandwidth
AllowedValues:
- Enable
- Disable
Type: String
Description:
zh-cn: 默认情况下,为ECS实例分配的IPv6地址仅具有私网通信能力,若您希望IPv6地址具有公网通信能力, 则需开通IPv6公网带宽。请从以上选项中选择您的配置。
en: By default, the IPv6 address assigned to the ECS instance can be used only for communications over private networks. To allow communications over the Internet, you must enable IPv6 Internet bandwidth. Select your configuration from the preceding options.
Label:
zh-cn: 配置IPv6公网带宽
en: Configure IPv6 Internet Bandwidth
InstancePassword:
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
Description:
zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)
en: Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
Confirm: true
Default: Null
ConstraintDescription:
zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)
en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
Label:
zh-cn: 实例密码
en: Instance Password
NoEcho: true
AssociationProperty: ALIYUN::ECS::Instance::Password
Type: String
ImageId:
AssociationPropertyMetadata:
IsSupportCloudinit: true
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
SupportedImageOwnerAlias:
- system
Default: aliyun_3_9_x64_20G_alibase_20231219.vhd
Required: true
Label:
zh-cn: 实例镜像
en: Image of Instance
AssociationProperty: ALIYUN::ECS::Image::ImageId
Type: String
InstanceSource:
Default: CreateNew
AssociationPropertyMetadata:
ValueLabelMapping:
UseExisted:
zh-cn: 选择已有实例
en: Select Existed Instance
CreateNew:
zh-cn: 创建新实例
en: Create New Instance
AllowedValues:
- CreateNew
- UseExisted
Type: String
Label:
zh-cn: 实例来源
en: Instance Source
ZoneId:
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
AutoSelectFirst: true
Default: Null
Required: true
Label:
zh-cn: 可用区
en: Availability Zone
AssociationProperty: ALIYUN::ECS::Instance::ZoneId
Type: String
Ipv6CidrBlockNumber:
AssociationProperty: AutoCompleteInput
AssociationPropertyMetadata:
Length: 2
CharacterClasses:
- Class: number
min: 1
Type: Number
InstanceType:
AssociationPropertyMetadata:
Visible:
Condition:
Fn::Equals:
- ${InstanceSource}
- CreateNew
SystemDiskCategory: cloud_essd
SpotStrategy: SpotAsPriceGo
InstanceChargeType: PostPaid
ZoneId: ${ZoneId}
Default: Null
Required: true
Label:
zh-cn: 实例类型
en: Instance Type
AssociationProperty: ALIYUN::ECS::Instance::InstanceType
Type: String
Outputs:
EcsLoginAddress:
Description:
zh-cn: ECS登录地址。
en: Ecs login address.
Value:
Fn::Sub:
- https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs®ionId=${ALIYUN::Region}&instanceId=${InstanceId}
- InstanceId:
Fn::If:
- UseExistedInstance
- Ref: EcsInstanceId
- Ref: EcsInstance
Description:
zh-cn: 创建ECS实例并配置IPv6地址,支持新创建或现有实例,自动分配公网IPv6带宽。
en: Create ECS instances and configure IPv6 addresses, supporting both new creations and existing instances, with automatic allocation of public IPv6 bandwidth.
Conditions:
DsIpv6Addresses.IsBodyEmpty:
Fn::Equals:
- ''
- ''
CreateInstance:
Fn::Equals:
- Ref: InstanceSource
- CreateNew
DsIpv6Gateway.IsBodyEmpty:
Fn::Equals:
- ''
- ''
UseExistedInstance:
Fn::Equals:
- Ref: InstanceSource
- UseExisted
CreateAndEnableIpv6:
Fn::And:
- CreateInstance
- Fn::Equals:
- Ref: PublicIpv6Address
- Enable
DsIpv6Addresses.IsRPC:
Fn::Not:
Fn::TransformNamespace:
- Condition
- DsIpv6Addresses.
- Fn::Contains:
- - OSS
- FC
- SLS
- CS
- VPC
DsIpv6Gateway.IsRPC:
Fn::Not:
Fn::TransformNamespace:
- Condition
- DsIpv6Gateway.
- Fn::Contains:
- - OSS
- FC
- SLS
- CS
- VPC
Resources:
DsVsw:
Type: DATASOURCE::VPC::VSwitch
Properties:
VSwitchId:
Fn::Jq:
- First
- .[0].VswitchId
- Fn::GetAtt:
- DsEcs
- Instances
Condition: UseExistedInstance
DsIpv6Addresses.Execution:
Type: ALIYUN::OOS::Execution
Properties:
TemplateName:
Ref: DsIpv6Addresses.Template
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Addresses
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
DsIpv6Gateway.Template:
Type: ALIYUN::OOS::Template
Properties:
Content:
Fn::Str:
Fn::If:
- DsIpv6Gateway.IsRPC
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
API: DescribeIpv6Gateways
Service: VPC
Parameters:
VpcId:
Fn::Jq:
- First
- .[0].VpcId
- Fn::GetAtt:
- DsEcs
- Instances
AutoPaging: true
Description: ROS Execute API
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
Body:
Fn::If:
- DsIpv6Gateway.IsBodyEmpty
- Null
- ''
Parameters:
VpcId:
Fn::Jq:
- First
- .[0].VpcId
- Fn::GetAtt:
- DsEcs
- Instances
Service: VPC
URI: ''
AutoPaging: true
Headers: {}
API: DescribeIpv6Gateways
Method: GET
Description: ROS Execute API
TemplateName:
Fn::Sub:
- ${__auto_generated__DsIpv6Gateway__Parameter__Prefix}-template-${ALIYUN::StackId}
- __auto_generated__DsIpv6Gateway__Parameter__Prefix: DescribeIpv6Gateways
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Gateway
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
ConfigureIPv6Address:
Type: ALIYUN::ROS::Stack
Properties:
TemplateBody:
ROSTemplateFormatVersion: '2015-09-01'
Conditions:
Windows:
Fn::Equals:
- windows
- Ref: OsType
Linux:
Fn::Equals:
- linux
- Ref: OsType
Resources:
WindowsCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent:
Fn::Sub: |-
# powershell
Write-Output "Start"
$install_dir = "C:\Windows\system32"
$install_path = "$install_dir\ecs-utils-ipv6.exe"
$Is64Bit = [Environment]::Is64BitOperatingSystem
Write-Output "Is64BitOperatingSystem: $Is64Bit"
if(-not (Test-Path -Path $install_path)){
# download the tool
if ([Environment]::Is64BitOperatingSystem) {
$tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/64/ecs-utils-ipv6.exe'
} else {
$tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/32/ecs-utils-ipv6.exe'
}
Write-Output "Download ecs-utils-ipv6.exe form url $tool_url"
Invoke-WebRequest -uri $tool_url -OutFile $install_path
Unblock-File $install_path
}
# run the tool
Write-Output "Run ecs-utils-ipv6.exe"
$maxRetries = 10
$retryInterval = 10
$retryCount = 0
while ($retryCount -lt $maxRetries) {
try {
Start-Process -FilePath "$install_path" -ArgumentList "--noenterkey" -NoNewWindow
Write-Output "Successfully!"
break
} catch {
Write-Error "run failed: $($_.Exception.Message). Start retry $($retryCount + 1)"
Start-Sleep -Seconds $retryInterval
$retryCount++
}
}
if ($retryCount -eq $maxRetries) {
Write-Error "Failed!"
}
Type: RunPowerShellScript
Sync: true
InstanceIds:
- Ref: InstanceId
Timeout: 3600
Condition: Windows
DependsOn: WaiteWindowsReady
WaiteWindowsReady:
Type: ALIYUN::ROS::Sleep
Properties:
CreateDuration: 300
Condition: Windows
LinuxCommand:
Type: ALIYUN::ECS::RunCommand
Properties:
CommandContent:
Fn::Sub: |-
#!/bin/bash
# script exit code:
# 0 - success
# 1 - unsupported system
# 2 - network not available
# 3 - failed to run ecs-utils-ipv6 tool
# 4 - failed to modify /etc/eni_utils/eni-function
function unsupported_system() {
log_fatal 1 "Unsupported System: $1"
}
function log_info() {
printf "%s [INFO] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
function log_error() {
printf "%s [ERROR] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
function log_fatal() {
printf "\n========================================================================\n"
printf "%s [FATAL] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
printf "\n========================================================================\n"
exit $1
}
function debug_exec(){
local cmd="$@"
log_info "$cmd"
eval "$cmd"
ret=$?
echo ""
log_info "$cmd, exit code: $ret"
return $ret
}
function check_network_available() {
log_info "ping ecs-image-utils.oss-cn-hangzhou.aliyuncs.com ..."
if ! debug_exec ping -c 4 ecs-image-utils.oss-cn-hangzhou.aliyuncs.com; then
log_fatal 2 "Could not connect to https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com"
fi
}
function run_ipv6_tool() {
log_info "run ecs-utils-ipv6 tool"
debug_exec chmod +x ./ecs-utils-ipv6
if ! debug_exec ./ecs-utils-ipv6; then
log_fatal 3 "Failed to run ecs-utils-ipv6 tool"
fi
}
function check_multi_eni_util() {
log_info "check multi-nic-util config"
if test -f /sbin/eni-ifscan; then
if ! debug_exec "sed -i 's/IPV6INIT=no/IPV6INIT=yes\n DHCPV6C=yes/g' /etc/eni_utils/eni-function"; then
log_fatal 4 "Failed to modify /etc/eni_utils/eni-function"
fi
fi
}
log_info "System Information:"
if ! lsb_release -a; then
unsupported_system
fi;
echo ""
check_network_available
RHEL=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/rhel/ecs-utils-ipv6
Debian=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/debian/ecs-utils-ipv6
SLES=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/sles/ecs-utils-ipv6
FreeBSD=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/freebsd/ecs-utils-ipv6
linux=$(lsb_release -a | grep "Distributor ID:" | cut -d':' -f2 | cut -d '(' -f1 | xargs echo -n)
case $linux in
CentOS|RedHat|Fedora|Aliyun|AlibabaCloud|Fedora|AnolisOS) wget --timeout=10 -q -O ecs-utils-ipv6 $RHEL ;;
Debian|Ubuntu) wget --timeout=10 -q -O ecs-utils-ipv6 $Debian ;;
SUSE|OpenSUSE) wget --timeout=10 -q -O ecs-utils-ipv6 $SLES ;;
FreeBSD) wget --timeout=10 -q -O ecs-utils-ipv6 $FreeBSD ;;
*) unsupported_system $linux ;;
esac
run_ipv6_tool
check_multi_eni_util
Type: RunShellScript
Sync: true
InstanceIds:
- Ref: InstanceId
Timeout: 3600
Condition: Linux
Parameters:
OsType:
Default: Null
Type: String
InstanceId:
Type: String
Parameters:
OsType:
Fn::Jq:
- First
- .[0].OSType
- Fn::GetAtt:
- DsEcs
- Instances
InstanceId:
Fn::If:
- UseExistedInstance
- Ref: EcsInstanceId
- Ref: EcsInstance
DependsOn:
- AssignIpv6Address
SecurityGroup:
Type: ALIYUN::ECS::SecurityGroup
Properties:
SecurityGroupIngress:
- PortRange: 3389/3389
SourceCidrIp: 0.0.0.0/0
IpProtocol: tcp
- PortRange: '-1/-1'
SourceCidrIp: 0.0.0.0/0
IpProtocol: icmp
- PortRange: '-1/-1'
Ipv6SourceCidrIp: '::/0'
IpProtocol: icmpv6
VpcId:
Ref: Vpc
SecurityGroupName:
Fn::Sub: ${CommonName}-sg
Condition: CreateInstance
AssignIpv6Address:
Type: ALIYUN::ROS::Stack
Properties:
TemplateBody:
ROSTemplateFormatVersion: '2015-09-01'
Conditions:
AssignIpv6Addresses:
Fn::Equals:
- Null
- Ref: Ipv6AddressId
EnableIpv6ForVpc:
Fn::Equals:
- Null
- Ref: Ipv6GatewayId
EnableIpv6ForVsw:
Fn::Equals:
- true
- Fn::Contains:
- - Null
- ''
- Ref: VswIpv6Address
Ipv6InternetBandwidth:
Fn::And:
- Fn::Equals:
- Fn::If:
- AssignIpv6Addresses
- Null
- ''
- Ref: Ipv6InternetBandwidthId
- Fn::Equals:
- Ref: PublicIpv6Address
- Enable
Resources:
IpV6Address:
Type: ALIYUN::ECS::AssignIpv6Addresses
Properties:
Ipv6AddressCount: 1
NetworkInterfaceId:
Ref: NetworkInterfaceId
Condition: AssignIpv6Addresses
DependsOn: OpenIPv6ForVsw
Ipv6InternetBandwidth:
Type: ALIYUN::VPC::Ipv6InternetBandwidth
Properties:
InternetChargeType: PayByTraffic
Bandwidth: 1
Ipv6AddressId:
Fn::If:
- AssignIpv6Addresses
- Fn::Select:
- 0
- Fn::GetAtt:
- IpV6Address
- Ipv6AddressIds
- Ref: Ipv6AddressId
Ipv6GatewayId:
Fn::If:
- EnableIpv6ForVpc
- Ref: Ipv6Gateway
- Ref: Ipv6GatewayId
Condition: Ipv6InternetBandwidth
DependsOn: Sleep
Sleep:
Type: ALIYUN::ROS::Sleep
Properties:
CreateDuration: 60
Condition: AssignIpv6Addresses
DependsOn: IpV6Address
OpenIPv6ForVsw:
Version: default
Type: MODULE::ACS::OOS::ExecuteAPI
Properties:
Prefix: open-ipv6-for-vsw
API: ModifyVSwitchAttribute
Method: POST
Parameters:
Ipv6CidrBlock:
Ref: Ipv6CidrBlockNumber
VSwitchId:
Ref: VswId
EnableIPv6: true
Service: VPC
Condition: EnableIpv6ForVsw
DependsOn: Ipv6Gateway
Ipv6Gateway:
Type: ALIYUN::VPC::Ipv6Gateway
Properties:
VpcId:
Ref: VpcId
Condition: EnableIpv6ForVpc
DependsOn: OpenIPv6ForVpc
OpenIPv6ForVpc:
Version: default
Type: MODULE::ACS::OOS::ExecuteAPI
Properties:
Prefix: open-ipv6-for-vpc
API: ModifyVpcAttribute
Method: POST
Parameters:
VpcId:
Ref: VpcId
EnableIPv6: true
Service: VPC
Condition: EnableIpv6ForVpc
Parameters:
VpcId:
Type: String
NetworkInterfaceId:
Type: String
Ipv6GatewayId:
Default: Null
Type: String
VswId:
Type: String
PublicIpv6Address:
Default: Disable
Type: String
Ipv6AddressId:
Default: Null
Type: String
Ipv6InternetBandwidthId:
Default: Null
Type: String
Ipv6CidrBlockNumber:
Type: Number
VswIpv6Address:
Type: String
Parameters:
VpcId:
Fn::Jq:
- First
- .[0].VpcId
- Fn::GetAtt:
- DsEcs
- Instances
NetworkInterfaceId:
Fn::Select:
- 0
- Fn::GetAtt:
- DsEni
- NetworkInterfaceIds
Ipv6GatewayId:
Fn::Jq:
- First
- .[0].Ipv6Gateways.Ipv6Gateway[0].Ipv6GatewayId
- Fn::If:
- UseExistedInstance
- Fn::Select:
- Result
- Fn::GetAtt:
- DsIpv6Gateway.Execution
- Outputs
- Null
- Fn::Select:
- not_exist
- {}
- Null
- invalid output(Output) of module{DsIpv6Gateway, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
VswId:
Fn::Jq:
- First
- .[0].VswitchId
- Fn::GetAtt:
- DsEcs
- Instances
PublicIpv6Address:
Ref: PublicIpv6Address
Ipv6AddressId:
Fn::Jq:
- First
- .[0].Ipv6Addresses.Ipv6Address[0].Ipv6AddressId
- Fn::If:
- UseExistedInstance
- Fn::Select:
- Result
- Fn::GetAtt:
- DsIpv6Addresses.Execution
- Outputs
- Null
- Fn::Select:
- not_exist
- {}
- Null
- invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
Ipv6InternetBandwidthId:
Fn::Jq:
- First
- .[0].Ipv6Addresses.Ipv6Address[0].Ipv6InternetBandwidth.Ipv6InternetBandwidthId
- Fn::If:
- UseExistedInstance
- Fn::Select:
- Result
- Fn::GetAtt:
- DsIpv6Addresses.Execution
- Outputs
- Null
- Fn::Select:
- not_exist
- {}
- Null
- invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false
Ipv6CidrBlockNumber:
Ref: Ipv6CidrBlockNumber
VswIpv6Address:
Fn::GetAtt:
- DsVsw
- Ipv6CidrBlock
Condition: UseExistedInstance
SecurityGroupIngress:
Type: ALIYUN::ECS::SecurityGroupIngress
Properties:
IpProtocol: icmpv6
SecurityGroupId:
Fn::Jq:
- First
- .[0].SecurityGroupIds[0]
- Fn::GetAtt:
- DsEcs
- Instances
NicType: intranet
PortRange: '-1/-1'
Ipv6SourceCidrIp: '::/0'
Condition: UseExistedInstance
Ipv6InternetBandwidth:
Type: ALIYUN::VPC::Ipv6InternetBandwidth
Properties:
InternetChargeType: PayByTraffic
Bandwidth: 1
Ipv6AddressId:
Fn::Jq:
- First
- .[0][0]
- Fn::GetAtt:
- EcsInstance
- Ipv6AddressIds
Ipv6GatewayId:
Ref: Ipv6Gateway
Condition: CreateAndEnableIpv6
Vpc:
Type: ALIYUN::ECS::VPC
Properties:
EnableIpv6: true
VpcName:
Fn::Sub: ${CommonName}-vpc
CidrBlock: 192.168.0.0/16
Condition: CreateInstance
DsEcs:
Type: DATASOURCE::ECS::Instances
Properties:
InstanceIds:
- Fn::If:
- UseExistedInstance
- Ref: EcsInstanceId
- Ref: EcsInstance
DsIpv6Addresses.Template:
Type: ALIYUN::OOS::Template
Properties:
Content:
Fn::Str:
Fn::If:
- DsIpv6Addresses.IsRPC
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
API: DescribeIpv6Addresses
Service: VPC
Parameters:
AssociatedInstanceId:
Ref: EcsInstanceId
AutoPaging: true
Description: ROS Execute API
- Outputs:
Result:
Type: List
Value: '{{ ExecuteAPI.Result }}'
FormatVersion: OOS-2019-06-01
Tasks:
- Action: ACS::ExecuteAPI
Outputs:
Result:
Type: List
ValueSelector: .
Name: ExecuteAPI
Properties:
Body:
Fn::If:
- DsIpv6Addresses.IsBodyEmpty
- Null
- ''
Parameters:
AssociatedInstanceId:
Ref: EcsInstanceId
Service: VPC
URI: ''
AutoPaging: true
Headers: {}
API: DescribeIpv6Addresses
Method: GET
Description: ROS Execute API
TemplateName:
Fn::Sub:
- ${__auto_generated__DsIpv6Addresses__Parameter__Prefix}-template-${ALIYUN::StackId}
- __auto_generated__DsIpv6Addresses__Parameter__Prefix: DescribeIpv6Addresses
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Addresses
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
VSwitch:
Type: ALIYUN::ECS::VSwitch
Properties:
VSwitchName:
Fn::Sub: ${CommonName}-vsw
Ipv6CidrBlock: 0
VpcId:
Ref: Vpc
CidrBlock: 192.168.0.0/24
ZoneId:
Ref: ZoneId
Condition: CreateInstance
Ipv6Gateway:
Type: ALIYUN::VPC::Ipv6Gateway
Properties:
VpcId:
Ref: Vpc
Condition: CreateInstance
DependsOn:
- VSwitch
EcsInstance:
Type: ALIYUN::ECS::InstanceGroup
Properties:
SystemDiskCategory: cloud_essd
VpcId:
Ref: Vpc
Ipv6AddressCount: 1
SecurityGroupId:
Ref: SecurityGroup
ImageId:
Ref: ImageId
InternetMaxBandwidthOut: 100
SpotStrategy: SpotAsPriceGo
VSwitchId:
Ref: VSwitch
Password:
Ref: InstancePassword
InstanceName:
Fn::Sub: ${CommonName}-ecs
InstanceType:
Ref: InstanceType
ZoneId:
Ref: ZoneId
MaxAmount: 1
Condition: CreateInstance
DsEni:
Type: DATASOURCE::ECS::NetworkInterfaces
Properties:
InstanceId:
Ref: EcsInstanceId
Type: Primary
Condition: UseExistedInstance
DsIpv6Gateway.Execution:
Type: ALIYUN::OOS::Execution
Properties:
TemplateName:
Ref: DsIpv6Gateway.Template
Condition: UseExistedInstance
Metadata:
ALIYUN::ROS::Module:
LogicalIdHierarchy: DsIpv6Gateway
TypeHierarchy: MODULE::ACS::OOS::ExecuteAPI
Metadata:
ALIYUN::ROS::Interface:
ParameterGroups:
- Parameters:
- InstanceSource
- ZoneId
- ImageId
- InstanceType
- InstancePassword
- EcsInstanceId
- PublicIpv6Address
Hidden:
- CommonName
- Ipv6CidrBlockNumber
{
"ROSTemplateFormatVersion": "2015-09-01",
"Mappings": {},
"Parameters": {
"EcsInstanceId": {
"AssociationPropertyMetadata": {
"Status": "Running",
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"UseExisted"
]
}
}
},
"Default": null,
"Required": true,
"Label": {
"zh-cn": "ECS实例ID",
"en": "ECS Instance ID"
},
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceId",
"Type": "String"
},
"CommonName": {
"Default": "config-ipv6",
"Type": "String"
},
"PublicIpv6Address": {
"AssociationPropertyMetadata": {
"ValueLabelMapping": {
"Enable": {
"zh-cn": "开通IPv6公网带宽",
"en": "Enable IPv6 Internet Bandwidth"
},
"Disable": {
"zh-cn": "不开通IPv6公网带宽",
"en": "Disable IPv6 Internet Bandwidth"
}
}
},
"AllowedValues": [
"Enable",
"Disable"
],
"Type": "String",
"Description": {
"zh-cn": "默认情况下,为ECS实例分配的IPv6地址仅具有私网通信能力,若您希望IPv6地址具有公网通信能力, 则需开通IPv6公网带宽。请从以上选项中选择您的配置。",
"en": "By default, the IPv6 address assigned to the ECS instance can be used only for communications over private networks. To allow communications over the Internet, you must enable IPv6 Internet bandwidth. Select your configuration from the preceding options."
},
"Label": {
"zh-cn": "配置IPv6公网带宽",
"en": "Configure IPv6 Internet Bandwidth"
}
},
"InstancePassword": {
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
}
},
"Description": {
"zh-cn": "服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)",
"en": "Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
},
"Confirm": true,
"Default": null,
"ConstraintDescription": {
"zh-cn": "长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)",
"en": "Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)"
},
"Label": {
"zh-cn": "实例密码",
"en": "Instance Password"
},
"NoEcho": true,
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"Type": "String"
},
"ImageId": {
"AssociationPropertyMetadata": {
"IsSupportCloudinit": true,
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
},
"SupportedImageOwnerAlias": [
"system"
]
},
"Default": "aliyun_3_9_x64_20G_alibase_20231219.vhd",
"Required": true,
"Label": {
"zh-cn": "实例镜像",
"en": "Image of Instance"
},
"AssociationProperty": "ALIYUN::ECS::Image::ImageId",
"Type": "String"
},
"InstanceSource": {
"Default": "CreateNew",
"AssociationPropertyMetadata": {
"ValueLabelMapping": {
"UseExisted": {
"zh-cn": "选择已有实例",
"en": "Select Existed Instance"
},
"CreateNew": {
"zh-cn": "创建新实例",
"en": "Create New Instance"
}
}
},
"AllowedValues": [
"CreateNew",
"UseExisted"
],
"Type": "String",
"Label": {
"zh-cn": "实例来源",
"en": "Instance Source"
}
},
"ZoneId": {
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
},
"AutoSelectFirst": true
},
"Default": null,
"Required": true,
"Label": {
"zh-cn": "可用区",
"en": "Availability Zone"
},
"AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
"Type": "String"
},
"Ipv6CidrBlockNumber": {
"AssociationProperty": "AutoCompleteInput",
"AssociationPropertyMetadata": {
"Length": 2,
"CharacterClasses": [
{
"Class": "number",
"min": 1
}
]
},
"Type": "Number"
},
"InstanceType": {
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Equals": [
"${InstanceSource}",
"CreateNew"
]
}
},
"SystemDiskCategory": "cloud_essd",
"SpotStrategy": "SpotAsPriceGo",
"InstanceChargeType": "PostPaid",
"ZoneId": "${ZoneId}"
},
"Default": null,
"Required": true,
"Label": {
"zh-cn": "实例类型",
"en": "Instance Type"
},
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
"Type": "String"
}
},
"Outputs": {
"EcsLoginAddress": {
"Description": {
"zh-cn": "ECS登录地址。",
"en": "Ecs login address."
},
"Value": {
"Fn::Sub": [
"https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs®ionId=${ALIYUN::Region}&instanceId=${InstanceId}",
{
"InstanceId": {
"Fn::If": [
"UseExistedInstance",
{
"Ref": "EcsInstanceId"
},
{
"Ref": "EcsInstance"
}
]
}
}
]
}
}
},
"Description": {
"zh-cn": "创建ECS实例并配置IPv6地址,支持新创建或现有实例,自动分配公网IPv6带宽。",
"en": "Create ECS instances and configure IPv6 addresses, supporting both new creations and existing instances, with automatic allocation of public IPv6 bandwidth."
},
"Conditions": {
"DsIpv6Addresses.IsBodyEmpty": {
"Fn::Equals": [
"",
""
]
},
"CreateInstance": {
"Fn::Equals": [
{
"Ref": "InstanceSource"
},
"CreateNew"
]
},
"DsIpv6Gateway.IsBodyEmpty": {
"Fn::Equals": [
"",
""
]
},
"UseExistedInstance": {
"Fn::Equals": [
{
"Ref": "InstanceSource"
},
"UseExisted"
]
},
"CreateAndEnableIpv6": {
"Fn::And": [
"CreateInstance",
{
"Fn::Equals": [
{
"Ref": "PublicIpv6Address"
},
"Enable"
]
}
]
},
"DsIpv6Addresses.IsRPC": {
"Fn::Not": {
"Fn::TransformNamespace": [
"Condition",
"DsIpv6Addresses.",
{
"Fn::Contains": [
[
"OSS",
"FC",
"SLS",
"CS"
],
"VPC"
]
}
]
}
},
"DsIpv6Gateway.IsRPC": {
"Fn::Not": {
"Fn::TransformNamespace": [
"Condition",
"DsIpv6Gateway.",
{
"Fn::Contains": [
[
"OSS",
"FC",
"SLS",
"CS"
],
"VPC"
]
}
]
}
}
},
"Resources": {
"DsVsw": {
"Type": "DATASOURCE::VPC::VSwitch",
"Properties": {
"VSwitchId": {
"Fn::Jq": [
"First",
".[0].VswitchId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
}
},
"Condition": "UseExistedInstance"
},
"DsIpv6Addresses.Execution": {
"Type": "ALIYUN::OOS::Execution",
"Properties": {
"TemplateName": {
"Ref": "DsIpv6Addresses.Template"
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Addresses",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
},
"DsIpv6Gateway.Template": {
"Type": "ALIYUN::OOS::Template",
"Properties": {
"Content": {
"Fn::Str": {
"Fn::If": [
"DsIpv6Gateway.IsRPC",
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"API": "DescribeIpv6Gateways",
"Service": "VPC",
"Parameters": {
"VpcId": {
"Fn::Jq": [
"First",
".[0].VpcId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
}
},
"AutoPaging": true
}
}
],
"Description": "ROS Execute API"
},
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"Body": {
"Fn::If": [
"DsIpv6Gateway.IsBodyEmpty",
null,
""
]
},
"Parameters": {
"VpcId": {
"Fn::Jq": [
"First",
".[0].VpcId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
}
},
"Service": "VPC",
"URI": "",
"AutoPaging": true,
"Headers": {},
"API": "DescribeIpv6Gateways",
"Method": "GET"
}
}
],
"Description": "ROS Execute API"
}
]
}
},
"TemplateName": {
"Fn::Sub": [
"${__auto_generated__DsIpv6Gateway__Parameter__Prefix}-template-${ALIYUN::StackId}",
{
"__auto_generated__DsIpv6Gateway__Parameter__Prefix": "DescribeIpv6Gateways"
}
]
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Gateway",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
},
"ConfigureIPv6Address": {
"Type": "ALIYUN::ROS::Stack",
"Properties": {
"TemplateBody": {
"ROSTemplateFormatVersion": "2015-09-01",
"Conditions": {
"Windows": {
"Fn::Equals": [
"windows",
{
"Ref": "OsType"
}
]
},
"Linux": {
"Fn::Equals": [
"linux",
{
"Ref": "OsType"
}
]
}
},
"Resources": {
"WindowsCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": {
"Fn::Sub": "# powershell\nWrite-Output \"Start\"\n$install_dir = \"C:\\Windows\\system32\"\n$install_path = \"$install_dir\\ecs-utils-ipv6.exe\"\n\n$Is64Bit = [Environment]::Is64BitOperatingSystem\nWrite-Output \"Is64BitOperatingSystem: $Is64Bit\"\n\nif(-not (Test-Path -Path $install_path)){\n # download the tool\n if ([Environment]::Is64BitOperatingSystem) {\n $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/64/ecs-utils-ipv6.exe' \n } else {\n $tool_url = 'https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/win/32/ecs-utils-ipv6.exe' \n }\n Write-Output \"Download ecs-utils-ipv6.exe form url $tool_url\"\n Invoke-WebRequest -uri $tool_url -OutFile $install_path\n Unblock-File $install_path\n}\n\n# run the tool\nWrite-Output \"Run ecs-utils-ipv6.exe\"\n$maxRetries = 10 \n$retryInterval = 10 \n$retryCount = 0 \n\nwhile ($retryCount -lt $maxRetries) {\n try {\n Start-Process -FilePath \"$install_path\" -ArgumentList \"--noenterkey\" -NoNewWindow\n Write-Output \"Successfully!\"\n break\n } catch {\n Write-Error \"run failed: $($_.Exception.Message). Start retry $($retryCount + 1)\"\n Start-Sleep -Seconds $retryInterval\n $retryCount++ \n }\n}\n\nif ($retryCount -eq $maxRetries) {\n Write-Error \"Failed!\"\n}"
},
"Type": "RunPowerShellScript",
"Sync": true,
"InstanceIds": [
{
"Ref": "InstanceId"
}
],
"Timeout": 3600
},
"Condition": "Windows",
"DependsOn": "WaiteWindowsReady"
},
"WaiteWindowsReady": {
"Type": "ALIYUN::ROS::Sleep",
"Properties": {
"CreateDuration": 300
},
"Condition": "Windows"
},
"LinuxCommand": {
"Type": "ALIYUN::ECS::RunCommand",
"Properties": {
"CommandContent": {
"Fn::Sub": "#!/bin/bash\n\n# script exit code:\n# 0 - success\n# 1 - unsupported system\n# 2 - network not available\n# 3 - failed to run ecs-utils-ipv6 tool\n# 4 - failed to modify /etc/eni_utils/eni-function\n\nfunction unsupported_system() {\n log_fatal 1 \"Unsupported System: $1\"\n}\n\nfunction log_info() {\n printf \"%s [INFO] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n}\n\nfunction log_error() {\n printf \"%s [ERROR] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n}\n\nfunction log_fatal() {\n printf \"\\n========================================================================\\n\"\n printf \"%s [FATAL] %s\\n\" \"$(date '+%Y-%m-%d %H:%M:%S')\" \"$1\"\n printf \"\\n========================================================================\\n\"\n exit $1\n}\n\nfunction debug_exec(){\n local cmd=\"$@\"\n log_info \"$cmd\"\n eval \"$cmd\"\n ret=$?\n echo \"\"\n log_info \"$cmd, exit code: $ret\"\n return $ret\n}\n\nfunction check_network_available() {\n log_info \"ping ecs-image-utils.oss-cn-hangzhou.aliyuncs.com ...\"\n if ! debug_exec ping -c 4 ecs-image-utils.oss-cn-hangzhou.aliyuncs.com; then\n log_fatal 2 \"Could not connect to https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com\"\n fi\n}\n\nfunction run_ipv6_tool() {\n log_info \"run ecs-utils-ipv6 tool\"\n debug_exec chmod +x ./ecs-utils-ipv6\n \n if ! debug_exec ./ecs-utils-ipv6; then\n log_fatal 3 \"Failed to run ecs-utils-ipv6 tool\"\n fi\n}\n\nfunction check_multi_eni_util() {\n log_info \"check multi-nic-util config\"\n if test -f /sbin/eni-ifscan; then\n \n if ! debug_exec \"sed -i 's/IPV6INIT=no/IPV6INIT=yes\\n DHCPV6C=yes/g' /etc/eni_utils/eni-function\"; then\n log_fatal 4 \"Failed to modify /etc/eni_utils/eni-function\"\n fi\n fi\n}\n\nlog_info \"System Information:\"\nif ! lsb_release -a; then\n unsupported_system\nfi;\necho \"\"\ncheck_network_available\n\nRHEL=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/rhel/ecs-utils-ipv6\nDebian=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/debian/ecs-utils-ipv6\nSLES=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/sles/ecs-utils-ipv6\nFreeBSD=https://ecs-image-utils.oss-cn-hangzhou.aliyuncs.com/ipv6/freebsd/ecs-utils-ipv6\n\nlinux=$(lsb_release -a | grep \"Distributor ID:\" | cut -d':' -f2 | cut -d '(' -f1 | xargs echo -n)\ncase $linux in\n CentOS|RedHat|Fedora|Aliyun|AlibabaCloud|Fedora|AnolisOS) wget --timeout=10 -q -O ecs-utils-ipv6 $RHEL ;;\n Debian|Ubuntu) wget --timeout=10 -q -O ecs-utils-ipv6 $Debian ;; \n SUSE|OpenSUSE) wget --timeout=10 -q -O ecs-utils-ipv6 $SLES ;;\n FreeBSD) wget --timeout=10 -q -O ecs-utils-ipv6 $FreeBSD ;;\n *) unsupported_system $linux ;;\nesac\n\nrun_ipv6_tool\ncheck_multi_eni_util"
},
"Type": "RunShellScript",
"Sync": true,
"InstanceIds": [
{
"Ref": "InstanceId"
}
],
"Timeout": 3600
},
"Condition": "Linux"
}
},
"Parameters": {
"OsType": {
"Default": null,
"Type": "String"
},
"InstanceId": {
"Type": "String"
}
}
},
"Parameters": {
"OsType": {
"Fn::Jq": [
"First",
".[0].OSType",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"InstanceId": {
"Fn::If": [
"UseExistedInstance",
{
"Ref": "EcsInstanceId"
},
{
"Ref": "EcsInstance"
}
]
}
}
},
"DependsOn": [
"AssignIpv6Address"
]
},
"SecurityGroup": {
"Type": "ALIYUN::ECS::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [
{
"PortRange": "3389/3389",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "tcp"
},
{
"PortRange": "-1/-1",
"SourceCidrIp": "0.0.0.0/0",
"IpProtocol": "icmp"
},
{
"PortRange": "-1/-1",
"Ipv6SourceCidrIp": "::/0",
"IpProtocol": "icmpv6"
}
],
"VpcId": {
"Ref": "Vpc"
},
"SecurityGroupName": {
"Fn::Sub": "${CommonName}-sg"
}
},
"Condition": "CreateInstance"
},
"AssignIpv6Address": {
"Type": "ALIYUN::ROS::Stack",
"Properties": {
"TemplateBody": {
"ROSTemplateFormatVersion": "2015-09-01",
"Conditions": {
"AssignIpv6Addresses": {
"Fn::Equals": [
null,
{
"Ref": "Ipv6AddressId"
}
]
},
"EnableIpv6ForVpc": {
"Fn::Equals": [
null,
{
"Ref": "Ipv6GatewayId"
}
]
},
"EnableIpv6ForVsw": {
"Fn::Equals": [
true,
{
"Fn::Contains": [
[
null,
""
],
{
"Ref": "VswIpv6Address"
}
]
}
]
},
"Ipv6InternetBandwidth": {
"Fn::And": [
{
"Fn::Equals": [
{
"Fn::If": [
"AssignIpv6Addresses",
null,
""
]
},
{
"Ref": "Ipv6InternetBandwidthId"
}
]
},
{
"Fn::Equals": [
{
"Ref": "PublicIpv6Address"
},
"Enable"
]
}
]
}
},
"Resources": {
"IpV6Address": {
"Type": "ALIYUN::ECS::AssignIpv6Addresses",
"Properties": {
"Ipv6AddressCount": 1,
"NetworkInterfaceId": {
"Ref": "NetworkInterfaceId"
}
},
"Condition": "AssignIpv6Addresses",
"DependsOn": "OpenIPv6ForVsw"
},
"Ipv6InternetBandwidth": {
"Type": "ALIYUN::VPC::Ipv6InternetBandwidth",
"Properties": {
"InternetChargeType": "PayByTraffic",
"Bandwidth": 1,
"Ipv6AddressId": {
"Fn::If": [
"AssignIpv6Addresses",
{
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"IpV6Address",
"Ipv6AddressIds"
]
}
]
},
{
"Ref": "Ipv6AddressId"
}
]
},
"Ipv6GatewayId": {
"Fn::If": [
"EnableIpv6ForVpc",
{
"Ref": "Ipv6Gateway"
},
{
"Ref": "Ipv6GatewayId"
}
]
}
},
"Condition": "Ipv6InternetBandwidth",
"DependsOn": "Sleep"
},
"Sleep": {
"Type": "ALIYUN::ROS::Sleep",
"Properties": {
"CreateDuration": 60
},
"Condition": "AssignIpv6Addresses",
"DependsOn": "IpV6Address"
},
"OpenIPv6ForVsw": {
"Version": "default",
"Type": "MODULE::ACS::OOS::ExecuteAPI",
"Properties": {
"Prefix": "open-ipv6-for-vsw",
"API": "ModifyVSwitchAttribute",
"Method": "POST",
"Parameters": {
"Ipv6CidrBlock": {
"Ref": "Ipv6CidrBlockNumber"
},
"VSwitchId": {
"Ref": "VswId"
},
"EnableIPv6": true
},
"Service": "VPC"
},
"Condition": "EnableIpv6ForVsw",
"DependsOn": "Ipv6Gateway"
},
"Ipv6Gateway": {
"Type": "ALIYUN::VPC::Ipv6Gateway",
"Properties": {
"VpcId": {
"Ref": "VpcId"
}
},
"Condition": "EnableIpv6ForVpc",
"DependsOn": "OpenIPv6ForVpc"
},
"OpenIPv6ForVpc": {
"Version": "default",
"Type": "MODULE::ACS::OOS::ExecuteAPI",
"Properties": {
"Prefix": "open-ipv6-for-vpc",
"API": "ModifyVpcAttribute",
"Method": "POST",
"Parameters": {
"VpcId": {
"Ref": "VpcId"
},
"EnableIPv6": true
},
"Service": "VPC"
},
"Condition": "EnableIpv6ForVpc"
}
},
"Parameters": {
"VpcId": {
"Type": "String"
},
"NetworkInterfaceId": {
"Type": "String"
},
"Ipv6GatewayId": {
"Default": null,
"Type": "String"
},
"VswId": {
"Type": "String"
},
"PublicIpv6Address": {
"Default": "Disable",
"Type": "String"
},
"Ipv6AddressId": {
"Default": null,
"Type": "String"
},
"Ipv6InternetBandwidthId": {
"Default": null,
"Type": "String"
},
"Ipv6CidrBlockNumber": {
"Type": "Number"
},
"VswIpv6Address": {
"Type": "String"
}
}
},
"Parameters": {
"VpcId": {
"Fn::Jq": [
"First",
".[0].VpcId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"NetworkInterfaceId": {
"Fn::Select": [
0,
{
"Fn::GetAtt": [
"DsEni",
"NetworkInterfaceIds"
]
}
]
},
"Ipv6GatewayId": {
"Fn::Jq": [
"First",
".[0].Ipv6Gateways.Ipv6Gateway[0].Ipv6GatewayId",
{
"Fn::If": [
"UseExistedInstance",
{
"Fn::Select": [
"Result",
{
"Fn::GetAtt": [
"DsIpv6Gateway.Execution",
"Outputs"
]
},
null
]
},
{
"Fn::Select": [
"not_exist",
{},
null,
"invalid output(Output) of module{DsIpv6Gateway, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
]
}
]
}
]
},
"VswId": {
"Fn::Jq": [
"First",
".[0].VswitchId",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"PublicIpv6Address": {
"Ref": "PublicIpv6Address"
},
"Ipv6AddressId": {
"Fn::Jq": [
"First",
".[0].Ipv6Addresses.Ipv6Address[0].Ipv6AddressId",
{
"Fn::If": [
"UseExistedInstance",
{
"Fn::Select": [
"Result",
{
"Fn::GetAtt": [
"DsIpv6Addresses.Execution",
"Outputs"
]
},
null
]
},
{
"Fn::Select": [
"not_exist",
{},
null,
"invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
]
}
]
}
]
},
"Ipv6InternetBandwidthId": {
"Fn::Jq": [
"First",
".[0].Ipv6Addresses.Ipv6Address[0].Ipv6InternetBandwidth.Ipv6InternetBandwidthId",
{
"Fn::If": [
"UseExistedInstance",
{
"Fn::Select": [
"Result",
{
"Fn::GetAtt": [
"DsIpv6Addresses.Execution",
"Outputs"
]
},
null
]
},
{
"Fn::Select": [
"not_exist",
{},
null,
"invalid output(Output) of module{DsIpv6Addresses, MODULE::ACS::OOS::ExecuteAPI}, as condition(UseExistedInstance) is false"
]
}
]
}
]
},
"Ipv6CidrBlockNumber": {
"Ref": "Ipv6CidrBlockNumber"
},
"VswIpv6Address": {
"Fn::GetAtt": [
"DsVsw",
"Ipv6CidrBlock"
]
}
}
},
"Condition": "UseExistedInstance"
},
"SecurityGroupIngress": {
"Type": "ALIYUN::ECS::SecurityGroupIngress",
"Properties": {
"IpProtocol": "icmpv6",
"SecurityGroupId": {
"Fn::Jq": [
"First",
".[0].SecurityGroupIds[0]",
{
"Fn::GetAtt": [
"DsEcs",
"Instances"
]
}
]
},
"NicType": "intranet",
"PortRange": "-1/-1",
"Ipv6SourceCidrIp": "::/0"
},
"Condition": "UseExistedInstance"
},
"Ipv6InternetBandwidth": {
"Type": "ALIYUN::VPC::Ipv6InternetBandwidth",
"Properties": {
"InternetChargeType": "PayByTraffic",
"Bandwidth": 1,
"Ipv6AddressId": {
"Fn::Jq": [
"First",
".[0][0]",
{
"Fn::GetAtt": [
"EcsInstance",
"Ipv6AddressIds"
]
}
]
},
"Ipv6GatewayId": {
"Ref": "Ipv6Gateway"
}
},
"Condition": "CreateAndEnableIpv6"
},
"Vpc": {
"Type": "ALIYUN::ECS::VPC",
"Properties": {
"EnableIpv6": true,
"VpcName": {
"Fn::Sub": "${CommonName}-vpc"
},
"CidrBlock": "192.168.0.0/16"
},
"Condition": "CreateInstance"
},
"DsEcs": {
"Type": "DATASOURCE::ECS::Instances",
"Properties": {
"InstanceIds": [
{
"Fn::If": [
"UseExistedInstance",
{
"Ref": "EcsInstanceId"
},
{
"Ref": "EcsInstance"
}
]
}
]
}
},
"DsIpv6Addresses.Template": {
"Type": "ALIYUN::OOS::Template",
"Properties": {
"Content": {
"Fn::Str": {
"Fn::If": [
"DsIpv6Addresses.IsRPC",
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"API": "DescribeIpv6Addresses",
"Service": "VPC",
"Parameters": {
"AssociatedInstanceId": {
"Ref": "EcsInstanceId"
}
},
"AutoPaging": true
}
}
],
"Description": "ROS Execute API"
},
{
"Outputs": {
"Result": {
"Type": "List",
"Value": "{{ ExecuteAPI.Result }}"
}
},
"FormatVersion": "OOS-2019-06-01",
"Tasks": [
{
"Action": "ACS::ExecuteAPI",
"Outputs": {
"Result": {
"Type": "List",
"ValueSelector": "."
}
},
"Name": "ExecuteAPI",
"Properties": {
"Body": {
"Fn::If": [
"DsIpv6Addresses.IsBodyEmpty",
null,
""
]
},
"Parameters": {
"AssociatedInstanceId": {
"Ref": "EcsInstanceId"
}
},
"Service": "VPC",
"URI": "",
"AutoPaging": true,
"Headers": {},
"API": "DescribeIpv6Addresses",
"Method": "GET"
}
}
],
"Description": "ROS Execute API"
}
]
}
},
"TemplateName": {
"Fn::Sub": [
"${__auto_generated__DsIpv6Addresses__Parameter__Prefix}-template-${ALIYUN::StackId}",
{
"__auto_generated__DsIpv6Addresses__Parameter__Prefix": "DescribeIpv6Addresses"
}
]
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Addresses",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
},
"VSwitch": {
"Type": "ALIYUN::ECS::VSwitch",
"Properties": {
"VSwitchName": {
"Fn::Sub": "${CommonName}-vsw"
},
"Ipv6CidrBlock": 0,
"VpcId": {
"Ref": "Vpc"
},
"CidrBlock": "192.168.0.0/24",
"ZoneId": {
"Ref": "ZoneId"
}
},
"Condition": "CreateInstance"
},
"Ipv6Gateway": {
"Type": "ALIYUN::VPC::Ipv6Gateway",
"Properties": {
"VpcId": {
"Ref": "Vpc"
}
},
"Condition": "CreateInstance",
"DependsOn": [
"VSwitch"
]
},
"EcsInstance": {
"Type": "ALIYUN::ECS::InstanceGroup",
"Properties": {
"SystemDiskCategory": "cloud_essd",
"VpcId": {
"Ref": "Vpc"
},
"Ipv6AddressCount": 1,
"SecurityGroupId": {
"Ref": "SecurityGroup"
},
"ImageId": {
"Ref": "ImageId"
},
"InternetMaxBandwidthOut": 100,
"SpotStrategy": "SpotAsPriceGo",
"VSwitchId": {
"Ref": "VSwitch"
},
"Password": {
"Ref": "InstancePassword"
},
"InstanceName": {
"Fn::Sub": "${CommonName}-ecs"
},
"InstanceType": {
"Ref": "InstanceType"
},
"ZoneId": {
"Ref": "ZoneId"
},
"MaxAmount": 1
},
"Condition": "CreateInstance"
},
"DsEni": {
"Type": "DATASOURCE::ECS::NetworkInterfaces",
"Properties": {
"InstanceId": {
"Ref": "EcsInstanceId"
},
"Type": "Primary"
},
"Condition": "UseExistedInstance"
},
"DsIpv6Gateway.Execution": {
"Type": "ALIYUN::OOS::Execution",
"Properties": {
"TemplateName": {
"Ref": "DsIpv6Gateway.Template"
}
},
"Condition": "UseExistedInstance",
"Metadata": {
"ALIYUN::ROS::Module": {
"LogicalIdHierarchy": "DsIpv6Gateway",
"TypeHierarchy": "MODULE::ACS::OOS::ExecuteAPI"
}
}
}
},
"Metadata": {
"ALIYUN::ROS::Interface": {
"ParameterGroups": [
{
"Parameters": [
"InstanceSource",
"ZoneId",
"ImageId",
"InstanceType",
"InstancePassword",
"EcsInstanceId",
"PublicIpv6Address"
]
}
],
"Hidden": [
"CommonName",
"Ipv6CidrBlockNumber"
]
}
}
}更多示例,请参考包含此资源的公共模板。