AWS Java SDK - 在 EC2 实例上使用 SSM 运行命令
Posted
技术标签:
【中文标题】AWS Java SDK - 在 EC2 实例上使用 SSM 运行命令【英文标题】:AWS Java SDK - Running a command using SSM on EC2 instances 【发布时间】:2020-02-25 20:54:42 【问题描述】:我在网上找不到任何此类示例,也找不到解释如何执行此操作的文档。基本上我有一个 Windows EC2 实例列表,我需要在每个实例中运行quser
命令来检查有多少用户登录。
可以使用 AWS Systems Manager 服务并运行 AWS-RunPowerShellScript 命令来执行此操作。我只找到了使用 AWS CLI 的示例,如下所示:
aws ssm send-command --instance-ids "instance ID" --document-name "AWS-RunPowerShellScript" --comment "Get Users" --parameters commands=quser --output text
但我如何使用 AWS Java SDK 1.11.x 完成此任务?
【问题讨论】:
如果在 SDKV2 中,您可以使用Waiter
逻辑。
【参考方案1】:
@Alexandre Krabbe 你问这个问题已经一年多了。所以不确定答案会对你有帮助。但我最近也在尝试做同样的事情,这让我想到了这个悬而未决的问题。我最终解决了这个问题,并认为我的回答可以帮助其他面临同样问题的人。这是相同的代码sn-p:
public void runCommand() throws InterruptedException
//Command to be run
String ssmCommand = "ls -l";
Map<String, List<String>> params = new HashMap<String, List<String>>()
put("commands", new ArrayList<String>() add(ssmCommand); );
;
int timeoutInSecs = 5;
//You can add multiple command ids separated by commas
Target target = new Target().withKey("InstanceIds").withValues("instance-id");
//Create ssm client.
//The builder could be chosen as per your preferred way of authentication
//use withRegion for specifying your region
AWSSimpleSystemsManagement ssm = AWSSimpleSystemsManagementClientBuilder.standard().build();
//Build a send command request
SendCommandRequest commandRequest = new SendCommandRequest()
.withTargets(target)
.withDocumentName("AWS-RunShellScript")
.withParameters(params);
//The result has commandId which is used to track the execution further
SendCommandResult commandResult = ssm.sendCommand(commandRequest);
String commandId = commandResult.getCommand().getCommandId();
//Loop until the invocation ends
String status;
do
ListCommandInvocationsRequest request = new ListCommandInvocationsRequest()
.withCommandId(commandId)
.withDetails(true);
//You get one invocation per ec2 instance that you added to target
//For just a single instance use get(0) else loop over the instanced
CommandInvocation invocation = ssm.listCommandInvocations(request).getCommandInvocations().get(0);
status = invocation.getStatus();
if(status.equals("Success"))
//command output holds the output of running the command
//eg. list of directories in case of ls
String commandOutput = invocation.getCommandPlugins().get(0).getOutput();
//Process the output
//Wait for a few seconds before you check the invocation status again
try
TimeUnit.SECONDS.sleep(timeoutInSecs);
catch (InterruptedException e)
//Handle not being able to sleep
while(status.equals("Pending") || status.equals("InProgress"));
if(!status.equals("Success"))
//Command ended up in a failure
【讨论】:
String commandOutput = invocation.getCommandPlugins().get(0).getOutput();似乎只返回错误窗口输出。无论如何要获得实际输出?【参考方案2】:在 SDK 1.11.x 中,使用类似:
val waiter = ssmClient.waiters().commandExecuted()
waiter.run(WaiterParameters(GetCommandInvocationRequest()
.withCommandId(commandId)
.withInstanceId(instanceId)
))
【讨论】:
以上是关于AWS Java SDK - 在 EC2 实例上使用 SSM 运行命令的主要内容,如果未能解决你的问题,请参考以下文章
带有 PHP SDK 的 AWS EC2 - 等到实例具有公共 DNS 名称
AWS SDK/CLI 访问错误,AWS Redshift create-cluster 的 EC2 实例凭证
使用 aws-sdk ruby gem 知道自己的实例 ID
使用boto3 Python SDK返回AWS EC2可用性区域属性