PowerShell、AWS CLI、およびjson

Amazonクラウドを使用する場合、多くの場合、Webコンソールを介して多くの日常的な操作を実行する必要があります。 しかし、私はそれらを自動化したい。

コマンドラインインターフェイスであるAWS CLIは、これに適しています。 もちろん、Scalaでアプリケーションを作成できますが、日常のタスクでは「重砲」なしで管理する方が適切です。

AWSチームは、jsonを含むさまざまな形式でデータを返すことができます。 bashとjqを使用できますが、後者はcygwinリポジトリにないので、手で怠inessをインストールしてください。 一方、PowerShellはjsonを強力にサポートしています! 確かに、これを使用することは完全に簡単ではないことがわかりました。

C:\Users\mpotanin> $instance = aws ec2 describe-instances --instance-ids i-ecf1fe5c C:\Users\...> ConvertFrom-Json $instance ConvertFrom-Json : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'InputObject'.    . At line:1 char:19 + ConvertFrom-Json $instance + ~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [ConvertFrom-Json], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
      
      





実際、jsonは複数の行として出力され、配列として扱われます。 PowerShellでフィードするにはいくつかの方法があります。

 $instance | ConvertFrom-Json ConvertFrom-Json ($instance -join "") ConvertFrom-Json "$instance"
      
      





正しい情報を取得することは今では難しくありません。

 (aws ec2 describe-instances --instance-ids i-ecf1fe5c | ConvertFrom-Json).Reservations[0].Instances[0].PublicIpAddress
      
      





単純な場合、情報の抽出をawsに委任できます。

 aws ec2 describe-instances --instance-ids i-ecf1fe5c --query 'Reservations[0].Instances[0].PublicIpAddress' | ConvertFrom-Json
      
      





それとも

 aws ec2 describe-instances --instance-ids i-ecf1fe5c --query 'Reservations[0].Instances[0].PublicIpAddress' --output=text
      
      





したがって、コンソールから自動スケーリンググループの奇妙な動作を観察すると、マウスでインスタンス名をコピーし、sshでインスタンス名に移動できます。

 function get-address([String]$instanceId) { aws ec2 describe-instances --instance-ids $instanceId --query 'Reservations[0].Instances[0].PublicIpAddress' | convertfrom-json } ssh -i devkey.pem -l ubuntu (get-address i-ecf1fe5c)
      
      







より複雑なケースでは、重要なコードを書く必要があります。 たとえば、次のように、スタックのクラウド形成の出力パラメーターを取得できます。

 function reduce ($f,$a) { if ($a.Length -eq 1) { $a } else { $p = $a[0] foreach ($x in 1..($a.Length-1)) { $p = $f.Invoke($p,$a[$x])[0] } $p } } function get-json($data) { ConvertFrom-json "$data" } function get-cf-outputs($cfName) { $o = (get-json(aws cloudformation describe-stacks --stack-name $cfName)).Stacks[0].Outputs $r = foreach($i in $o) { @{$i.OutputKey = $i.OutputValue} } reduce {param($a,$i); $a+$i } $r }
      
      





コマンドでデータベース接続パラメーターを取得できます

 (get-cf-outputs microservice-rds-dev).DatabaseEndpoint
      
      







jsonをaws cliコマンドに渡すことも驚くべきことです。 たとえば、dynamodbテーブルにエントリを追加しようとすると失敗します。

 C:\Users\...> aws dynamodb put-item --table-name tableName --item '{"groupId":{"S":"5"}, "ancestors":{"L":[{"S":"5"},{"S":"0"}]}}' Error parsing parameter '--item': Invalid JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
      
      





つまり、どこか深くaws cliがこの行を解釈してからjsonライブラリーに渡します。 (もしそれがbashであれば、私は理解するだろうが、なぜ私の理解以上のpythonプログラムでそれが必要なのか。)

この奇妙な動作を回避するには、特殊文字をエスケープするだけで十分です。

 function put-item([string]$table, $data) { aws dynamodb put-item --table-name $table --item (convertto-json -Depth 128 $data).Replace('\','\\').Replace('"','\"') }
      
      





原則として、PowerShell用のネイティブAWSクライアントもありますが、私にはもっと複雑で、さらに悪いことに文書化されているように見えました。



All Articles