amazon-web-servicesaws-ssm

How can I use "aws ssm send-command" in a way that it returns the exit code of the script I ran?


I'd like to run one command on one instance in aws and get back the exit code as soon as it exited on the remote instance, i.e:

aws ssm send-command --instance-id i-012345678 --document-name AWS-RunShellScript --parameters 'commands=["touch /tmp/bingo"]'
echo $?

The problem is that when I use aws ssm send-command I always get some json on the output and then it waits until I type Ctrl+C. I'd like it to a) wait until the remote command finishes and then continue my local script and b) get the exit code of the remote command


Solution

  • aws ssm send-command is asynchronous and only returns information about the execution itself (since it doesn't wait for the script to finish).

    From the output of aws ssm send-command you need to grab the command ID, and then you can use that with aws ssm get-command-invocation to retrieve information about the execution of the script, which includes the exit code (ResponseCode in the JSON output.)

    Note that aws ssm get-command-invocation might not return anything for a bit until the execution of the script has actually been completed.


    Here's an example in bash:

    INSTANCE_ID=i-...
    COMMAND_ID=$(aws ssm send-command --instance-id "$INSTANCE_ID" --document-name AWS-RunShellScript --parameters 'commands=["touch /tmp/bingo"]' --query 'Command.CommandId' --output text)
    until [ $(aws ssm get-command-invocation --instance-id "$INSTANCE_ID" --command-id "$COMMAND_ID" --query 'Status' --output text) != "InProgress" ]; do 
      echo "command is still running!"
      sleep 1
    done
    COMMAND_EXIT_CODE=$(aws ssm get-command-invocation --instance-id "$INSTANCE_ID" --command-id "$COMMAND_ID" --query 'ResponseCode' --output text)
    echo "command exited with exit code ${COMMAND_EXIT_CODE}"