Issue
I would like to run arbitrary commands on my EC2 instance using the PHP SDK, however, when i run the commands nothing seems to be happening.
My workflow is as follows:
return $this->awsSdk
->createSsm()
->sendCommand([
'DocumentName' => 'AWS-RunShellScript',
'Targets' => [
[
'Key' => 'InstanceIds',
'Values' => [$this->getInstance($instance)] //Returns a value such as i-012345345h30 as an example
]
],
'Commands' => $commands, //An array of commands, (For testing this is ['touch testing.txt']
'Output' => 'text'
])->toArray();
Result of this is as follows:
array:2 [
"Command" => array:26 [
"CommandId" => "MY_COMMAND_ID"
"DocumentName" => "AWS-RunShellScript"
"DocumentVersion" => "$DEFAULT"
"Comment" => ""
"ExpiresAfter" => Aws\Api\DateTimeResult @1704816674^ {#910
date: 2024-01-09 16:11:14.150 UTC (+00:00)
}
"Parameters" => []
"InstanceIds" => []
"Targets" => array:1 [
0 => array:2 [
"Key" => "InstanceIds"
"Values" => array:1 [
0 => "MY_INSTANCE_ID"
]
]
]
"RequestedDateTime" => Aws\Api\DateTimeResult @1704809474^ {#913
date: 2024-01-09 14:11:14.150 UTC (+00:00)
}
"Status" => "Pending"
"StatusDetails" => "Pending"
"OutputS3Region" => "eu-west-1"
"OutputS3BucketName" => ""
"OutputS3KeyPrefix" => ""
"MaxConcurrency" => "50"
"MaxErrors" => "0"
"TargetCount" => 0
"CompletedCount" => 0
"ErrorCount" => 0
"DeliveryTimedOutCount" => 0
"ServiceRole" => ""
"NotificationConfig" => array:3 [
"NotificationArn" => ""
"NotificationEvents" => []
"NotificationType" => ""
]
"CloudWatchOutputConfig" => array:2 [
"CloudWatchLogGroupName" => ""
"CloudWatchOutputEnabled" => false
]
"TimeoutSeconds" => 3600
"AlarmConfiguration" => array:2 [
"IgnorePollAlarmFailure" => false
"Alarms" => []
]
"TriggeredAlarms" => []
]
"@metadata" => array:4 [
"statusCode" => 200
"effectiveUri" => "https://ssm.eu-west-1.amazonaws.com"
"headers" => array:6 [
"server" => "Server"
"date" => "Tue, 09 Jan 2024 14:11:14 GMT"
"content-type" => "application/x-amz-json-1.1"
"content-length" => "903"
"connection" => "keep-alive"
"x-amzn-requestid" => "SOME_ID"
]
"transferStats" => array:1 [
"http" => array:1 [
0 => []
]
]
]
] // app/Console/Commands/GenerateSslCertificate.php:45
- Get the result of the command in a different call
return $this->awsSdk
->createSsm()
->getCommandInvocation([
'CommandId' => $id,
'InstanceId' => $this->getInstance($instance),
]);
And the result of this is:
Aws\Result^ {#892
-data: array:18 [
"CommandId" => "MY_COMMAND_ID"
"InstanceId" => "MY_INSTANCE_ID"
"Comment" => ""
"DocumentName" => "AWS-RunShellScript"
"DocumentVersion" => "$DEFAULT"
"PluginName" => "aws:runShellScript"
"ResponseCode" => 0
"ExecutionStartDateTime" => "2024-01-09T14:11:14.371Z"
"ExecutionElapsedTime" => "PT0.017S"
"ExecutionEndDateTime" => "2024-01-09T14:11:14.371Z"
"Status" => "Success"
"StatusDetails" => "Success"
"StandardOutputContent" => ""
"StandardOutputUrl" => ""
"StandardErrorContent" => ""
"StandardErrorUrl" => ""
"CloudWatchOutputConfig" => array:2 [
"CloudWatchLogGroupName" => ""
"CloudWatchOutputEnabled" => false
]
"@metadata" => array:4 [
"statusCode" => 200
"effectiveUri" => "https://ssm.eu-west-1.amazonaws.com"
"headers" => array:6 [
"server" => "Server"
"date" => "Tue, 09 Jan 2024 14:12:44 GMT"
"content-type" => "application/x-amz-json-1.1"
"content-length" => "582"
"connection" => "keep-alive"
"x-amzn-requestid" => "SOME_ID"
]
"transferStats" => array:1 [
"http" => array:1 [
0 => []
]
]
]
]
-monitoringEvents: []
However, when I log in to the instance, I cant find anywhere where the file testing.txt
is created.
Can anyone point me in the right direction of how I can get this to work please?
*** UPDATE ***
After some digging, I have restructured the command to the following:
return $this->awsSdk
->createSsm()
->sendCommand([
'InstanceIds' => ['MY INSTANCE ID'],
'DocumentName' => 'AWS-RunShellScript',
'Comment' => 'Run Script',
'Parameters' => [
'Commands' => ['pwd'],
],
'Output' => 'text'
])->toArray();
Its also worth noting that the equivalent CLI command seems to work without issue using the AWS-RunShellScript
document:
aws ssm send-command \
--instance-ids "MY_INSTANCE_ID" \
--document-name "AWS-RunShellScript" \
--comment "IP config" \
--parameters commands=ifconfig \
--output text
Solution
Having scraped the AWS docs for some hours, I found my issue.
After instantiating the SDK:
$this->awsSdk = new Sdk([
'region' => 'eu-west-1',
'credentials' => [
'key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET_KEY'
]
]);
I then created a function which allows me to send commands, like so:
public function sendCommands(string $instance, array $commands)
{
return $this->awsSdk
->createSsm()
->sendCommand([
'InstanceIds' => [$this->getInstance($instance)],
'DocumentName' => 'AWS-RunShellScript',
'Comment' => 'Run Script',
'Parameters' => [
'commands' => $commands,
],
'Output' => 'text'
])->toArray();
}
The only difference here is the lower case C
in commands which seemed to fix my issue. However, I thought it best to include my whole solution.
Answered By - Josh Bolton Answer Checked By - Pedro (WPSolving Volunteer)