AWS再入門ブログリレー2022 AWS Tools for PowerShell編

2022.03.18

当エントリは弊社コンサルティング部による『AWS 再入門ブログリレー 2022』の32日目のエントリです。

このブログリレーの企画は、普段 AWS サービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。

AWS をこれから学ぼう!という方にとっては文字通りの入門記事として、またすでに AWS を活用されている方にとっても AWS サービスの再発見や 2022 年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。

では、さっそくいってみましょう。今日のテーマは『AWS Tools for PowerShell』です。

AWS Tools for PowerShellとは

AWS Tools for PowerShellはAWSの各種リソースをPowerShellから管理するためのPowerShellモジュールです。
利用者は様々なPowerShellコマンドレットを使い各種リソースを管理します。

AWS CLIとの違い

コマンドでAWSを管理するツールとしては第一にAWS CLIがあります。
こちらはawsコマンド一つでAWSの各種リソースを管理することが可能で、PowerShellも含めて各種シェル上で利用することができます。

よく誤解されるのですが PowerShell上でAWS CLIを使っても何も問題ありません。
AWS Tools for PowerShellはPowerShellでの利用に最適化されたPowerShell専用のコマンド群(みたいなもの)と考えて頂くと良いでしょう。

普段からPowerShellを使い慣れておりPowerShellの流儀に合わせたい場合はAWS Tools for PowerShellを採用してください。
逆にAWS CLIの方を使い慣れているのであれば無理をしてまでAWS Tools for PowerShellを選択する必要はありません。皆さんが使い慣れてるツールを選びやりたいことを実現してください。

一応補足として両者の大まかな差異を表にしておきます。
ツール選定の際の参考にしてください。

項目 AWS CLI AWS Tools for PowerShell
実装 Python製 (botocore) C#製 (AWS SDK for .NET)
対応シェル PowerShellに限らない PowerShellのみ
コマンド体系 awsコマンド1つ 多数のPowerShellコマンドレット(≒内部コマンド)
入出力 JSON等のテキスト .NETのオブジェクト

3種類のPowerShellモジュール

AWS Tools for PowerShellは歴史的経緯により3種類のモジュールが提供されています。
各モジュールでできることは大体同じなのですが、サポートされる環境の違いなどがあるので適切に使い分ける必要があります。

1. AWSPowerShell モジュール

AWSPowerShellモジュールは最初にリリースされた一番歴史あるタイプのモジュールです。
PowerShellがクロスプラットフォームになる以前から提供されていたためWindows専用です。
本日時点でWindows PowerShell 3.0 - 5.1環境での利用がサポートされています。

このモジュールは1つのモジュールで(対応する)すべてのAWSサービスの機能を提供します。

そしてWindows Server EC2にデフォルトで組み込まれています。

2. AWSPowerShell.NetCore モジュール

AWSPowerShell.NetCoreモジュールはPowerShellがクロスプラットフォーム化した後にリリースされたモジュールで主にmacOS、Linux向けとなります。
基盤となる.NET Coreの互換性向上により本日時点でWindows PowerShell 3.0 - 5.1 + .NET Framework 4.7.2以降 (Windows)およびPowerShell 6以降 (Windows, macOS, Linux)の環境での利用がサポートされています。

このモジュールも1つのモジュールで(対応する)すべてのAWSサービスの機能を提供します。

次に紹介するモジュールの登場によりこのモジュールを選択する機会はほとんど無くなったハズ...だったのですが、いつの間にかAWS CloudShellに標準搭載され地味に生き延びています。

3. AWS.Tools.* モジュール

最後に新しいタイプのAWS.Tools.*なモジュールがあります。
こちらは前者2つとは異なり、例えばEC2向けの機能であればAWS.Tools.EC2モジュールとサービス毎にモジュールが分離されており利用者の必要な分だけインストールして利用する形となります。

現在最新のAWS Tools for PowerShell v4においてはこのタイプのモジュールの利用が推奨されています。
モジュールサイズおよびロード時間の短縮といったメリットもあるのでまずはこのモジュールの利用を検討してください。

本日時点でWindows PowerShell 5.1 + .NET Framework 4.7.2以降 (Windows)およびPowerShell 6以降 (Windows, macOS, Linux)の環境での利用がサポートされています。

どう使い分けるべきか?

これから新規にAWS Tools for PowerShellを使う方は最初に「AWS.Tools.* モジュール」の利用を検討してください。
そしてツールの実行環境がWindows Server EC2である場合はデフォルトでインストールされている「AWSPowerShell モジュール」を、AWS CloudShell上では「AWSPowerShell.NetCore モジュール」の利用を検討すると良いでしょう。

導入方法

ここからはAWS Tools for PowerShellの導入手順を解説します。
前節の通り3種類のモジュールがあり導入方法が微妙に異なるのですが、本記事ではAWS.Tools.*なモジュールについてのみ触れます。

PowerShell環境は現在最新のPowerShell 7.2.2を前提とします。
本記事ではAWS CloudShellのPowerShell 7.2.1およびWindows 10のPowerShell 7.2.2環境で動作確認をしています。

1. インストール方法

AWS Tools for PowerShellのインストールはPowerShell Galleryから行います。
最初に各サービス毎のモジュールのインストールを補助するためのAWS.Tools.Installerモジュールをインストールします。

PowerShellコンソールをから以下の様にInstall-Moduleコマンドを実行してください。

# まずは AWS.Tools.Installer モジュールをインストール
Install-Module AWS.Tools.Installer -Force

AWS.Tools.Installerモジュールがインストールされると各サービス毎のモジュールを楽にインストールできるInstall-AWSToolsModuleコマンドが使用可能になります。
例えば以下の様にするとEC2とAWS Security Token Service(STS)用のモジュールをインストールします。

# その後利用するサービスに応じてモジュールをインストール (モジュール名の AWS.Tools の部分は省略可)
Install-AWSToolsModule EC2, SecurityToken -Force

実行結果を確認するとAWS.Tools.EC2AWS.Tools.SecurityTokenモジュールがインストールされていることがわかります。
同時にサービスを跨ぐ共通機能を提供するAWS.Tools.Commonモジュールもインストールされます。

C:\> Get-InstalledModule -Name AWS* | Select-Object Name, Version, Description

Name                    Version Description
----                    ------- -----------
AWS.Tools.Common        4.1.45  The AWS Tools for PowerShell lets developers and administrators manage their AWS servi…
AWS.Tools.EC2           4.1.45  The EC2 module of AWS Tools for PowerShell lets developers and administrators manage A…
AWS.Tools.Installer     1.0.2.4 The AWS.Tools.Installer module makes it easier to install, update and uninstall other …
AWS.Tools.SecurityToken 4.1.45  The SecurityToken module of AWS Tools for PowerShell lets developers and administrator…

ちなみに各サービスのモジュール名はGet-AWSServiceコマンドで調べることができます。

# Get-AWSService コマンドで各サービスのモジュール名を取得
C:\> Get-AWSService | Select-Object Service, ModuleName

Service                             ModuleName
-------                             ----------
AccessAnalyzer                      AWS.Tools.AccessAnalyzer
Account                             AWS.Tools.Account
ACMPCA                              AWS.Tools.ACMPCA
AlexaForBusiness                    AWS.Tools.AlexaForBusiness
Amplify                             AWS.Tools.Amplify
AmplifyBackend                      AWS.Tools.AmplifyBackend
AmplifyUIBuilder                    AWS.Tools.AmplifyUIBuilder
APIGateway                          AWS.Tools.APIGateway

# ・・・後略・・・

2. 認証情報の設定

次にAWS Tools for PowerShellの認証情報を設定します。
認証情報の設定方法は利用環境に応じて異なりざっくり以下の通りとなります。

利用環境 認証方式 設定手順 備考
AWS CloudShell コンテナインスタンスのロール - (設定不要) 自動でログインユーザーの認証情報が連携される
Amazon EC2, AWS Lambda等 IAMロール 参考 インスタンスメタデータ経由で認証情報を自動連携
その他 認証情報ストア 後述

AWS CloudShell上では自動でログインユーザーの認証情報が連携されるため追加設定無くAWS Tools for PowerShellを利用できます。
またEC2やLambdaなどのAWS環境では対象インスタンスにIAMロールをアタッチすることでそのロールの権限でAWS Tools for PowerShellを使えます。
それ以外の環境(例えばクライアントPCなど)では認証情報ストアと呼ばれる設定ファイルに所定の設定が必要となります。

AWS Tools for PowerShellでは基盤であるAWS SDK for .NET向けの認証情報を設定するための「AWS SDKストア」と呼ばれる設定と、AWS CLI向けの「共有認証情報ファイル」の2つの設定ファイルを使うことができます。
どちらを使っても構わないのですが、私のこれまでの経験上「共有認証情報ファイル」を使いAWS CLIとAWS Tools for PowerShellで認証情報を共用するほうが圧倒的に運用が楽になります。

共有認証情報ファイルは

  • C:\Users\[ユーザー名]\.aws\credentials (Windowsの場合)
  • ~/.aws/credentials (macOSおよびLinuxの場合)

にありAWS CLIと同一の設定をしてOKです。

~/.aws/credentials

# AWS CLI同様にアクセスキーとシークレットキーを設定
[my_profile]
aws_access_key_id=AKIxxxxxxxxxxxxxxxxxxxxxxx
aws_secret_access_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

またAWS CLIのconfigファイル(C:\Users\[ユーザー名]\.aws\configおよび~/.aws/config)の内容も 一部 共用可能であり、例えば以下の様なスイッチロール用の設定を共用できたりします。
(※明らかにPowerShell向けで無い設定は共用されません)

~/.aws/config

# AWS CLI用configファイルの設定も 一部 共用可能
# 以下のスイッチロール用の設定も共用できる
[profile switch_profile]
role_arn = arn:aws:iam::123456789012:role/my-iam-role-name
mfa_serial = arn:aws:iam::123456789012:mfa/my-iam-role-name
source_profile = my_profile

ここまでの手順で設定した認証情報(プロファイル)はGet-AWSCredentials -ListProfileDetailコマンドで確認できます。

# AWS Tools for PowerShellで利用可能なプロファイルの一覧を取得
C:\> Get-AWSCredentials -ListProfileDetail

ProfileName    StoreTypeName         ProfileLocation
-----------    -------------         ---------------
my_profile     SharedCredentialsFile C:\Users\shibata\.aws\credentials
switch_profile SharedCredentialsFile C:\Users\shibata\.aws\credentials

そしてこれらのプロファイルを利用するにはSet-AWSCredentialコマンドを使うか各コマンドレットの-ProfileNameパラメーターを指定してやります。

# Set-AWSCredential コマンドで利用する既定のプロファイルを指定
Set-AWSCredential -ProfileName my_profile

# もしくは個々のコマンドレットで都度指定する
Get-STSCallerIdentity -ProfileName my_profile

試してみた

ここからは実際の環境でAWS Tools for PowerShellを試していきます。

1. AWS CloudShellで試してみた

まずは一番手っ取り早く試せるAWS CloudShell環境で試してみます。
AWS CloudShellにはデフォルトでAWSPowerShell.NetCoreモジュールがインストール済みで認証情報も自動連係してくれます。

適当なユーザーでマネジメントコンソールにログインし、CloudShellを起動します。
CloudShellのデフォルトシェルはBashですのでpwshコマンドを実行しPowerShellを起動してやります。

本日時点ではPowerShell 7.2.1がインストール済みでした。

以下のコマンドでAWSPowerShell.NetCoreモジュールのバージョンを確認できます。

Get-Module AWS* -ListAvailable

本日時点ではVer.4.1.17.0がインストールされていました。

PowerShell本体の既知の問題により、PowerShell 6以降の環境でAWSPowerShell.NetCoreモジュールを利用するには明示的なロード(Import-Moduleの実行)が必要です。

# 既知の問題により AWSPowerShell.NetCore モジュールの明示的なロードが必要
Import-Module AWSPowerShell.NetCore

ロードには少し時間がかかるので終わるまで待ち、あとは自由に各種コマンドレットを利用してください。
たとえばVPCの情報を取得したい場合は以下の様にGet-EC2Vpcコマンドを実行します。

# 例 : デフォルトVPCの情報を取得
Get-EC2Vpc | Where-Object { $_.IsDefault }

2. クライアント環境で試してみた

次にクライアント環境(Windows 10、PowerShell 7.2.2)で試してみます。
まずは先ほど説明した様にAWS Tools for PowerShellをインストールします。

# まずは AWS.Tools.Installer モジュールをインストール
Install-Module AWS.Tools.Installer -Force
# 今回はEC2とSTSのモジュールをインストール
Install-AWSToolsModule EC2, SecurityToken -Force

インストール結果はこんな感じです。

次に認証情報を設定するために適当なIAMユーザーを作ります。

今回はpowershell-userという名前のユーザーを作ります。
必要なのはアクセスキーだけですので「アクセスキー - プログラムによるアクセス」にだけチェックを付け次へ進みます。

ユーザーに与える権限を必要に応じて設定します。
今回はマネージドポリシーのReadOnlyAccess(AWS各種リソースに対して参照のみ可能な権限)を与えておきます。

後の情報はデフォルトのまま進めていきます。

ユーザーが作成されアクセスキーとシークレットキーが発行されるので記録しておきます。

~/.aws/credentialsファイルを作成し、記録したアクセスキーとシークレットキーをに以下の様に記載します。

~/.aws/credentials

# プロファイル名は任意
[my_profile]
aws_access_key_id=<取得したアクセスキー>
aws_secret_access_key=<取得したシークレットキー>

これで事前準備が完了です。
ここからAWS Tools for PowerShellを実行していきますが、最初に以下の2つのコマンドを実行しておくと便利です。

  1. Set-AWSCredentialコマンドでデフォルトで使用するプロファイルを指定
  2. Set-DefaultAWSRegionコマンドでデフォルトで使用するリージョンを指定

またGet-STSCallerIdentityコマンドを使うと現在のIdentity情報を取得できますので、設定した内容が意図通りか確認することができます。
(AWS CLIのaws sts get-caller-identityコマンドと同等の処理です)

# デフォルトで使用するプロファイルを指定
Set-AWSCredential -ProfileName my_profile
# デフォルトで使用するリージョンを指定
Set-DefaultAWSRegion -Region ap-northeast-1

# 現在のIdentity情報を確認
Get-STSCallerIdentity

あとはCloudShellの時と同様に自由に各種コマンドレットを利用してください。

# 例 : デフォルトVPCの情報を取得
Get-EC2Vpc | Where-Object { $_.IsDefault }

Tips集

最後にAWS Tools for PowerShellを使うにあたり便利なTipsをいくつか紹介します。

1. 便利な-Select パラメーター

AWS Tools for PowerShell v4から各コマンドレットに-Selectパラメーターが追加され、コマンド実行結果のフィルタリングができる様になっています。
AWS CLIの--queryパラメーターに近いものだと考えて頂くのが分かりやすいでしょう。

# たとえば Get-EC2Instance コマンドは Reservation オブジェクトを返すが、
# -Select パラメーターによりフィルタして Instance オブジェクトを返す様にできる
C:\> Get-EC2Instance -Select Reservations.Instances

InstanceId          InstanceType Platform PrivateIpAddress PublicIpAddress SecurityGroups     SubnetId                 VpcId
----------          ------------ -------- ---------------- --------------- --------------     --------                 -----
i-05bc56047f47c67ad t2.micro              10.0.11.206                      {shiba-dev-ssh-sg} subnet-xxxxxxxxxxxxxxxxx vpc-…
i-06e12bb154979c338 t3.medium    Windows  10.0.11.128                      {shiba-dev-rdp-sg} subnet-xxxxxxxxxxxxxxxxx vpc-…

この-Selectパラメーターの記述方法は独自形式の簡素な構文ですが、入力補完が利くのでシンプルなフィルタリングには非常に便利に使えます。

2. 便利なハッシュテーブル

AWS Tools for PowerShellは.NETのオブジェクトを入出力するため、各コマンドレットのパラメーターに.NETのオブジェクトを求められることがあります。

たとえば前述のGet-EC2Instanceコマンドの-FilterパラメーターにはAmazon.EC2.Model.Filterクラスのオブジェクトが要求され、型を厳密に考えると本来であれば以下の様な指定をする必要があります。

# Amazon.EC2.Model.Filter型のオブジェクトを生成
$filter = New-Object Amazon.EC2.Model.Filter -Property @{Name = 'tag:Name'; Values = 'test-ec2'}
# コマンドレットの引数に指定
Get-EC2Instance -Filter $filter

とはいえこの様な指定をいちいち行うのは非常に手間なのでAWS Tools for PowerShellでは大抵の型はハッシュテーブルから自動変換できる様になっています。
-Filterパラメーターもハッシュテーブルを使いよりシンプルにできます。

# -Filterパラメーターにハッシュテーブルを指定 : HashTable → Amazon.EC2.Model.Filter への変換はツール側で実施
Get-EC2Instance -Filter @{Name = 'tag:Name'; Values = 'test-ec2'}

全ての型が変換可能ではない様なのですが、私の体感ではAWS Tools for PowerShell v4になってからは「とりあえず型に困ったらハッシュテーブルを渡してみる」でだいたい解決する程度には使えています。

3. 便利なスプラッティング

これはPowerShell本体の機能の話になるのですが、PowerShellにはコマンドレットに渡すパラメーターをハッシュテーブルにまとめて引き渡すことができるスプラッティングという機能があります。

大量のパラメーターを必要とするコマンドレットに対しスプラッティングを使うと処理の記述を非常にすっきりさせることができます。
たとえばEC2を作成するNew-EC2Instanceコマンドでは多くのパラメーターを指定する必要がありますが、スプラッティングを使うと以下の様な記述にすることが可能です。  

# スプラッティングを使うことにより多数のパラメーターを1つのハッシュテーブルにまとめることができる
$params = @{
    KeyName = 'my-keypair-name'
    ImageId = 'ami-00e06fadf89a04f2d' # Windows_Server-2019-Japanese-Full-Base-2022.03.09
    InstanceType = 't3.medium'
    MinCount = 1
    MaxCount = 1
    SubnetId = (Get-EC2Subnet -Filter @{Name = 'tag:Name'; Values = 'my-subnet'}).SubnetId
    SecurityGroupId = (Get-EC2SecurityGroup -Filter @{Name = 'group-name'; Values = 'my-security-group'}).GroupId
    EbsOptimized = $false
    BlockDeviceMapping = @(
        # root volume
        [Amazon.EC2.Model.BlockDeviceMapping]@{
            DeviceName = '/dev/sda1'
            Ebs = @{
                VolumeType = 'gp3'
                VolumeSize = 30
                DeleteOnTermination = $true
            }
        }
    )
    TagSpecification = @{
        ResourceType = 'Instance';
        Tags         = @( @{Key = 'Name'; value = 'my-test-ec2'});
    }
}
New-EC2Instance @params

# スプラッティングを使わない場合はこんな感じの記述をしなければならない
New-EC2Instance -KeyName 'my-keypair-name' `
    -ImageId 'ami-00e06fadf89a04f2d' `
    -InstanceType 't3.medium' -MinCount 1 -MaxCount 1 `
    -SubnetId (Get-EC2Subnet -Filter @{Name = 'tag:Name'; Values = 'my-subnet'}).SubnetId `
    -SecurityGroupId (Get-EC2SecurityGroup -Filter @{Name = 'group-name'; Values = 'my-security-group'}).GroupId `
    -EbsOptimized $false 
    #
    # ・・・めんどうなので後略・・・
    #

4. 便利な比較サイト

AWSのドキュメントはAWS CLIを前提としてるものが多く、AWS Tools for PowerShellのドキュメントは正直それほど多くありません。
このため「AWS CLIではaws hogehogeコマンドを使えば良いのはわかったが、AWS Tools for PowerShellでどのコマンドレットを使えば良いかわからない」という事態になることがままあります。

その様な事態に対応するためにAWS CLIのコマンドとAWS Tools for PowerShellのコマンドレットの対応表をまとめたサイトを自作しており、手前味噌ではありますが結構役に立つと自負しております。

このサイトを作った動機や実装についてはこちらの記事に書いてますのでよろしければご覧ください。

終わりに

以上、『AWS 再入門ブログリレー 2022』の32日目のエントリ『AWS Tools for PowerShell』編でした。
次回、3/21(月)は弊社yhanaによる「AWS Single Sign-On編」の予定です!