PowerShellからAWSを操作するための設定

# 概要
## この記事で行うこと
普段AWSコンソール画面から行っているEC2インスタンスの作成、起動、CloudWatchやRoute53などの操作をPowerShellからできるようにするための設定方法を記録します。

PowerShellへAWSPowerShellモジュールをインストール&インポートすることにより、操作が可能になります。

[AWS CLI](https://aws.amazon.com/jp/cli/)にてAWSの操作が可能ですが、そのPowerShell版となります。
AWS CLIとの違いや、どちらのツールを使うのが良いか悩んだ場合は、[こちらの記事](https://dev.classmethod.jp/articles/re-introduction-2022-aws-tools-for-powershell/)が参考になるかと思います。
ちなみに以下のように書かれていました。
> 普段からPowerShellを使い慣れておりPowerShellの流儀に合わせたい場合はAWS Tools for PowerShellを採用してください。
逆にAWS CLIの方を使い慣れているのであれば無理をしてまでAWS Tools for PowerShellを選択する必要はありません。皆さんが使い慣れてるツールを選びやりたいことを実現してください。


## なぜそうしたいか
AWSコンソール画面はレイアウトに変更が入ったりします。
作業手順書を作成しても、レイアウトが変わると手順書が古くなってしまいます。
PowerShellでAWSの操作ができるようになることで、これらのレイアウト変更に振り回されなくなります。

また、手順をPowerShellのスクリプトとして作成することで、繰り返し作業の負担軽減や、手作業によるミスの回避などが期待できます。


# Windowsでの設定

## AWSPowerShellをインストールする
AWSPowerShellをインストールすることにより、基本的なAWS操作が可能になります。
より細かい操作のためのモジュールのインストールやバージョン管理を行いたい場合は、AWS.Tools.InstallerとAWS.Tools.Commonのインストールが必要らしいです。
これらのインストール方法は後述します。

```bash:PowerShell
Install-Module -Name AWSPowerShell
```

## AWSPowerShellをインポートする
先ほどインストールしたAWSPowerShellをインポートします。
```bash:PowerShell
Import-Module AWSPowerShell
```
※このままだとPowerShellを立ち上げるたびにインポートする必要があります。

:::note info
PowerShellにおける、Install-ModuleとImport-Moduleについて

PowerShellではモジュールを使用する際、インストールとインポートの二つの手順を実施する必要があります。
Install-Moduleは初回のみ実行する必要があります。
Import-Moduleは、PowerShellが開始されるたびに実行する必要があります。

ただし、この挙動はモジュールによって異なる事があるようで、インストールと同時にインポートされるモジュールもあるようです。
正確な挙動はモジュールごとに確認するのが確実です。
:::

## PowerShellの起動時に自動的にAWSPowerShellモジュールをロードするように設定する
これは必要に応じて実施する。

次のコマンドを実施して、PowerShellプロファイルを作成/編集する
```bash:PowerShell
notepad $PROFILE.CurrentUserAllHosts
```
プロファイルが編集状態になるので、以下の行を追加、保存する。
`Import-Module AWSPowerShell`

## AWS.Tools.Installerのインストール
AWS.Tools.Installerは、AWS.Toolsモジュールを管理するためのツールです。
必要になったらインストールするくらいで良いと思います。
基本的な操作だけであれば、AWSPowerShellのみで足りる認識です。
詳しくは以下を参照

[Windows PowerShell 用 AWS Tools](https://aws.amazon.com/jp/powershell/)

:::note warn
AWSPowerShellをインストールした後に、AWS.Tools.InstallerとAWS.Tools.Commonをインストールしたところ、次のようなワーニングが表示されました。

> 警告: AWS Tools for PowerShell の複数のバリアント (AWSPowerShell、AWSPowerShell.NetCore または AWS.Tools) が現在インストールされています。詳細については、「Get-Module -Name AWSPowerShell,AWSPowerShell.NetCore,AWS.Tools.Common -ListAvailable」を実行してください。コマンドレットの自動インポートの問題を回避するには、1 つのバリアントのみをインストールすることをお勧めします。
AWS.Tools は、AWS Tools for PowerShell の新しいモジュール化バージョンで、PowerShell Core 6 以降および Windows Powershell 5.1 以降 (.NET Framework 4.7.2 以降がインストールされている場合) と互換性があります。
AWSPowerShell.NetCore は、単一の大きなモジュールですべての AWS サービスをサポートするモノリシック バリアントで、PowerShell Core 6 以降および Windows Powershell 3 以降 (.NET Framework 4.7.2 以降がインストールされている場合) と互換性があります。
AWSPowerShell は、Windows PowerShell 2 を実行しているか、.NET Framework 4.7.2 (またはそれ以降) に更新できない古いシステム用のレガシー モジュールです。

AWSPowerShellをインストールせずとも、AWS.Tools.InstallerとAWS.Tools.Commonで適切なモジュールをインストールすれば同じようにスクリプトが動いたので、どちらか片方を使用するようにしたほうが良さそうです。

:::

```bash:PowerShell
Install-Module -Name AWS.Tools.Installer
```

## AWS.Tools.Commonのインストール
AWSのサービスにアクセスするための基本的な機能を提供します。
AWS.Tools.Installerと合わせて、必要に応じてインストールしてください。
```bash:PowerShell
Install-AWSToolsModule AWS.Tools.Common
```

## インストールされているか確認する
ここまででインストールした一覧を確認します。
```bash:PowerShell
Get-Module -ListAvailable -Name AWS*
```

# 認証情報の設定と確認
## 認証情報の設定
AWSアカウントにアクセスするための認証設定を行う。
```bash:PowerShell
Set-AWSCredential -AccessKey "xxxxxxxxxxxxxxxx" -SecretKey "xxxxxxxxxxxxxxxx" -StoreAs "xxxx"
```
引数について
- -AccessKey
    - アクセスキー
- -SecretKey
    - シークレットキー
- -StoreAs
    - AWSの認証情報を特定の名前で保存するためのオプション。複数の認証情報を保存して、アカウントを切り替えて使用することができる。

## 認証情報の確認
認証情報が正しく設定できたか確認する。
```bash:PowerShell
Get-AWSCredential -ListProfileDetail
```

# リージョンの設定と確認
## リージョンの設定
```bash:PowerShell
Set-DefaultAWSRegion -Region xxxxxxx
```
引数について
- -Region
    - 使用するリージョンを指定する
> この設定は、現在のセッションの間のみ保持されます。

## リージョンの確認
```bash:PowerShell
Get-DefaultAWSRegion
```

# AWSへの接続ができたか確認する
 ## EC2インスタンス情報を取得する
 以下のコマンドでエラーが出ないか確認する。
 ```bash:PowerShell
 Get-EC2Instance
 ```
## EC2インスタンスを作成する
`New-EC2Instance`を使ってEC2インスタンスを作成するサンプルコードです。
以下の項目を入力値として受け取ります。
- リージョン
- AMIのID
- インスタンスタイプ
- キーペアの名前

適切な値を入力して、EC2が作成できるか試してみてください。
実行後に`Get-EC2Instance`を実行して、EC2の一覧情報を取得すれば、先の実行結果との差分を確認できます。


```bash:PowerShell
$logFilePath = Join-Path -Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) -ChildPath "logfile.txt"

if (-not (Test-Path $logFilePath)) {
    New-Item -Path $logFilePath -ItemType File
}

$region = Read-Host "Enter the region for the EC2 instance"
$imageId = Read-Host "Enter the ImageId for the EC2 instance"
$instanceType = Read-Host "Enter the InstanceType for the EC2 instance"
$keyName = Read-Host "Enter the KeyName for the EC2 instance"

try {
    Import-Module AWSPowerShell
    Set-DefaultAWSRegion -Region $region

    # Create instance name
    $timeStamp = (Get-Date).ToString("yyyyMMdd-HHmmss")
    $instanceName = "sample_instance_$timeStamp"

    # create tags for EC2 instance
    $tagSpecification_es2 = @{ `
            ResourceType = "instance"; `
            Tags         = @( `
            @{Key = "Name"; value = $instanceName } `
        ); `
    
    }

    # create EC2 instance
    $instance = New-EC2Instance `
        -ImageId $imageId `
        -InstanceType $instanceType `
        -KeyName $keyName `
        -BlockDeviceMapping @{ DeviceName = "/dev/sda1"; Ebs = @{ VolumeSize = 50; VolumeType = "gp2" } } `
        -TagSpecification $tagSpecification_es2
    
    $instance.Instances.InstanceId | Out-File -FilePath $logFilePath -Append
}
catch {
    # exception handling
    $errorMessage = $_.Exception.Message
    $errorLog = "Error occurred: $errorMessage"
    $errorLog | Out-File -FilePath $logFilePath -Append
}
```


 
# アンインストール方法
アンインストールで詰まったのでメモ的に残します。
この方法がベストなのかは判断しかねるので、行う際は自己責任でお願いします。

## AWS.Tools.Common のアンインストール
次のコマンドを実施します。
```bash:PowerShell
Uninstall-Module -Name AWS.Tools.Common
```
※AWS.Tools.Commonモジュールが使用されている場合、失敗する可能性があります。その場合はPowerShellを再起動してから試してみてください。

## AWS.Tools.Installer のアンインストール
```bash:PowerShell
Uninstall-Module -Name AWS.Tools.Installer
```
こちらで削除失敗した時があったので、仕方なく以下の方法で、手動で削除しました。
次のコマンドを実施し、インストールされているフォルダを調べます。
```bash:PowerShell
Get-Module -ListAvailable -Name AWS*
```
直接削除します。

## AWSPowerShellのアンインストール
```bash:PowerShell
Uninstall-Module -Name AWSPowerShell
```

# 参考URL
どのようなコマンドが実施可能かは、以下の情報を参照してください。
[AWS Tools for PowerShell Cmdlet Reference](https://docs.aws.amazon.com/powershell/latest/reference/)