awsのassume-roleに対応していなそうなコマンドを無理やり使う方法のメモ

たまに以下の様な形で実行できないaws用のコマンドが存在する。

$ AWS_PROFILE=<profile> <cmd>

例えばcf-to-tfとかがそう。

github.com

カジュアルに使おうとして動かなかった。

$ AWS_PROFILE=playground AWS_REGION=us-east-1 npx @humanmade/cf-to-tf  --stack EC2ContainerService-lambda-check config | tee /tmp/ecs.json
{ Error: connect EHOSTUNREACH 169.254.169.254:80 - Local (192.168.10.100:50396)
    at internalConnect (net.js:882:16)
    at defaultTriggerAsyncIdScope (internal/async_hooks.js:294:19)
    at defaultTriggerAsyncIdScope (net.js:972:9)
    at process._tickCallback (internal/process/next_tick.js:61:11)
  message:
   'Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1',
  errno: 'EHOSTUNREACH',
  code: 'CredentialsError',
  syscall: 'connect',
  address: '169.254.169.254',
  port: 80,
  time: 2021-07-02T07:19:20.572Z,
  originalError:
   { message: 'Could not load credentials from any providers',
     errno: 'EHOSTUNREACH',
     code: 'CredentialsError',
     syscall: 'connect',
     address: '169.254.169.254',
     port: 80,
     time: 2021-07-02T07:19:20.572Z,
     originalError:
      { message: 'EC2 Metadata roleName request returned error',
        errno: 'EHOSTUNREACH',
        code: 'EHOSTUNREACH',
        syscall: 'connect',
        address: '169.254.169.254',
        port: 80,
        time: 2021-07-02T07:19:20.571Z,
        originalError: [Object] } } } 

aws sts assume-roleを使って動かす

aws sts assume-roleを使う。 返ってきたJSONをいい感じに環境変数に埋めて使えば動くようになる。

aws sts assume-roleの結果は以下のようなもの (https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role.html#examples より)

{
    "AssumedRoleUser": {
        "AssumedRoleId": "AROA3XFRBF535PLBIFPI4:s3-access-example",
        "Arn": "arn:aws:sts::123456789012:assumed-role/xaccounts3access/s3-access-example"
    },
    "Credentials": {
        "SecretAccessKey": "9drTJvcXLB89EXAMPLELB8923FB892xMFI",
        "SessionToken": "AQoXdzELDDY//////////wEaoAK1wvxJY12r2IrDFT2IvAzTCn3zHoZ7YNtpiQLF0MqZye/qwjzP2iEXAMPLEbw/m3hsj8VBTkPORGvr9jM5sgP+w9IZWZnU+LWhmg+a5fDi2oTGUYcdg9uexQ4mtCHIHfi4citgqZTgco40Yqr4lIlo4V2b2Dyauk0eYFNebHtYlFVgAUj+7Indz3LU0aTWk1WKIjHmmMCIoTkyYp/k7kUG7moeEYKSitwQIi6Gjn+nyzM+PtoA3685ixzv0R7i5rjQi0YE0lf1oeie3bDiNHncmzosRM6SFiPzSvp6h/32xQuZsjcypmwsPSDtTPYcs0+YN/8BRi2/IcrxSpnWEXAMPLEXSDFTAQAM6Dl9zR0tXoybnlrZIwMLlMi1Kcgo5OytwU=",
        "Expiration": "2016-03-15T00:05:07Z",
        "AccessKeyId": "ASIAJEXAMPLEXEG2JICEA"
    }
}

今回使うのは以下。

テキトーにjsonに出力して、jqで取り出して使っている1

実行例。これで動いた。例としてはシェルを新しく立ち上げてexportしたほうがわかりやすかったかもしれない。

$ AWS_PROFILE=playground aws sts assume-role --role-arn arn:aws:iam::xxxxxx:role/PlayGround --role-session-name cf-to-tf > /tmp/credentials.json
$ AWS_ACCESS_KEY_ID=$(jq -r .Credentials.AccessKeyId /tmp/credentials.json) AWS_SECRET_ACCESS_KEY=$(jq -r .Credentials.SecretAccessKey /tmp/credentials.json) AWS_SESSION_TOKEN=$(jq -r .Credentials.SessionToken /tmp/credentials.json) AWS_REGION=us-east-1 npx @humanmade/cf-to-tf  --stack EC2ContainerService-lambda-check config | tee /tmp/ecs.json

# 整形
$ cat /tmp/ecs.json | json2hcl | npx @humanmade/cf-to-tf clean-hcl| terraform fmt - | tee /tmp/ecs.tf

が、今回の用途ではcf-to-tfの出力結果はあまり良い感じに使えなかった。 まぁ今回はaws sts assume-roleのメモということで。

dockerでの利用

その他の利用方法として、環境変数経由でAWSへのアクセス情報を渡すのは、dockerのコンテナの中でawsへのリクエストが必要なときにも使える2。 だいたいawssdk (e.g. go-aws-sdk) などがこの辺の環境変数に対応しているので。

関連

使えそうな環境変数はこの辺を見ると良い。

assume-role似関しては以下のページも参考になる


  1. いつか消えるであることを期待して /tmp 以下に出力して使うということを結構やっている気がする

  2. あるい~/.awsをvolumeで共有しても良いが..