AWS Systems ManagerのRunCommandでAWSCLIの実行ファイルが見つからない問題への対処法
AWSのSystems ManagerのRunCommandを利用して、スクリプト内のAWSCLIのコマンド呼び出しに失敗した問題の解説と、対処方法について記事にします。
どんな状況?
例えば以下の様なPowerShellのスクリプトファイルがあったとします。
※スクリプトには、あまり意味はありません!
$awscliVersion = aws.exe --version
Write-Host $awscliVersion
このファイルをEC2のWindowsインスタンス上に設置し、これをRunCommand経由で呼び出す様に、ローカルマシン上で、次の様なコマンドを実行します。
なお、実行はPowerShellのターミナルから実施するものとします。
aws ssm send-command `
--document-name "AWS-RunPowerShellScript" `
--document-version "1" `
--targets "Key=instanceids,Values=<EC2のインスタンスIDを指定>" `
--parameters "commands=['D:¥Get-CLIVersion.ps1']" `
--timeout-seconds 60 `
--output json
これが失敗する理由は、一般的にはEC2にロールが設定されていないとか、そういったことはよくありますよね。もちろん、プロファイルやロールなりで設定しておけば実行できるはずです。
正しく実行できれば、Systems ManagerのRunCommandを経由してローカルでサーバー側のAWSCLIのバージョンが取得できるという寸法です。
で、私もとあるEC2インスタンスでaws.exeを呼び出す際には何の問題もなく実行できていたのです。
ところが、別の環境で実行したところaws.exeが見つからないというエラーに悩まされることになりました。これが全ての始まりです。
なぜ、aws.exeが見つからないのか?
初めはAWSCLIのインストールを忘れていたのかと思い、EC2にリモートデスクトップで接続して確認したところ、確かにそこにはAWSCLIがインストールされているのです。
設置したスクリプトをEC2上で直接実行してみると、正しく結果が返ってきます。
つまり、サーバーにログインして実行すると問題はないが、RunCommand経由で実行すると見つからないのです。
AWSCLIはセットアップ時に環境変数PATHにawsコマンドがあるパスが登録されているはずですので、見つからないはずがありません・・。
スクリプト実行時に環境変数PATHの中身を出力して確認してみましょう。
先ほどの、Get-BucketList.ps1の先頭に以下の1行を追加しましょう。
$env:Path > env.txt
では、以下のコマンドを叩いて確認してみましょう。
aws ssm send-command `
--document-name "AWS-RunPowerShellScript" `
--document-version "1" `
--targets "Key=instanceids,Values=<EC2のインスタンスIDを指定>" `
--parameters "commands=['D:¥Get-BucketList.ps1']" `
--timeout-seconds 60 `
--output json
実行が完了した頃合いにGet-BucketList.ps1のパスにできたenv.txtファイルを開いて確認すると、環境変数PATHの内容が出力されており、AWSCLIのパスも登録されていることを確認できました。
では、読み取れない環境で同じように実行してみます。
すると、env.txtにはAWSCLIのパスが出力されていません。
調べてみますと、以下の条件では、環境変数を意図した通りに読めないとのことでした。
- Windowsのサービスで動作している
- サービスがLocal System権限で動作している
- 環境変数に追加されたのち、OS再起動を行っていない
つまり、AWSCLIをインストール後、OSを再起動していなかったために発生していた問題ということがわかりました。
Administratorなどでログインして、スクリプトを直接実行すると環境変数が取れることとも辻褄が合いますね。
解決策
と、いうことで、解決策は2つ考えられます。
一つは、OSを再起動して環境変数をロードできる状態にする方法。
もう一つは、再起動できない状況などでしたら、以下のように環境変数に追加してしまう方法です。
$env:Path += ";環境変数に追加したいパスをここに"
"の後のセミコロンは忘れずに!
以上、Windowsのまだまだ知らない構造を知るきっかけになりました。
Discussion
トラブルシューティング大変お疲れ様でした!
初見では解決にとても時間がかかりそうな現象なのでとても勉強になりました。
AWS で Windows の EC2 インスタンス運用は今のところ未経験ですが、必要が生じた際にはこの記事で得られた知見を活用させてもらおうと思います😊
コメントありがとうございます!
ぜひ役立てていただけたら、これ以上の幸いはありません!