小ネタです。
AWS IAM Policy を作成する際に以下の様なエラーが発生することがあります。
An error occurred (MalformedPolicyDocument) when calling the CreatePolicy operation: The policy failed legacy parsing
このエラー自体は汎用的なメッセージであり、発生原因はいくつか存在するようです。
JSONとしては正しいが、IAM Policy の仕様上許可されない場合に出力されるようです。
少し謎な仕様があったのでメモ。
基本
AWSマネジメントコンソールの Policy editor で表示される雛形です。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Action": [], "Resource": [] } ] }
文法に関する諸々は公式ドキュメントにまとまっています。
IAM JSON ポリシーリファレンス - AWS Identity and Access Management
先頭は {
で始まる必要があります。
よくある話です。
空白や改行が先頭にあるとエラーになります。
Policy editor 上では少し詳しいメッセージ出力となり、作成時に “JSON strings must not have leading spaces” が出力されます。
作成時に と書いたのは、Validation 時点で判明せず、 “Next” ボタン押下時に出力されるためです。
CLI や SDK での実行では “The policy failed legacy parsing” としか教えてくれません。 access-analyzer での ValidatePolicy も通ります。
Statement は配列 である必要があります。
本題です。Statement 要素は 配列
です。
"Statement": [{...},{...},{...}]
だがしかし、1オブジェクトでの作成は許可されます。
“Statement” が1つで済むポリシーは、値部分が配列である必要はなく、オブジェクトでも作成できます。
尚、この記述方法は公式ドキュメント上でも普通に使われています。
- JSON ポリシー概要
JSON ポリシー構文の例
だがしかしだがしかし、オブジェクトの場合は Version 要素が先頭である必要があります。
本題の本題です。
公式ドキュメント上の "ポリシーの文法に関する注意事項" に要素順は問わないとあるのですが、通りません。
- IAM JSON ポリシー言語の文法 - AWS Identity and Access Management
ブロックは任意の順序で記述できます。
+ cat policy.object.error.json { "Statement": { "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::example_bucket" }, "Version": "2012-10-17" } + aws iam create-policy --policy-name example-policy.object.error --policy-document file://policy.object.error.json An error occurred (MalformedPolicyDocument) when calling the CreatePolicy operation: The policy failed legacy parsing
Policy editor での”Next”ボタン押下は通り、その後の “Create policy” ボタン押下後にエラーになります。
尚、 “Statement” が配列であれば通ります。
まとめ
余計なトラブルの回避のため Statement 要素は配列
, Version は先頭
にしておくのが良さそうです。