はじめに
AWS Systems Manager の Run Command についてまとめてみました。
操作は全て aws-cli で行い、内容もコマンドベースの内容になります。
Run Command について
SSM エージェントをインストールしたインスタンスに対し、ドキュメントとしてあらかじめ用意したタスクをコマンドとして実行することができます。
簡単にいうと、AWS Systems Manager からリモートでコマンド実行などの操作ができるということです。
前提条件
aws-cli コマンド
「list-documents」「describe-instance-information」「describe-document」「send-command」「list-commands」「list-command-invocations」の6コマンドについてまとめました。
■ list-documents - 利用可能なドキュメントの表示
利用可能なすべてのドキュメントを表示します。
$ aws ssm list-documents
特定のドキュメントのみに絞りたい場合は --document-filter-list
オプション を利用します。
$ aws ssm list-documents --document-filter-list key=Name,value=AWS-RunShellScript
{
"DocumentIdentifiers": [
{
"Name": "AWS-RunShellScript",
"Owner": "Amazon",
"PlatformTypes": [
"Linux"
],
"DocumentVersion": "1",
"DocumentType": "Command",
"SchemaVersion": "1.2",
"DocumentFormat": "JSON",
"Tags": []
}
]
}
■ describe-instance-information - 実行可能インスタンスの表示
コマンドを受信する準備ができているインスタンスを確認します。
$ aws ssm describe-instance-information --query "InstanceInformationList[*]"
[
{
"InstanceId": "i-0c8a643ed4eba0d50",
"PingStatus": "Online",
"LastPingDateTime": "2021-04-02T09:45:35.443000+09:00",
"AgentVersion": "3.0.161.0",
"IsLatestVersion": false,
"PlatformType": "Linux",
"PlatformName": "Amazon Linux",
"PlatformVersion": "2",
"ResourceType": "EC2Instance",
"IPAddress": "172.31.33.239",
"ComputerName": "ip-172-31-33-239.ap-northeast-1.compute.internal"
}
]
特定のインスタンスについての詳細を表示するには、次のように --instance-information-filter-list
オプションで インスタンスID を指定することで行えます。
ここでは先ほど describe-instance-information
で取得したインスタンスIDを利用しています。
$ aws ssm describe-instance-information --instance-information-filter-list key=InstanceIds,valueSet=i-0c8a643ed4eba0d50
■ describe-document - 説明と使用可能なパラメータを表示する
Systems Manager JSON ドキュメントの説明を表示するには、次のコマンドを使用します。
$ aws ssm describe-document
このままだと全てのドキュメントが表示されるため、特定のドキュメント(ここではAWS-RunShellScript)の表示のみ行いたい場合は --name
オプション を使って指定することができます。
$ aws ssm describe-document --name "AWS-RunShellScript"
{
"Document": {
"Hash": "99749de5e62f71e5ebe9a55c2321e2c394796afe7208cff048696541e6f6771e",
"HashType": "Sha256",
"Name": "AWS-RunShellScript",
"Owner": "Amazon",
"CreatedDate": "2017-08-31T06:43:10.613000+09:00",
"Status": "Active",
"DocumentVersion": "1",
"Description": "Run a shell script or specify the commands to run.",
"Parameters": [
{
"Name": "commands",
"Type": "StringList",
"Description": "(Required) Specify a shell script or a command to run."
},
{
"Name": "workingDirectory",
"Type": "String",
"Description": "(Optional) The path to the working directory on your instance.",
"DefaultValue": ""
},
{
"Name": "executionTimeout",
"Type": "String",
"Description": "(Optional) The time in seconds for a command to complete before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).",
"DefaultValue": "3600"
}
],
"PlatformTypes": [
"Linux"
],
"DocumentType": "Command",
"SchemaVersion": "1.2",
"LatestVersion": "1",
"DefaultVersion": "1",
"DocumentFormat": "JSON",
"Tags": []
}
}
さらに、--query
オプション を利用すると、出力内容を整形することもできます。
次のコマンドはドキュメント名とその説明を抽出した例です。
$ aws ssm describe-document --name "AWS-RunShellScript" --query "[Document.Name,Document.Description]"
[
"AWS-RunShellScript",
"Run a shell script or specify the commands to run."
]
もう一つ例を挙げておきます。
こちらはドキュメントを実行する際に利用するパラメータ関連の情報を出力しています。
aws ssm describe-document --name "AWS-RunShellScript" --query "Document.Parameters[*]"
[
{
"Name": "commands",
"Type": "StringList",
"Description": "(Required) Specify a shell script or a command to run."
},
{
"Name": "workingDirectory",
"Type": "String",
"Description": "(Optional) The path to the working directory on your instance.",
"DefaultValue": ""
},
{
"Name": "executionTimeout",
"Type": "String",
"Description": "(Optional) The time in seconds for a command to complete before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).",
"DefaultValue": "3600"
}
]
アスタリスク(*)
を用いることで、ネストされている部分をまとめて抽出しています。
■ send-command - ドキュメントを使用してコマンドを送信
インスタンスへコマンドを送信するにはドキュメントを指定して行います。
今回は AWS-RunShellScript
ドキュメント を使って ifconfig コマンドを送信します。
$ aws ssm send-command --instance-ids i-0c8a643ed4eba0d50 --document-name "AWS-RunShellScript" --comment "IP config" --parameters commands=ifconfig
{
"Command": {
"CommandId": "3230ba49-d49c-4c25-b7f0-e753c5713738",
"DocumentName": "AWS-RunShellScript",
"DocumentVersion": "",
"Comment": "IP config",
"ExpiresAfter": "2021-04-02T12:17:39.453000+09:00",
"Parameters": {
"commands": [
"ifconfig"
]
},
"InstanceIds": [
"i-0c8a643ed4eba0d50"
],
"Targets": [],
"RequestedDateTime": "2021-04-02T10:17:39.453000+09:00",
"Status": "Pending",
"StatusDetails": "Pending",
"OutputS3BucketName": "",
"OutputS3KeyPrefix": "",
"MaxConcurrency": "50",
"MaxErrors": "0",
"TargetCount": 1,
"CompletedCount": 0,
"ErrorCount": 0,
"DeliveryTimedOutCount": 0,
"ServiceRole": "",
"NotificationConfig": {
"NotificationArn": "",
"NotificationEvents": [],
"NotificationType": ""
},
"CloudWatchOutputConfig": {
"CloudWatchLogGroupName": "",
"CloudWatchOutputEnabled": false
},
"TimeoutSeconds": 3600
}
}
■ list-commands - コマンドステータスの取得
コマンドステータスの取得を行います。
取得には send-command
で実行した際に発行される CommandId を指定します。
ここでは先ほど実行して発行された CommandId を利用します。
$ aws ssm list-commands --command-id 3230ba49-d49c-4c25-b7f0-e753c5713738
{
"Commands": [
{
"CommandId": "3230ba49-d49c-4c25-b7f0-e753c5713738",
"DocumentName": "AWS-RunShellScript",
"DocumentVersion": "",
"Comment": "IP config",
"ExpiresAfter": "2021-04-02T12:17:39.453000+09:00",
"Parameters": {
"commands": [
"ifconfig"
]
},
"InstanceIds": [
"i-0c8a643ed4eba0d50"
],
"Targets": [],
"RequestedDateTime": "2021-04-02T10:17:39.453000+09:00",
"Status": "Success",
"StatusDetails": "Success",
"OutputS3BucketName": "",
"OutputS3KeyPrefix": "",
"MaxConcurrency": "50",
"MaxErrors": "0",
"TargetCount": 1,
"CompletedCount": 1,
"ErrorCount": 0,
"DeliveryTimedOutCount": 0,
"ServiceRole": "",
"NotificationConfig": {
"NotificationArn": "",
"NotificationEvents": [],
"NotificationType": ""
},
"CloudWatchOutputConfig": {
"CloudWatchLogGroupName": "",
"CloudWatchOutputEnabled": false
},
"TimeoutSeconds": 3600
}
]
}
■ list-command-invocations - コマンド実行に関するステータス取得
コマンド実行に関するステータスを取得します。
$ aws ssm list-command-invocations --command-id 3230ba49-d49c-4c25-b7f0-e753c5713738
{
"CommandInvocations": [
{
"CommandId": "3230ba49-d49c-4c25-b7f0-e753c5713738",
"InstanceId": "i-0c8a643ed4eba0d50",
"InstanceName": "",
"Comment": "IP config",
"DocumentName": "AWS-RunShellScript",
"DocumentVersion": "",
"RequestedDateTime": "2021-04-02T10:17:39.597000+09:00",
"Status": "Success",
"StatusDetails": "Success",
"StandardOutputUrl": "",
"StandardErrorUrl": "",
"CommandPlugins": [],
"ServiceRole": "",
"NotificationConfig": {
"NotificationArn": "",
"NotificationEvents": [],
"NotificationType": ""
},
"CloudWatchOutputConfig": {
"CloudWatchLogGroupName": "",
"CloudWatchOutputEnabled": false
}
}
]
}
--details
オプション を追加すると CommandPlugins の部分も表示されます。
"CommandPlugins": [
{
"Name": "aws:runShellScript",
"Status": "Success",
"StatusDetails": "Success",
"ResponseCode": 0,
"ResponseStartDateTime": "2021-04-02T10:17:40.129000+09:00",
"ResponseFinishDateTime": "2021-04-02T10:17:40.141000+09:00",
"Output": "eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9001\n inet 172.31.33.239 netmask 255.255.240.0 broadcast 172.31.47.255\n inet6 fe80::439:f6ff:fe5e:ad7f prefixlen 64 scopeid 0x20<link>\n ether 06:39:f6:5e:ad:7f txqueuelen 1000 (Ethernet)\n RX packets 475097 bytes 213995563 (204.0 MiB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 378752 bytes 44378719 (42.3 MiB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\nlo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536\n inet 127.0.0.1 netmask 255.0.0.0\n inet6 ::1 prefixlen 128 scopeid 0x10<host>\n loop txqueuelen 1000 (Local Loopback)\n RX packets 10 bytes 726 (726.0 B)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 10 bytes 726 (726.0 B)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\n",
"StandardOutputUrl": "",
"StandardErrorUrl": "",
"OutputS3Region": "ap-northeast-1",
"OutputS3BucketName": "",
"OutputS3KeyPrefix": ""
}
],
初めは、list-commands
コマンド と list-command-invocations
コマンド の違いわかりませんでした。
ただ、実行結果を良く見ると、list-commands
では Parameters や MaxConcurrency などの値が出力され、list-command-invocations
では CommandPlugins の部分で send-command
で実行しされた結果(ここではifconfigの戻り値)が確認できます。
ぱっと見同じような値が出力されているのでどっちを使っても良いのかなと思いますが、取得したい値によっては使い分けが必要がありそうです。
おわりに
Run Command は管理コンソールから操作するとステップが多くて時間がかかります。
aws-cli だとコマンド一つで実行できるので便利です。