命令中使用自定义参数

云助手支持使用自定义参数或内置环境参数来灵活调整命令内容,类似于模板变量的功能。同时,也可以在云助手命令中结合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角色

      相关配置示例如下所示。

      名称

      示例

      当前可信实体类型

      选择阿里云服务

      角色类型

      选择普通服务角色

      角色名称

      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