1
2

More than 3 years have passed since last update.

AWS CLI を使って AWS Systems Manager Run Command を実行する

Posted at

はじめに

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 - 利用可能なドキュメントの表示

利用可能なすべてのドキュメントを表示します。

list-documents
$ aws ssm list-documents

特定のドキュメントのみに絞りたい場合は --document-filter-listオプション を利用します。

list-documents
$ 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 - 実行可能インスタンスの表示

コマンドを受信する準備ができているインスタンスを確認します。

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を利用しています。

describe-instance-information
$ aws ssm describe-instance-information --instance-information-filter-list key=InstanceIds,valueSet=i-0c8a643ed4eba0d50

■ describe-document - 説明と使用可能なパラメータを表示する

Systems Manager JSON ドキュメントの説明を表示するには、次のコマンドを使用します。

describe-document
$ aws ssm describe-document

このままだと全てのドキュメントが表示されるため、特定のドキュメント(ここではAWS-RunShellScript)の表示のみ行いたい場合は --nameオプション を使って指定することができます。

describe-document
$ 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オプション を利用すると、出力内容を整形することもできます。
次のコマンドはドキュメント名とその説明を抽出した例です。

describe-document
$ aws ssm describe-document --name "AWS-RunShellScript" --query "[Document.Name,Document.Description]"
[
    "AWS-RunShellScript",
    "Run a shell script or specify the commands to run."
]

もう一つ例を挙げておきます。
こちらはドキュメントを実行する際に利用するパラメータ関連の情報を出力しています。

describe-document
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 コマンドを送信します。

send-command
$ 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 を利用します。

list-commands
$ 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 - コマンド実行に関するステータス取得

コマンド実行に関するステータスを取得します。

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 の部分も表示されます。

list-command-invocations
            "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 では ParametersMaxConcurrency などの値が出力され、list-command-invocations では CommandPlugins の部分で send-command で実行しされた結果(ここではifconfigの戻り値)が確認できます。
ぱっと見同じような値が出力されているのでどっちを使っても良いのかなと思いますが、取得したい値によっては使い分けが必要がありそうです。

おわりに

Run Command は管理コンソールから操作するとステップが多くて時間がかかります。
aws-cli だとコマンド一つで実行できるので便利です。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2