ROS模板参数的进化之路

在使用ROS资源编排产品创建资源时,使用参数(Parameters)可提高模板的灵活性和可复用性,为了保证资源能顺利创建,通常需要打开多个控制台查找资源参数信息,这种体验是非常糟糕的。我们不喜欢手动输出参数,更加希望用鼠标点点就能选到正确的参数。

AssociationProperty和AssociationPropertyMetadata

在模板中使用 AssociationPropertyAssociationPropertyMetadata 字段能动态的获取对应的属性。例如 ImageId 参数需要填写ECS的镜像ID,镜像ID可是一大长串的字符,而且公共镜像随着时间的推移,镜像ID还有可能变化,此时如果使用 AssociationProperty 就能动态的获取到所有的镜像ID。

{
    "Parameters":
    {
        "ImageId":
        {
            "AssociationProperty": "ALIYUN::ECS::Instance::ImageId",
            "Description": "请选择镜像",
            "Label": "镜像",
            "Type": "String"
        }
    },
    "ROSTemplateFormatVersion": "2015-09-01"
}

注:上述模板无法直接创建资源,仅做参数选填演示

复制上述模板到 ROS 控制台创建资源栈,可体验到如下效果
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_ 是为了让参数按照指定的顺序显示
注:上述模板无法直接创建资源,仅做参数选填演示

实际效果如下图所示
ROS模板参数的进化之路

OOS参数仓库

AssociationPropertyAssociationPropertyMetadata 还是有局限性,仅限于系统支持的部分特定参数,但是有些自己的业务数据参数又臭又长,它又不是类似云产品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"
}

用上面模板进入ROS控制台体验效果如下
ROS模板参数的进化之路

GetTemplateParameterConstraints 查询模板参数取值

结合上述2个功能,基本所有参数都不用手动去填写了,但是还是有一些资源创建失败的场景。

Resource CREATE failed: ResponseException: resources.Database: The resource is out of usage. Code: OperationDenied RequestId: E5AAC333-XXXXXX-27605816C0C0

ResponseException: 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等实例都在同一个可用区,而特定规格的实例通常只是在特定的可用区有售卖,要选择三个产品共同都适用的可用区,AssociationPropertyAssociationPropertyMetadata 就无能为力了。

参数查询就能很方便的解决此问题,而且不需要在模板中添加额外的字段。把下面的模板复制到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 等参数,又会根据选择的地域信息来动态查询。
ROS模板参数的进化之路

More and more

个人认为,用户交互比较好的体验是 Common Buy 的购买页面,拥有统一的样式与风格,毕竟是经过各自产品各种内部接口不断打磨后的结果。但如果要是多个产品组合,完成一个功能的时候,common buy这种方式显得力不从心。ROS 模板中的参数,能直接解析成类似产品购买页面的表单,那购买多产品组合形态,购买一个解决方案就和购买单个产品一样丝滑了。

上一篇:移动端性能优化系列—启动速度


下一篇:UILabel attributedText html 图片自适应