命令中使用自定义参数

云助手支持使用自定义参数或内置环境参数来灵活调整命令内容,类似于模板变量的功能。同时,也可以在云助手命令中结合OOS的参数仓库功能,更为方便和安全地管理自定义参数。本文将详细介绍其使用方法。

前提条件

  • 实例的状态必须为运行中(Running)。

  • 实例已安装云助手Agent,且云助手Agent版本需要高于以下对应的版本。具体操作,请参见安装云助手Agent

    • Linux:2.2.3.309

    • Windows:2.1.3.309

使用说明

  • 通过API使用自定义参数执行云助手命令。

    调用RunCommandInvokeCommand执行云助手命令时,可以通过指定参数EnableParameter=true启用自定义参数功能,在CommandContent中使用{{}}方式定义自定义参数。在使用自定义参数时,存在以下限制:

    • {{}}内参数名前后的空格以及换行符会被忽略。

    • 自定义参数个数不能超过20个。

    • 自定义参数名仅允许a-zA-Z0-9-_的组合,且不区分大小写。

    • 不支持acs::前缀指定非内置参数,支持的内置环境参数,请参见内置环境参数

    • 单个参数名不能超过64字节。

  • ECS控制台云助手中使用自定义参数。

    云助手命令中自定义参数仅支持使用内置环境参数,且自定义参数个数不能超过20个。支持的内置环境参数,请参见内置环境参数

使用自定义参数

在云助手命令中使用自定义参数,可以更加灵活地编写脚本,提高命令的复用性。例如,在您的Linux实例中,存在一个定时执行的脚本,该脚本需要根据实际情况灵活地设置其执行频率。

import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.RunCommandRequest;
import com.aliyun.teaopenapi.models.Config;

import java.util.Collections;
import java.util.List;


public class EcsService {

    /**
     * 从环境变量中获取AccessKeyId、AccessKeySecret
     */
    private static final String ACCESS_KEY_ID = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
    private static final String ACCESS_KEY_SECRET = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

    public static void main(String[] args_) throws Exception {
        // 地域ID
        String regionId = "cn-hangzhou";
        Config config = new Config()
                .setAccessKeyId(ACCESS_KEY_ID)
                .setAccessKeySecret(ACCESS_KEY_SECRET)
                .setRegionId(regionId);
        Client ecsClient = new Client(config);
        List<String> instanceIds = Collections.singletonList("i-bp1h23xufsi8XXXXXXXX");
        // 待执行命令内容,其中/path/to/your/script.sh需要替换为待执行脚本
        String commandContent = "#!/bin/bash\n " +
                "(crontab -l 2>/dev/null; echo \"{{cron}} /path/to/your/script.sh\") | crontab -";
        // 命令执行超时时间
        long commandTimeOut = 60;
        RunCommandRequest request = new RunCommandRequest();
        request.setRegionId(regionId);
        request.setType("RunShellScript");
        // 开启自定义参数功能
        request.setEnableParameter(true);
        // 设置自定义参数cron的值
        request.setParameters(Collections.singletonMap("cron", "0 2 * * *"));
        request.setCommandContent(commandContent);
        request.setInstanceId(instanceIds);
        request.setTimeout(commandTimeOut);
        ecsClient.runCommand(request);
    }
}
import json
import os

from alibabacloud_ecs20140526 import models as ecs_20140526_models
from alibabacloud_ecs20140526.client import Client as Ecs20140526Client
from alibabacloud_tea_openapi import models as open_api_models

ACCESS_KEY_ID = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
ACCESS_KEY_SECRET = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")


def get_ecs_client(region_id):
    config = open_api_models.Config(
        access_key_id=ACCESS_KEY_ID,
        access_key_secret=ACCESS_KEY_SECRET,
        region_id=region_id
    )
    return Ecs20140526Client(config)


def main():
    # 地域ID
    region_id = "cn-hangzhou"
    client = get_ecs_client(region_id)
    # 要执行命令的ECS实例ID
    instance_ids = ["i-bp1h23xufsi8XXXXXXXX"]
    # 待执行命令内容,其中/path/to/your/script.sh为待执行脚本
    command_content = "#!/bin/bash\n (crontab -l 2>/dev/null; echo \"{{cron}} /path/to/your/script.sh\") | crontab -"
    # 命令执行超时时间,单位为秒
    command_timeout = 60
    # 适用于Linux实例的Shell命令:RunShellScript
    command_type = "RunShellScript"

    # 执行命令
    request = ecs_20140526_models.RunCommandRequest()
    request.region_id = region_id
    request.type = command_type
    # 开启自定义参数功能
    request.enable_parameter = True
    # 设置自定义参数的值
    request.parameters = {"cron": "0 2 * * *"}
    request.command_content = command_content
    request.instance_id = instance_ids
    request.timeout = command_timeout
    response = client.run_command(request)
    print("execute_command result:", json.dumps(response.to_map()['body']))


if __name__ == "__main__":
    main()

使用OOS参数

系统运维管理OOS提供参数仓库功能,支持普通参数和加密参数。您可以在云助手命令中结合OOS的参数仓库功能,更为方便和安全地管理自定义参数。使用系统运维管理OOS提供参数仓库功能时,需要先开通系统运维管理OOS。更多信息,请参见什么是系统运维管理

使用普通参数

如果您的命令不涉及敏感数据,可以使用普通参数。以在Linux实例中增加新用户为例,介绍如何在云助手命令中使用OOS参数仓库的普通参数。

  1. 通过系统运维管理OOS的参数仓库创建普通参数。具体操作,请参见普通参数

    以下示例表示在普通参数中新增一个username参数,取值为user01,您可以根据实际情况修改。

    名称

    示例值

    参数名称

    username

    参数类型

    String

    user01

  2. 调用API执行云助手命令。

    使用RAM用户通过云助手命令为Linux实例创建一个新用户,命令内容为adduser {{oos:username}}。其中,{{oos:username}}表示新用户名由OOS参数仓库的普通参数username定义。

    说明

    RAM用户授予允许使用云助手执行包含OSS普通参数的命令,具体权限策略信息,请参见在命令中使用OSS普通参数

    import com.aliyun.ecs20140526.Client;
    import com.aliyun.ecs20140526.models.RunCommandRequest;
    import com.aliyun.ecs20140526.models.RunCommandResponse;
    import com.aliyun.teaopenapi.models.Config;
    
    import java.util.Arrays;
    import java.util.List;
    
    public class EcsService {
        public static void main(String[] args_) throws Exception {
            // 地域ID
            String regionId = "cn-hangzhou";
            Config config = new Config()
                    .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                    .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                    .setRegionId(regionId);
            Client ecsClient = new Client(config);
            RunCommandRequest request = new RunCommandRequest();
            request.setRegionId(regionId);
            request.setType("RunShellScript");
            // 开启自定义参数功能
            request.setEnableParameter(true);
            // 待执行命令内容
            String commandContent = "adduser {{oos:username}}";
            request.setCommandContent(commandContent);
            List<String> instanceIds = Arrays.asList("i-bp1h23xufsi8XXXXXXXX");
            request.setInstanceId(instanceIds);
            // 命令执行超时时间
            request.setTimeout(60L);
            RunCommandResponse response = ecsClient.runCommand(request);
            System.out.println(new Gson().toJson(response.getBody()));
        }
    }
    
    import json
    import os
    
    from alibabacloud_ecs20140526 import models as ecs_20140526_models
    from alibabacloud_ecs20140526.client import Client as Ecs20140526Client
    from alibabacloud_tea_openapi import models as open_api_models
    
    ACCESS_KEY_ID = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
    ACCESS_KEY_SECRET = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    
    
    def get_ecs_client(region_id):
        config = open_api_models.Config(
            access_key_id=ACCESS_KEY_ID,
            access_key_secret=ACCESS_KEY_SECRET,
            region_id=region_id
        )
        return Ecs20140526Client(config)
    
    
    def main():
        # 地域ID
        region_id = "cn-hangzhou"
        client = get_ecs_client(region_id)
        # 要执行命令的ECS实例ID
        instance_ids = ["i-bp1h23xufsi8XXXXXXXX"]
        # 待执行命令内容
        command_content = "adduser {{oos:username}}"
        # 命令执行超时时间,单位为秒
        command_timeout = 60
        # 适用于Linux实例的Shell命令:RunShellScript
        command_type = "RunShellScript"
    
        # 执行命令
        request = ecs_20140526_models.RunCommandRequest()
        request.region_id = region_id
        request.type = command_type
        # 开启自定义参数功能
        request.enable_parameter = True
        request.command_content = command_content
        request.instance_id = instance_ids
        request.timeout = command_timeout
        response = client.run_command(request)
        print("execute_command result:", json.dumps(response.to_map()['body']))
    
    
    if __name__ == "__main__":
        main()
    

使用加密参数

如果您的参数涉及敏感数据(例如密码等),建议使用加密参数。使用加密参数,需要开通密钥管理服务(KMS)。更多信息,请参见什么是密钥管理服务

  1. 通过系统运维管理OOS的参数仓库创建加密参数和普通参数。具体操作,请参见加密参数普通参数

    以下示例表示在OOS参数仓库中创建用户名参数username和密码参数password。

    • 在普通参数中新增一个用户名参数username,取值为user01,您可以根据实际情况修改。

      名称

      示例值

      参数名称

      username

      参数类型

      String

      user01

    • 在加密参数中新增一个密码参数password,取值为MyPassword01,您可以根据实际情况修改。

      名称

      示例值

      参数名称

      password

      KMS密钥ID

      Default Service CMK

      说明

      此处示例值是由KMS生成的免费服务密钥,请根据实际情况选择。

      MyPassword01

      说明

      此密码仅做示例,请不要在生产环境使用。

  2. 为目标ECS实例设置RAM角色。

    1. 创建RAM角色。具体操作,请参见创建可信实体为阿里云服务的RAM角色

      相关配置示例如下所示。

      名称

      示例

      信任主体类型

      选择云服务

      信任主体名称

      云服务器 ECS / ECS

      单击确定角色名称设置为AxtParametersRamRole

    2. 创建RAM角色相关权限策略。具体操作,请参见创建自定义权限策略

      权限策略示例

      策略名称为AxtParametersRamPolicy,策略内容如下所示,表示允许调用KMSOOS的相关API(GetSecretValueGetParametersGetSecretParametersGetParameterGetSecretParameter)。

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "kms:GetSecretValue",
                      "oos:GetParameters",
                      "oos:GetSecretParameters",
                      "oos:GetParameter",
                      "oos:GetSecretParameter"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
    3. RAM角色(AxtParametersRamRole)设置策略权限(AxtParametersRamPolicy)。具体操作,请参见RAM角色授权

    4. 为目标ECS实例设置RAM角色(AxtParametersRamRole)。具体操作,请参见创建RAM角色并授予给ECS实例

  3. 调用API执行云助手命令。

    使用RAM用户通过云助手命令为Linux实例修改用户密码,命令内容如下所示:

     echo '{{oos-secret:password}}' | passwd '{{oos:username}}' --stdin

    其中,{{oos-secret:password}}表示用户的新密码,由OOS参数仓库的加密参数password定义;{{oos:username}}表示用户名,由OOS参数仓库的普通参数username定义。

    说明

    RAM用户授予允许使用云助手执行包含OSS加密参数的命令,具体权限策略信息,请参见在命令中使用OSS加密参数

    import com.aliyun.ecs20140526.Client;
    import com.aliyun.ecs20140526.models.RunCommandRequest;
    import com.aliyun.ecs20140526.models.RunCommandResponse;
    import com.aliyun.teaopenapi.models.Config;
    import com.google.gson.Gson;
    
    import java.util.Arrays;
    import java.util.List;
    
    public class EcsService {
        public static void main(String[] args_) throws Exception {
            // 地域ID
            String regionId = "cn-hangzhou";
            Config config = new Config()
                    .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                    .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                    .setRegionId(regionId);
            Client ecsClient = new Client(config);
            RunCommandRequest request = new RunCommandRequest();
            request.setRegionId(regionId);
            request.setType("RunShellScript");
            // 开启自定义参数功能
            request.setEnableParameter(true);
            // 待执行命令内容
            String commandContent = "echo '{{oos-secret:password}}' | passwd '{{oos:username}}' --stdin";
            request.setCommandContent(commandContent);
            List<String> instanceIds = Arrays.asList("i-bp1h23xufsi8XXXXXXXX");
            request.setInstanceId(instanceIds);
            // 命令执行超时时间
            request.setTimeout(60L);
            RunCommandResponse response = ecsClient.runCommand(request);
            System.out.println(new Gson().toJson(response.getBody()));
        }
    }
    
    import json
    import os
    
    from alibabacloud_ecs20140526 import models as ecs_20140526_models
    from alibabacloud_ecs20140526.client import Client as Ecs20140526Client
    from alibabacloud_tea_openapi import models as open_api_models
    
    ACCESS_KEY_ID = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
    ACCESS_KEY_SECRET = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    
    
    def get_ecs_client(region_id):
        config = open_api_models.Config(
            access_key_id=ACCESS_KEY_ID,
            access_key_secret=ACCESS_KEY_SECRET,
            region_id=region_id
        )
        return Ecs20140526Client(config)
    
    
    def main():
        # 地域ID
        region_id = "cn-hangzhou"
        client = get_ecs_client(region_id)
        # 要执行命令的ECS实例ID
        instance_ids = ["i-bp1h23xufsi8XXXXXXXX"]
        # 待执行命令内容
        command_content = "echo '{{oos-secret:password}}' | passwd '{{oos:username}}' --stdin"
        # 命令执行超时时间,单位为秒
        command_timeout = 60
        # 适用于Linux实例的Shell命令:RunShellScript
        command_type = "RunShellScript"
    
        # 执行命令
        request = ecs_20140526_models.RunCommandRequest()
        request.region_id = region_id
        request.type = command_type
        # 开启自定义参数功能
        request.enable_parameter = True
        request.command_content = command_content
        request.instance_id = instance_ids
        request.timeout = command_timeout
        response = client.run_command(request)
        print("execute_command result:", json.dumps(response.to_map()['body']))
    
    
    if __name__ == "__main__":
        main()
    

内置环境参数介绍

可以指定内置环境参数作为自定义参数,在执行命令时,无需手动为参数赋值,云助手将自动替换为相应的值。

内置环境参数

说明

{{ACS::RegionId}}

地域ID。

{{ACS::AccountId}}

阿里云主账号UID。

{{ACS::InstanceId}}

实例 ID。命令下发到多个实例时,如需指定{{ACS::InstanceId}}作为内置环境参数,需确保云助手 Agent 不低于以下版本:

  • Linux:2.2.3.309

  • Windows:2.1.3.309

{{ACS::InstanceName}}

实例名称。命令下发到多个实例时,如需指定{{ACS::InstanceName}}作为内置环境参数,需确保云助手 Agent 不低于以下版本:

  • Linux:2.2.3.344

  • Windows:2.1.3.344

{{ACS::InvokeId}}

命令执行ID。如需指定{{ACS::InvokeId}}作为内置环境参数,需确保云助手 Agent 不低于以下版本:

  • Linux:2.2.3.309

  • Windows:2.1.3.309

{{ACS::CommandId}}

命令 ID。通过调用 RunCommand接口执行命令时,如需指定{{ACS::CommandId}}作为内置环境参数,需确保云助手 Agent 不低于以下版本:

  • Linux:2.2.3.309

  • Windows:2.1.3.309