EC2メタデータから取得できる一時クレデンシャルの有効期限を確認してみた

2015.11.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

西澤です。RedshiftにS3からデータをロードする際には、COPYコマンドにS3にアクセス可能な認証情報を渡す必要がありますが、そのままではEC2のインスタンスプロファイルの権限を利用することができません。その具体的な利用方法については、これまでのブログに詳細に記載されていますので、まずはこちらをご覧ください。

一時クレデンシャルの有効期限が切れたらどうなるのか?

AWS CLIAWS SDKは、EC2に割り当てたインスタンスプロファイル(IAMロール)の権限を自動で取得できるように実装されているので安心です。しかも認証情報は下記の通り、AWSが自動的に循環させてくれると記載されています。

インスタンスのアプリケーションは、インスタンスメタデータアイテム"iam/security-credentials/role-name"のロールから提供されたセキュリティ認証情報を取得します。アプリケーションには、ロールに関連付けられたセキュリティ認証情報によって、ロールに対して定義したアクションおよびリソースのアクセス許可が付与されます。これらのセキュリティ認証情報は一時的なものであり、私たちが自動的に循環させます。新しい認証情報は、古い認証情報が失効する少なくとも 5 分前から有効になるようにします。

でも、Redshiftの公式ドキュメントには下記の記載があります。COPYコマンド実行中に一時セキュリティ認証の有効期限が切れると、COPYが失敗する、と。。。

一時的セキュリティ認証情報は、COPY ステートメントの期間全体で有効にする必要があります。一時的セキュリティ認証情報の期限がロードプロセス中に切れた場合、COPY は失敗し、処理はロールバックされます。例えば、一時的セキュリティ認証情報の期限が 15 分後に切れるときに COPY に 1 時間かかる場合、COPY は完了前に失敗します。

それでは困ります!かといってCOPYコマンド専用にアクセスキーを作ることはやりたくない。

EC2メタデータの有効期限を確認してみた

ということで、実際に検証してみました。自動的に循環されるというメタデータ上のインスタンスプロファイルですが、リンクローカルアドレスにアクセスすることで有効期限も確認できるので、実際に情報を取得し続けて結果を見てみることにしました。

Amazon Linuxでの確認

下記のようなスクリプトを仕込んでログに出力し続けてみました。

curl -q http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2Role | egrep "LastUpdated|Expiration" | while read line; do echo "`date +'[%Y/%m/%d %H:%M:%S] '` $line"; done >> curl.log

結果はこのようになりました。

[2015/11/18 00:00:01]  "LastUpdated" : "2015-11-17T23:48:25Z",
[2015/11/18 00:00:01]  "Expiration" : "2015-11-18T06:09:50Z"
[2015/11/18 01:00:01]  "LastUpdated" : "2015-11-18T00:51:11Z",
[2015/11/18 01:00:01]  "Expiration" : "2015-11-18T07:24:27Z"
[2015/11/18 02:00:01]  "LastUpdated" : "2015-11-18T01:50:59Z",
[2015/11/18 02:00:01]  "Expiration" : "2015-11-18T08:18:06Z"
[2015/11/18 03:00:01]  "LastUpdated" : "2015-11-18T02:51:01Z",
[2015/11/18 03:00:01]  "Expiration" : "2015-11-18T09:24:35Z"
[2015/11/18 04:00:01]  "LastUpdated" : "2015-11-18T03:54:44Z",
[2015/11/18 04:00:01]  "Expiration" : "2015-11-18T10:26:02Z"
[2015/11/18 05:00:01]  "LastUpdated" : "2015-11-18T04:58:13Z",
[2015/11/18 05:00:01]  "Expiration" : "2015-11-18T11:21:46Z"
[2015/11/18 06:00:01]  "LastUpdated" : "2015-11-18T04:58:13Z",
[2015/11/18 06:00:01]  "Expiration" : "2015-11-18T11:21:46Z"
[2015/11/18 07:00:01]  "LastUpdated" : "2015-11-18T06:00:36Z",
[2015/11/18 07:00:01]  "Expiration" : "2015-11-18T12:06:38Z"
[2015/11/18 08:00:01]  "LastUpdated" : "2015-11-18T07:02:39Z",
[2015/11/18 08:00:01]  "Expiration" : "2015-11-18T13:03:11Z"
[2015/11/18 09:00:01]  "LastUpdated" : "2015-11-18T08:03:35Z",
[2015/11/18 09:00:01]  "Expiration" : "2015-11-18T14:26:05Z"
[2015/11/18 10:00:01]  "LastUpdated" : "2015-11-18T09:03:38Z",
[2015/11/18 10:00:01]  "Expiration" : "2015-11-18T15:08:52Z"
[2015/11/18 11:00:01]  "LastUpdated" : "2015-11-18T10:03:53Z",
[2015/11/18 11:00:01]  "Expiration" : "2015-11-18T16:15:29Z"
[2015/11/18 12:00:01]  "LastUpdated" : "2015-11-18T11:03:41Z",
[2015/11/18 12:00:01]  "Expiration" : "2015-11-18T17:35:17Z"

Windowsでの確認

結果は変わらないとは思いましたが、サンプルを増やす為にWindowsも。下記のようなスクリプトを仕込んでログに出力し続けてみました。

$now = Get-Date -Format "[yyyy/MM/dd HH:mm:ss] "
$invoke = invoke-restmethod -uri http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2Role
$output1 = $now + "LastUpdated: " + $invoke.LastUpdated
$output2 = $now + "Expiration: " + $invoke.Expiration
$output1 >> invoke.log
$output2 >> invoke.log

結果はこのようになりました。

[2015/11/18 02:00:00] LastUpdated: 2015-11-18T01:54:25Z
[2015/11/18 02:00:00] Expiration: 2015-11-18T08:12:49Z
[2015/11/18 03:00:00] LastUpdated: 2015-11-18T02:56:23Z
[2015/11/18 03:00:00] Expiration: 2015-11-18T09:21:46Z
[2015/11/18 04:00:00] LastUpdated: 2015-11-18T03:56:40Z
[2015/11/18 04:00:00] Expiration: 2015-11-18T10:21:38Z
[2015/11/18 05:00:00] LastUpdated: 2015-11-18T03:56:40Z
[2015/11/18 05:00:00] Expiration: 2015-11-18T10:21:38Z
[2015/11/18 06:00:00] LastUpdated: 2015-11-18T05:00:48Z
[2015/11/18 06:00:00] Expiration: 2015-11-18T11:07:47Z
[2015/11/18 07:00:00] LastUpdated: 2015-11-18T06:03:03Z
[2015/11/18 07:00:00] Expiration: 2015-11-18T12:22:24Z
[2015/11/18 08:00:00] LastUpdated: 2015-11-18T07:04:00Z
[2015/11/18 08:00:00] Expiration: 2015-11-18T13:17:37Z
[2015/11/18 09:00:00] LastUpdated: 2015-11-18T08:06:26Z
[2015/11/18 09:00:00] Expiration: 2015-11-18T14:28:43Z
[2015/11/18 10:00:00] LastUpdated: 2015-11-18T09:07:46Z
[2015/11/18 10:00:00] Expiration: 2015-11-18T15:37:30Z
[2015/11/18 11:00:00] LastUpdated: 2015-11-18T10:07:24Z
[2015/11/18 11:00:00] Expiration: 2015-11-18T16:22:09Z
[2015/11/18 12:00:00] LastUpdated: 2015-11-18T11:09:13Z
[2015/11/18 12:00:00] Expiration: 2015-11-18T17:20:05Z
[2015/11/18 13:00:00] LastUpdated: 2015-11-18T12:09:47Z
[2015/11/18 13:00:00] Expiration: 2015-11-18T18:18:19Z
[2015/11/18 14:00:00] LastUpdated: 2015-11-18T13:10:08Z
[2015/11/18 14:00:00] Expiration: 2015-11-18T19:42:17Z

確認結果のまとめ

検証した結果をまとめると、以下のように動作しているようでした。

  • 60分強の頻度で認証情報が更新されている
  • 更新時に6時間強の有効期間で認証情報が取得されている

ということで、やや安心できる結果となりました。

  • メタデータの一時認証情報の有効期間が取得時点から5時間を下回ることはなかった
  • 5時間以上の処理を行う場合は、メタデータを使うと有効期限が途中で切れる可能性がある

まとめ

ということで、検証の結果からはRedshiftへのロードに5時間以上かかるような処理をしない限りは大丈夫、ということで安心しました。ただし、本記事は検証の結果であり、動作を保証するものではありませんので、くれぐれもご注意ください。