AWS CLIにhistory機能が追加されました #reinvent

2017.11.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

西澤です。みんな大好きAWS CLIに地味に嬉しいアップデートがあったのをたまたま見つけたのでご紹介したいと思います。

AWS CLIのリリース情報を確認していたところ、ちょっと気になる記述を見つけました。

  • 1.13.0
    • feature:cli_history: Setting the value of cli_history to enabled in the shared config file enables the CLI to keep history of all commands ran.
    • feature:history list: Lists all of the commands that have been run via the stored history of the CLI.
    • feature:history show: Shows the important events related to running a command that was recorded in the CLI history.

aws-cli/CHANGELOG.rst at develop · aws/aws-cli

きちんとマニュアルも更新されているようです。

AWS CLIのhistory機能を有効化

前提として、AWS CLIのバージョンを1.13.0以上にバージョンアップしておく必要があります。必要に応じてバージョンアップしておきましょう。執筆時点の最新バージョンでは1.14.0になっていました。

$ aws --version
aws-cli/1.14.0 Python/2.7.10 Darwin/16.7.0 botocore/1.8.4

公式ドキュメントの手順の通りに設定を行います。cli_history enabledをプロファイルに設定すると、~/.aws/configファイルに設定が書き込まれるようです。

$ aws configure set cli_history enabled --profile cm-nishizawa
$ cat ~/.aws/config
[default]
output = json
[profile cm-nishizawa]
output = json
region = us-west-2
cli_history = enabled
:::

AWS CLIのhistory記録を呼び出し

それでは、この状態でhistoryがどのように呼び出せるのかを実際に試してみます。まずは、適当なawsコマンドをいくつか実行します。

$ aws ec2 describe-regions
$ aws ec2 describe-availability-zones
$ aws s3 ls s3://aaa

すると、.aws/cli/historyの下に何だかデータが生成されているようです。

$ ls -l ~/.aws/cli/history/
total 104
-rw-r--r-- 1 nishizawa.tetsunori staff 20480 11 30 11:21 history.db
-rw-r--r-- 1 nishizawa.tetsunori staff 32768 11 30 11:21 history.db-shm
-rw-r--r-- 1 nishizawa.tetsunori staff 0 11 30 11:21 history.db-wal
$ find ~/.aws/cli/history -ls -exec file {} \;
19686927 0 drwxr-xr-x 5 nishizawa.tetsunori staff 170 11 30 10:25 /Users/nishizawa.tetsunori/.aws/cli/history
/Users/nishizawa.tetsunori/.aws/cli/history: directory
19686929 40 -rw-r--r-- 1 nishizawa.tetsunori staff 20480 11 30 11:21 /Users/nishizawa.tetsunori/.aws/cli/history/history.db
/Users/nishizawa.tetsunori/.aws/cli/history/history.db: SQLite 3.x database, last written using SQLite version 3016000
19686933 64 -rw-r--r-- 1 nishizawa.tetsunori staff 32768 11 30 11:21 /Users/nishizawa.tetsunori/.aws/cli/history/history.db-shm
/Users/nishizawa.tetsunori/.aws/cli/history/history.db-shm: data
19686932 0 -rw-r--r-- 1 nishizawa.tetsunori staff 0 11 30 11:21 /Users/nishizawa.tetsunori/.aws/cli/history/history.db-wal
/Users/nishizawa.tetsunori/.aws/cli/history/history.db-wal: empty

まずは、実行したコマンドの一覧をlistで呼び出してみます。こちらはオプション等は一切無しのようです。

$ aws history list
b251d060-f43a-4124-8803-1b0307c4e292 2017-11-30 11:33:04 AM s3 ls 255
12498f1d-d28f-47b5-8e23-f5a4d6cf8f04 2017-11-30 11:19:30 AM ec2 describe-availability-zones 0
3dfb7224-a54f-4513-840b-8c5b4e364b8f 2017-11-30 10:25:48 AM ec2 describe-regions 0

それでは、実行結果の詳細をshowで確認してみます。これは想像していたよりずっとしっかりしたhistoryですね。驚きました。

$ aws history show

AWS CLI command entered
at time: 2017-11-30 11:33:04.641
with AWS CLI version: aws-cli/1.14.0 Python/2.7.10 Darwin/16.7.0 botocore/1.8.4
with arguments: [u's3', u'ls', u's3://aaa']

[0] API call made
at time: 2017-11-30 11:33:04.737
to service: s3
using operation: ListObjects
with parameters: {
"Bucket": "aaa",
"Delimiter": "/",
"Prefix": ""
}

[0] HTTP request sent
at time: 2017-11-30 11:33:04.741
to URL: https://s3.us-west-2.amazonaws.com/aaa?delimiter=%2F&prefix=&encoding-type=url
with method: GET
with headers: {
"Authorization": "AWS4-HMAC-SHA256 Credential=AKIAIJXL3QINBH3K6ZRQ/20171130/us-west-2/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=a7ca6d2ff43691172122f0276155c383bfc29974a6539b917e17ad5006f67e4b",
"User-Agent": "aws-cli/1.14.0 Python/2.7.10 Darwin/16.7.0 botocore/1.8.4",
"X-Amz-Content-SHA256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"X-Amz-Date": "20171130T023304Z"
}
with body: There is no associated body

[0] HTTP response received
at time: 2017-11-30 11:33:05.339
with status code: 301
with headers: {
"content-type": "application/xml",
"date": "Thu, 30 Nov 2017 02:33:04 GMT",
"server": "AmazonS3",
"transfer-encoding": "chunked",
"x-amz-bucket-region": "us-east-1",
"x-amz-id-2": "bfoj0yn02Xo1i6xyh9CPAR2NSWx8GnyzJEMQOayklBeTqosnelNqqxTmnj9BVFSIw8Cc3GUOjtc=",
"x-amz-request-id": "8A4FD0E466EE0EC0"
}
with body: <!--?xml version="1.0" ?-->

<code>PermanentRedirect</code>
The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
aaa
s3.amazonaws.com
8A4FD0E466EE0EC0
bfoj0yn02Xo1i6xyh9CPAR2NSWx8GnyzJEMQOayklBeTqosnelNqqxTmnj9BVFSIw8Cc3GUOjtc=

[0] HTTP response parsed
at time: 2017-11-30 11:33:05.340
parsed to: {
"Error": {
"Bucket": "aaa",
"Code": "PermanentRedirect",
"Endpoint": "s3.amazonaws.com",
"Message": "The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint."
},
"ResponseMetadata": {
"HTTPHeaders": {
"content-type": "application/xml",
"date": "Thu, 30 Nov 2017 02:33:04 GMT",
"server": "AmazonS3",
"transfer-encoding": "chunked",
"x-amz-bucket-region": "us-east-1",
"x-amz-id-2": "bfoj0yn02Xo1i6xyh9CPAR2NSWx8GnyzJEMQOayklBeTqosnelNqqxTmnj9BVFSIw8Cc3GUOjtc=",
"x-amz-request-id": "8A4FD0E466EE0EC0"
},
"HTTPStatusCode": 301,
"HostId": "bfoj0yn02Xo1i6xyh9CPAR2NSWx8GnyzJEMQOayklBeTqosnelNqqxTmnj9BVFSIw8Cc3GUOjtc=",
"RequestId": "8A4FD0E466EE0EC0"
}
}

[0] HTTP request sent
at time: 2017-11-30 11:33:05.341
to URL: https://s3.amazonaws.com/aaa?delimiter=%2F&prefix=&encoding-type=url
with method: GET
with headers: {
"Authorization": "AWS4-HMAC-SHA256 Credential=AKIAIJXL3QINBH3K6ZRQ/20171130/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=e34f6754a9dee759701c16c1b47e6075170c29ed0a7d719a38fdfc29eb4967a4",
"User-Agent": "aws-cli/1.14.0 Python/2.7.10 Darwin/16.7.0 botocore/1.8.4",
"X-Amz-Content-SHA256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"X-Amz-Date": "20171130T023305Z"
}
with body: There is no associated body

[0] HTTP response received
at time: 2017-11-30 11:33:06.128
with status code: 403
with headers: {
"content-type": "application/xml",
"date": "Thu, 30 Nov 2017 02:33:05 GMT",
"server": "AmazonS3",
"transfer-encoding": "chunked",
"x-amz-bucket-region": "us-east-1",
"x-amz-id-2": "/EcZryxvUzKXr2531heCtMizP93m0c9bMfbNSJS0KXI1NlvXDUcfn9DjXI58GyACWlowNCI7tm0=",
"x-amz-request-id": "063C9B92E28B3BAB"
}
with body: <!--?xml version="1.0" ?-->

<code>AccessDenied</code>
Access Denied
063C9B92E28B3BAB
/EcZryxvUzKXr2531heCtMizP93m0c9bMfbNSJS0KXI1NlvXDUcfn9DjXI58GyACWlowNCI7tm0=

[0] HTTP response parsed
at time: 2017-11-30 11:33:06.128
parsed to: {
"Error": {
"Code": "AccessDenied",
"Message": "Access Denied"
},
parsed to: {
"Error": {
"Code": "AccessDenied",
"Message": "Access Denied"
},
"ResponseMetadata": {
"HTTPHeaders": {
"content-type": "application/xml",
"date": "Thu, 30 Nov 2017 02:33:05 GMT",
"server": "AmazonS3",
"transfer-encoding": "chunked",
"x-amz-bucket-region": "us-east-1",
"x-amz-id-2": "/EcZryxvUzKXr2531heCtMizP93m0c9bMfbNSJS0KXI1NlvXDUcfn9DjXI58GyACWlowNCI7tm0=",
"x-amz-request-id": "063C9B92E28B3BAB"
},
"HTTPStatusCode": 403,
"HostId": "/EcZryxvUzKXr2531heCtMizP93m0c9bMfbNSJS0KXI1NlvXDUcfn9DjXI58GyACWlowNCI7tm0=",
"RequestId": "063C9B92E28B3BAB"
}
}

AWS CLI command exited
at time: 2017-11-30 11:33:06.132
with return code: 255

直近ではなく以前の結果をhistoryから取得したい場合には、listで確認したcommand_idを引数に渡せばOKです。

$ aws history show 3dfb7224-a54f-4513-840b-8c5b4e364b8f

AWS CLI command entered
at time: 2017-11-30 10:25:48.199
with AWS CLI version: aws-cli/1.14.0 Python/2.7.10 Darwin/16.7.0 botocore/1.8.4
with arguments: [u'ec2', u'describe-regions']

[0] API call made
at time: 2017-11-30 10:25:48.595
to service: ec2
using operation: DescribeRegions
with parameters: {}

[0] HTTP request sent
at time: 2017-11-30 10:25:48.601
to URL: https://ec2.us-west-2.amazonaws.com/
with method: POST
with headers: {
"Authorization": "AWS4-HMAC-SHA256 Credential=AKIAIJXL3QINBH3K6ZRQ/20171130/us-west-2/ec2/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=216c2166cf23288084d453911462408895182bacb337077064c89041ad7b659a",
"Content-Length": "41",
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"User-Agent": "aws-cli/1.14.0 Python/2.7.10 Darwin/16.7.0 botocore/1.8.4",
"X-Amz-Date": "20171130T012548Z"
}
with body: Action=DescribeRegions&Version=2016-11-15

[0] HTTP response received
at time: 2017-11-30 10:25:49.199
with status code: 200
with headers: {
"content-type": "text/xml;charset=UTF-8",
"date": "Thu, 30 Nov 2017 01:25:47 GMT",
"server": "AmazonEC2",
"transfer-encoding": "chunked",
"vary": "Accept-Encoding"
}
with body: <!--?xml version="1.0" ?-->

e60926d0-b5b2-4e8d-82ff-0e759b0beff7


ap-south-1
ec2.ap-south-1.amazonaws.com


eu-west-2
ec2.eu-west-2.amazonaws.com


eu-west-1
ec2.eu-west-1.amazonaws.com


ap-northeast-2
ec2.ap-northeast-2.amazonaws.com


ap-northeast-1
ec2.ap-northeast-1.amazonaws.com


sa-east-1
ec2.sa-east-1.amazonaws.com


ca-central-1
ec2.ca-central-1.amazonaws.com


ap-southeast-1
ec2.ap-southeast-1.amazonaws.com


ap-southeast-2
ec2.ap-southeast-2.amazonaws.com


eu-central-1
ec2.eu-central-1.amazonaws.com


us-east-1
ec2.us-east-1.amazonaws.com


us-east-2
ec2.us-east-2.amazonaws.com


us-west-1
ec2.us-west-1.amazonaws.com


us-west-2
ec2.us-west-2.amazonaws.com


[0] HTTP response parsed
at time: 2017-11-30 10:25:49.200
parsed to: {
"Regions": [
{
"Endpoint": "ec2.ap-south-1.amazonaws.com",
"RegionName": "ap-south-1"
},
{
"Endpoint": "ec2.eu-west-2.amazonaws.com",
"RegionName": "eu-west-2"
},
{
"Endpoint": "ec2.eu-west-1.amazonaws.com",
"RegionName": "eu-west-1"
},
{
"Endpoint": "ec2.ap-northeast-2.amazonaws.com",
"RegionName": "ap-northeast-2"
},
{
"Endpoint": "ec2.ap-northeast-1.amazonaws.com",
"RegionName": "ap-northeast-1"
},
{
"Endpoint": "ec2.sa-east-1.amazonaws.com",
"RegionName": "sa-east-1"
},
{
"Endpoint": "ec2.ca-central-1.amazonaws.com",
"RegionName": "ca-central-1"
},
{
"Endpoint": "ec2.ap-southeast-1.amazonaws.com",
"RegionName": "ap-southeast-1"
},
{
"Endpoint": "ec2.ap-southeast-2.amazonaws.com",
"RegionName": "ap-southeast-2"
},
{
"Endpoint": "ec2.eu-central-1.amazonaws.com",
"RegionName": "eu-central-1"
},
{
"Endpoint": "ec2.us-east-1.amazonaws.com",
"RegionName": "us-east-1"
},
{
"Endpoint": "ec2.us-east-2.amazonaws.com",
"RegionName": "us-east-2"
},
{
"Endpoint": "ec2.us-west-1.amazonaws.com",
"RegionName": "us-west-1"
},
{
"Endpoint": "ec2.us-west-2.amazonaws.com",
"RegionName": "us-west-2"
}
],
"ResponseMetadata": {
"HTTPHeaders": {
"content-type": "text/xml;charset=UTF-8",
"date": "Thu, 30 Nov 2017 01:25:47 GMT",
"server": "AmazonEC2",
"transfer-encoding": "chunked",
"vary": "Accept-Encoding"
},
"HTTPStatusCode": 200,
"RequestId": "e60926d0-b5b2-4e8d-82ff-0e759b0beff7"
}
}

AWS CLI command exited
at time: 2017-11-30 10:25:49.204
with return code: 0

まとめ

事前に設定を有効にしておく必要がありますが、重要なシステムを対象とする作業においては、どのようなコマンドを実行し、どのような結果が返ってきたのかを確認できるのは嬉しいですね。re:Inventで盛り上がっている中ですが、今後もAWSの細かいアップデートもしっかり拾ってお伝えしていきたいと思います。

どこかの誰かのお役に立てば嬉しいです。