EC2インスタンスメタデータからワンライナーでクレデンシャルを取得してみた (Windows Server編)

2022.10.09

しばたです。

先日弊社臼田により以下の記事が公開されました。

こちらではLinux向けのワンライナーが紹介されていますが、PowerShellおじさんとしてWindows Server版の手順を紹介しようと思います。

ワンライナー (Windows PowerShell / PowerShell 7)

PowerShell環境では以下のワンライナーでインスタンスメタデータのクレデンシャルを取得できます。

# PowerShell 3.0以降の環境で動作
'http://169.254.169.254/latest/meta-data/iam/security-credentials/'|%{irm "$_/$(irm $_)"}

実行例はこんな感じです。

# Windows Server 2016で動作確認
PS C:\> 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'|%{irm "$_/$(irm $_)"}

Code            : Success
LastUpdated     : 2022-10-09T02:25:58Z
Type            : AWS-HMAC
AccessKeyId     : ASIAXXXXXXXXXXXXXXXX
SecretAccessKey : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Token           : xxxxxxxxxxxxxxxxxxx ・・・中略・・・  xxxxxxxxxxxxxxxxxxx
Expiration      : 2022-10-09T09:00:00Z

こちらエイリアスをバリバリ使ってますので、エイリアス無しバージョンだとこんな感じです。
ワンライナーでは無くなりましたが環境依存の心配事がない形となります。

# 内容としては割とシンプルに Invoke-RestMethod を二回実行してるだけ
'http://169.254.169.254/latest/meta-data/iam/security-credentials/' | ForEach-Object {
    Invoke-RestMethod -Uri "$_/$(Invoke-RestMethod -Uri $_)"
}

データ取得に必要なURLが

  • http://169.254.169.254/latest/meta-data/iam/security-credentials/
  • http://169.254.169.254/latest/meta-data/iam/security-credentials/IAMロール名

の2種なのでシンプルにInvoke-RestMethodを二回実行しているだけです。
エイリアス無しだと直感的に理解できるかと思います。

ちなみにPowerShell 7でも動作しますので、Linux EC2にPowerShell 7をインストールした環境であれば同じワンライナーが使えます。

補足 : 元のワンライナーについて

個人的にはワンライナーはどうにかしてパイプでつなげたい派です。
臼田の記事にあったワンライナーは変数を使ってますが、変数がアリなら個人的には$()を使う形が好きですね。

# 個人的には $() を使うのが好き
mu=http://169.254.169.254/latest/meta-data/iam/security-credentials/;curl -s $mu/$(curl -s $mu)

# 実行例
$ mu=http://169.254.169.254/latest/meta-data/iam/security-credentials/;curl -s $mu/$(curl -s $mu)
{
  "Code" : "Success",
  "LastUpdated" : "2022-10-09T03:33:40Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIAXXXXXXXXXXXXXXXX",
  "SecretAccessKey" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "Token" : "xxxxxxxxxxxxxxxxxxx ・・・中略・・・  xxxxxxxxxxxxxxxxxxx",
  "Expiration" : "2022-10-09T09:58:16Z"
}

で、どうにかパイプで繋げられないか頑張ったのですがこの辺が限界でした...

# xargsでコマンド文字列を生成させて別シェルで実行
echo http://169.254.169.254/latest/meta-data/iam/security-credentials/ | xargs -I@ sh -c 'curl -s $(echo @$(curl -s @))'

# 実行例
$ echo http://169.254.169.254/latest/meta-data/iam/security-credentials/ | xargs -I@ sh -c 'curl -s $(echo @$(curl -s @))'
{
  "Code" : "Success",
  "LastUpdated" : "2022-10-09T05:30:59Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIAXXXXXXXXXXXXXXXX",
  "SecretAccessKey" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "Token" : "xxxxxxxxxxxxxxxxxxx ・・・中略・・・  xxxxxxxxxxxxxxxxxxx",
  "Expiration" : "2022-10-09T11:33:45Z"
}

最後に

簡単ですが以上となります。
シェルスクリプトは本当に難しいですね...