在使用ROS资源编排产品创建资源时,使用参数(Parameters)可提高模板的灵活性和可复用性,为了保证资源能顺利创建,通常需要打开多个控制台查找资源参数信息,这种体验是非常糟糕的。我们不喜欢手动输出参数,更加希望用鼠标点点就能选到正确的参数。
AssociationProperty和AssociationPropertyMetadata
在模板中使用 AssociationProperty
和 AssociationPropertyMetadata
字段能动态的获取对应的属性。例如 ImageId
参数需要填写ECS的镜像ID,镜像ID可是一大长串的字符,而且公共镜像随着时间的推移,镜像ID还有可能变化,此时如果使用 AssociationProperty
就能动态的获取到所有的镜像ID。
{
"Parameters":
{
"ImageId":
{
"AssociationProperty": "ALIYUN::ECS::Instance::ImageId",
"Description": "请选择镜像",
"Label": "镜像",
"Type": "String"
}
},
"ROSTemplateFormatVersion": "2015-09-01"
}
注:上述模板无法直接创建资源,仅做参数选填演示
复制上述模板到 ROS 控制台创建资源栈,可体验到如下效果
如果还希望对动态查找的结果做筛选,则可以使用 AssociationPropertyMetadata
来指定。例如 VSwitchId
参数需要填写某个 Vpc 下的某个可用区的交换机ID,则可以参考如下模板。
{
"Metadata":
{
"ALIYUN::ROS::Interface":
{
"ParameterGroups":
[
{
"Parameters": [
"VpcId",
"ZoneId",
"VSwitchId"
]
}
]
}
},
"Parameters":
{
"VSwitchId":
{
"AssociationProperty": "ALIYUN::ECS::VSwitch::VSwitchId",
"AssociationPropertyMetadata":
{
"VpcId": "${VpcId}",
"ZoneId": "${ZoneId}"
},
"Description": "请选择需要的交换机",
"Label": "交换机",
"Type": "String"
},
"VpcId":
{
"AssociationProperty": "ALIYUN::ECS::VPC::VPCId",
"Description": "请选择需要的Vpc",
"Label": "VpcId",
"Type": "String"
},
"ZoneId":
{
"AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
"Description": "请选择可用区",
"Label": "可用区Id",
"Type": "String"
}
},
"ROSTemplateFormatVersion": "2015-09-01"
}
注: 模板中的 _Metadata_
是为了让参数按照指定的顺序显示
注:上述模板无法直接创建资源,仅做参数选填演示
实际效果如下图所示
OOS参数仓库
AssociationProperty
和 AssociationPropertyMetadata
还是有局限性,仅限于系统支持的部分特定参数,但是有些自己的业务数据参数又臭又长,它又不是类似云产品ID这种能动态查询的,例如密钥数据、脚本数据、SQL语句或者某些需要加密的数据,每次手动去复制粘贴也非常繁琐。
参数仓库就能很好的解决这类参数,把密钥数据、脚本数据、SQL语句这些扔到参数仓库中,给它取一个好听的名字,填写参数时直接引用即可。
然后再模板中把 Type 设置为参数仓库的类型即可。
ALIYUN::OOS::Parameter::Value
表示普通参数类型ALIYUN::OOS::SecretParameter::Value
表示加密参数类型
{
"Parameters":
{
"PemData":
{
"Description": "请输入公钥密钥",
"Label": "公钥信息",
"Type": "ALIYUN::OOS::Parameter::Value"
}
},
"ROSTemplateFormatVersion": "2015-09-01"
}
GetTemplateParameterConstraints 查询模板参数取值
结合上述2个功能,基本所有参数都不用手动去填写了,但是还是有一些资源创建失败的场景。
Resource CREATE failed: ResponseException: resources.Database: The resource is out of usage. Code: OperationDenied RequestId: E5AAC333-XXXXXX-27605816C0C0ResponseException: resources.EcsInstance: The resource is out of stock in the specified zone. Please try other types, or choose other regions and zones. Code: OperationDenied.NoStock RequestId: EEC76BD4-XXXXXX-04BB4D1C150C
看到上述报错,真是头都大了。而且资源编排主要是多产品组合购买,某些参数是需要更加苛刻的条件。
我希望购买的ECS、RDS、Redis等实例都在同一个可用区,而特定规格的实例通常只是在特定的可用区有售卖,要选择三个产品共同都适用的可用区,AssociationProperty
和 AssociationPropertyMetadata
就无能为力了。
参数查询就能很方便的解决此问题,而且不需要在模板中添加额外的字段。把下面的模板复制到ROS控制台体验一下吧。
{
"Metadata":
{
"ALIYUN::ROS::Interface":
{
"ParameterGroups":
[
{
"Parameters":
[
"ZoneInfo",
"ECSInstanceType",
"RDSInstanceClass",
"RedisInstanceClass"
]
}
]
}
},
"Parameters":
{
"ECSInstanceType":
{
"Type": "String"
},
"RDSInstanceClass":
{
"Type": "String"
},
"RedisInstanceClass":
{
"Type": "String"
},
"ZoneInfo":
{
"Type": "String"
}
},
"ROSTemplateFormatVersion": "2015-09-01",
"Resources":
{
"ECS":
{
"Properties":
{
"InstanceType":
{
"Ref": "ECSInstanceType"
},
"ZoneId":
{
"Ref": "ZoneInfo"
},
"ImageId": "centos_7_8_x64_20G_alibase_20211028.vhd",
"SystemDiskCategory": "cloud_essd"
},
"Type": "ALIYUN::ECS::Instance"
},
"RDS":
{
"Properties":
{
"Category": "HighAvailability",
"DBInstanceClass":
{
"Ref": "RDSInstanceClass"
},
"Engine": "MySQL",
"EngineVersion": "5.6",
"ZoneId":
{
"Ref": "ZoneInfo"
}
},
"Type": "ALIYUN::RDS::DBInstance"
},
"Redis":
{
"Properties":
{
"EngineVersion": "4.0",
"InstanceClass":
{
"Ref": "RedisInstanceClass"
},
"ZoneId":
{
"Ref": "ZoneInfo"
}
},
"Type": "ALIYUN::REDIS::Instance"
}
}
}
注:上述模板无法直接创建资源,仅做参数选填演示ZoneInfo
参数是分布根据ECS、RDS、Redis三个资源的其他属性来分布查询,然后取交集所得,而 ECSInstanceType, RDSInstanceClass, RedisInstanceClass
等参数,又会根据选择的地域信息来动态查询。
More and more
个人认为,用户交互比较好的体验是 Common Buy 的购买页面,拥有统一的样式与风格,毕竟是经过各自产品各种内部接口不断打磨后的结果。但如果要是多个产品组合,完成一个功能的时候,common buy这种方式显得力不从心。ROS 模板中的参数,能直接解析成类似产品购买页面的表单,那购买多产品组合形态,购买一个解决方案就和购买单个产品一样丝滑了。