ちょっと話題の記事

AWS CLIのコマンドとPowerShellコマンドレットを比較表示するサイトを作ってみた

2019.03.14

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

しばたです。

コマンドラインでAWSを操作するAWS CLIAWS Tools for PowerShellですが、例えばEC2インスタンスを作成する場合であればaws ec2 run-instancesコマンドとNew-EC2Instanceコマンドレットの様に対になる組み合わせが"概ね"存在します。

AWSのドキュメントはAWS CLIを前提としてるものが多いため、PowerShellのコマンドレットで作業をしようとする際に対になるAWS CLIを知りたくなることが結構あるのですが、残念ながらこの組み合わせに関して公式にはドキュメント化されていません。
需要はありそうなので「誰か有志が組み合わせをまとめたりしてくれないかな?」と思いネット上を調べてみたのですが、残念ながらその様なサイトを見つけることもできませんでした。

そういうわけで「なければ作るしかない」という気持ちになりAWS CLIのコマンドとPowerShellコマンドレットを比較表示するサイトを作ってみました。

AWS CLI -eq PowerShell

作ったサイトはこちらになります。

トップページにAWSの各サービスとAWS CLIのサブコマンドを列記しており、

サブコマンド欄をクリックすると、CLIの各コマンドと対になるPowerShellコマンドレットの一覧が表示されます。

実装について

サービスが100以上あるAWSでこの様なサイトを手作業で作ると時間がいくらあっても足りませんのでコンテンツは自動生成しています。
自動生成したコンテンツをHugo+GitHub Pagesでホストしています。

自動生成する部分のソースコードやコンテンツ一式はGitHubに上げています。

Get-AWSCmdletName

自動生成のキモとなるのはGet-AWSCmdletNameコマンドレットです。
これは様々な条件でAWS Tools for PowerShell内のコマンドレットを検索するものなのですが、AwsCliCommandというパラメーターがありAWS CLIのコマンドから該当するPowerShellコマンドレットを検索することができます。

Import-Module AWSPowerShell.NetCore
# aws ec2 run-instances と対になるコマンドレットを検索
Get-AWSCmdletName -AwsCliCommand 'aws ec2 run-instances'

より詳細な使い方については以下のドキュメントを参照してください。

AWS CLIのコマンド一覧

ここまでわかれば後はすべてのAWS CLIのコマンドを取得すれば比較表を自動生成できます。

AWS CLIのコマンド一覧はaws helpコマンドで取得できます。
ヘルプなのでデータは構造化されていないため気合いで内容をパースして必要な部分を取得します。

# AWS CLIのコマンド一覧を取得する例
aws help | col -b | sed -n '/AVAILABLE SERVICES/,/SEE ALSO/p' | grep 'o ' | sed s/'o '//g | tr -d ' ' | sed -e /help/d | sort

各サブコマンドで利用できるオペレーションの一覧もaws [サブコマンド] helpから取得できるのですが、調べた限りだとヘルプドキュメントの更新が追い付いていない様で実際のコマンドより少ない数のコマンドしか取得できないケースが多く出ました。
仕方ないのでダミーのコマンドを実行してエラーメッセージに含まれる「使用可能オペレーション」の一覧を取得することにしました。

このやり方ですべて取得できているか怪しいところはあるのですがaws [サブコマンド] helpよりは正確なので割り切っています。

# aws ec2 サブコマンドで利用可能なオペレーション一覧を取得する例
# ※ dummy_error_command とエラーになるコマンドを指定してエラーメッセージから使用可能コマンドを取得
aws ec2 dummy_error_command 2>&1 | tail -n +9 | awk -F'|' '{printf "%s\n%s\n",$1,$2}' | tr -d ' ' | sed -e /wait/d -e /help/d -e /^$/d | sort

これで(おそらく全ての)AWS CLIコマンドが取得できましたので、最後は一つずつGet-AWSCmdletNameと付け合わせていけば比較表が完成します。

Get-AWSCmdletName のハマりポイント

AWS CLI -eq PowerShellを作成する際に何点かGet-AWSCmdletNameでハマったところがあるので共有します。

Get-AWSCmdletName の仕組み

AWS Tools for PowerShellの各コマンドレットは内部にAWSClientCmdletAttributeおよびAWSCmdletAttributeという属性を持ち、自分自身がどのサービス用の機能なのか、APIのどのオペレーションに該当するのかというメタデータを保持しています。
Get-AWSCmdletNameはこの属性値を"機械的"に検索して該当するコマンドを見つけようとします。

1. 全てのサブコマンドに対応していない

Get-AWSCmdletNameが検索可能なサービス名はAWS CLIのサブコマンド名と完全に一致しておらず、ざっくり1/3くらいのサービスは単純な検索では期待した動作になりません。

例えばAmazon DynamoDB(aws dynamodb)の場合だと、以下の様に単純にAWS CLIを検索しても期待した結果を得ることができませんでした。

# DynamoDBでは単純にAWS CLIを指定しても検索できない...
Get-AWSCmdletName -AwsCliCommand 'aws dynamodb describe-table'

この様な場合はサブコマンドの代わりにコマンドレットのPrefixを指定してやると、Prefixの方が検索の優先順位が高いらしく対になるコマンドレットを検索できます。

# こういう場合はCmdletのPrefix(ddb)を指定してやると検索できる
Get-AWSCmdletName -AwsCliCommand 'aws ddb describe-table'

この点に関しては「正直どうよ?」という気持ちが強いのですが、仕方ないので割り切って利用しています。

2. S3には使えない

S3だけはAWS CLIとPowerShellコマンドの体系が全く異なる様でGet-AWSCmdletNameが全く役に立ちませんでした。
S3に関してはAWS CLIとの対応は考えず必要なコマンドレットは個別に調べた方が良いでしょう。

# S3は Serviceパラメーターから必要なコマンドレットを検索した方が良い
Get-AWSCmdletName -Service s3

AWS CLI -eq PowerShellでどう対応するかについては現在進行形で悩んでいます。
対応を決めたらコンテンツを更新したいと思います。

最後に

ざっとこんな感じです。
現実問題としてこのサイトの需要がどれほどあるのかは怪しいところですが、作った本人は既に活用しまくっています。
Hugoを使ったサイト作りの勉強にもなったので十分満足しています。

AWS Tools for PowerShellを使っていて私と同じ悩みを抱えている人の役に立てば幸いです。