2015-08-21 154 views
0

我的策略不适用于AWS。 JSONlint说我有一个有效的json。有一个语法问题,但我没有看到它。带有多个条件的AWS IAM策略语法错误

此策略包含以下错误:策略不符合身份和访问管理(IAM)策略语法。有关IAM策略语法的更多信息,请参阅AWS IAM策略。

{ 
"Version": "2012-10-17", 
"Statement": [ 
    { 
     "Effect": "Allow", 
     "Action": "ec2:*", 
     "Resource": "*", 
     "Condition": { 
      "StringEquals": {"ec2:ResourceTag/sf_env": "dev", 
      "StringEquals": {"ec2:Region": "us-west-2" 
      } 
      } 
     } 
    }, 
    { 
     "Effect": "Allow", 
     "Action": "rds:*", 
     "Resource": "*", 
     "Condition": { 
      "StringEquals": { "ec2:ResourceTag/sf_env": "dev", 
      "StringEquals": { "ec2:Region": "us-west-2" 
      } 
      } 
     } 
    }, 
    { 
     "Sid": "AllowHealthCheckOnly", 
     "Effect": "Allow", 
     "Action": "elasticloadbalancing:Describe*", 
     "Resource": "*", 
     "Condition": { 
      "StringEquals":{ "ec2:ResourceTag/sf_env": "dev", 
      "StringEquals":{ "ec2:Region": "us-west-2" 
      } 
     } 
    } 
    }, 
    { 
     "Sid": "ConfigureHealthCheckOnly", 
     "Effect": "Allow", 
     "Action": "elasticloadbalancing:ConfigureHealthCheck", 
     "Resource": "arn:aws:elasticloadbalancing:us-west-2:xxxxxxxxxxxx:loadbalancer/instance1", 
     "Condition": { 
      "StringEquals": { "ec2:ResourceTag/sf_env": "dev", 
      "StringEquals": { "ec2:Region": "us-west-2" 
      } 
      } 
     } 
    }, 
    { 
     "Sid": "FullElasticCacheManagedPolicyPermissions", 
     "Effect": "Allow", 
     "Action": [ 
      "elasticache:*", 
      "ec2:DescribeAvailibilityZones", 
      "ec2:DescribeVpcs", 
      "ec2:DescribeAccountAttributes", 
      "ec2:DescribeSeucrityGroups", 
      "cloudwatch:GetMetricStatistics", 
      "cloudwatch:DescribeAlarms", 
      "sns:ListTopics", 
      "sns:ListSubscriptions" 
     ], 
     "Resource": "*", 
     "Condition": { 
      "StringEquals": { "ec2:ResourceTag/sf_env": "dev", 
      "StringEquals": { "ec2:Region": "us-west-2" 
      } 
      } 
     } 
    } 
] 

}

+2

Spitballing在这里,但它看起来像在每个语句中的第一个'StringEquals'可能没有在正确的时间关闭后的大括号? –

+0

大括号可以,它们在哪里。 json对此并不敏感。我认为问题在于我如何写出多重条件和关键值。第一次尝试这个。我可以得到1个条件检查工作就好了。 http://docs.aws.amazon.com/IAM/latest/UserGuide/conditions-setoperators.html http://docs.aws.amazon.com/IAM/latest/UserGuide/policies-grammar.html – ficestat

+0

@HyperAnthony转身绝对正确。当然,只要你不小心想出了一个同样有效的JSON结构 - 这就是发生在这里的事情 - 但是JSON对这个并不“敏感”,但是关键和值明显不符合要求,会导致序列化陷入混乱。解决这个问题揭示了第二个问题,即对象具有重复键,可能会导致某些值存储在位桶中,而不是存储在行另一端的反序列化结构中。 –

回答

-1

你不能在JSON 2个StringEquals。我使用StringLike作为解决方法。 post帮我弄清楚了这一点。我的政策现在有正确的AWS语法!

{ 
"Version": "2012-10-17", 
"Statement": [ 
    { 
     "Effect": "Allow", 
     "Action": "ec2:*", 
     "Resource": "*", 
     "Condition": { 
      "StringEquals": { 
      "ec2:ResourceTag/sf_env": "dev" 
      }, 
      "StringLike": {"ec2:Region": "us-west-2" 
      } 
     }  
    }, 
    { 
     "Effect": "Allow", 
     "Action": "rds:*", 
     "Resource": "*", 
     "Condition": { 
      "StringEquals": { 
       "ec2:ResourceTag/sf_env": "dev" 
      }, 
      "StringLike": { 
       "ec2:Region": "us-west-2" 
      } 
      } 
    }, 
    { 
     "Sid": "AllowHealthCheckOnly", 
     "Effect": "Allow", 
     "Action": "elasticloadbalancing:Describe*", 
     "Resource": "*", 
     "Condition": { 
      "StringEquals":{ 
       "ec2:ResourceTag/sf_env": "dev" 
     }, 
      "StringLike":{ 
       "ec2:Region": "us-west-2" 
      } 
     } 
    }, 
    { 
     "Sid": "ConfigureHealthCheckOnly", 
     "Effect": "Allow", 
     "Action": "elasticloadbalancing:ConfigureHealthCheck", 
     "Resource": "arn:aws:elasticloadbalancing:us-west-2:xxxxxxxxxxxx:loadbalancer/instance1", 
     "Condition": { 
      "StringEquals": { 
       "ec2:ResourceTag/sf_env": "dev" 
      }, 
      "StringLike": { "ec2:Region": "us-west-2" 
      } 
     } 
    }, 
    { 
     "Sid": "FullElasticCacheManagedPolicyPermissions", 
     "Effect": "Allow", 
     "Action": [ 
      "elasticache:*", 
      "ec2:DescribeAvailibilityZones", 
      "ec2:DescribeVpcs", 
      "ec2:DescribeAccountAttributes", 
      "ec2:DescribeSeucrityGroups", 
      "cloudwatch:GetMetricStatistics", 
      "cloudwatch:DescribeAlarms", 
      "sns:ListTopics", 
      "sns:ListSubscriptions" 
     ], 
     "Resource": "*", 
     "Condition": { 
      "StringEquals": { 
       "ec2:ResourceTag/sf_env": "dev" 
      }, 
      "StringLike": { "ec2:Region": "us-west-2" 
      } 
      } 
    } 
] 

}

6

JSONLint说,你有语法有效的JSON和你做......但问题是,你成功...编码数据不会使语义意义。

在您的最后一个条件看只是,你写道:

"Condition": { 
     "StringEquals": { "ec2:ResourceTag/sf_env": "dev", 
     "StringEquals": { "ec2:Region": "us-west-2" 
     } 
     } 
    } 

请注意:由于以下是抠出一个更大的JSON对象的键/值片断,你必须巢每一种在额外的{大括号外括号}用于JSONLint来解析它,并且实际上它是在没有周围结构的情况下自行评估时确实是有效的JSON表示。在测试创建示例时,我在每种情况下将这些添加到了JSONLint输入中,并将其从输出中移除,希望为了清晰起见。

JSONLint重新格式化以上,显示你什么你沟通:

"Condition": { 
      "StringEquals": { 
       "ec2:ResourceTag/sf_env": "dev", 
       "StringEquals": { 
        "ec2:Region": "us-west-2" 
       } 
      } 
     } 

JSON的优势在于它的简单结构和约束:它有{对象}(键/值对,其中关键是一个字符串,并且该值恰恰是在这个句子中提到的任何类型的东西之一)... [数组](值的列表)... "字符串" ...数字(未加引号)...布尔值( ,truefalse,未加引号)...和null(null,未加引号)。

StringEquals,因为你都表示它上面,是具有两个键,ec2:ResourceTag/sf_env(其具有一个字符串作为它的值)...和StringEquals(第二外观,其具有另一个嵌套对象作为其值)的对象。

显然,这不是你想要的,但它是你提供的东西的正确解释。

请注意,缩进是完全可选的,但JSONLint的输出格式以有意义的方式使用缩进。注意"ec2:ResourceTag/sf_env""ec2:Region"(使用非JSON项)“同胞”(与数据结构的同一级别)如何,不同的缩进是你的红旗,一切都不好。

更正括号的位置,你可能是为了更写的东西是这样的:

"Condition": { 
    "StringEquals": { "ec2:ResourceTag/sf_env": "dev" }, 
    "StringEquals": { "ec2:Region": "us-west-2" } 
} 

这看起来更明智,虽然它仍然是几乎可以肯定是不正确的,因为这样反序列化的工作原理:现在你有两个StringEquals键在同一个对象,虽然JSON标准似乎并不禁止这种,行为是不确定充其量,许多或反序列化,这将解释上述大多数图书馆的意思是:

"Condition": { 
    "StringEquals": { 
     "ec2:Region": "us-west-2" 
    } 
} 

后面的键和它们的值可以合理地预期将取代相同的早期键和它们的值。

这就是JSONLint解释它的方式。在一个JSON对象中,一个键只能有一个值 - 记住“value”的意思是一个对象,数组,字符串,数字,布尔值或空值。当存在多个值时,它必须正确嵌套在内部结构中。

那么,什么是正确的表示?

"Condition": { 
    "StringEquals": { 
     "ec2:ResourceTag/sf_env": ["dev"], 
     "ec2:Region": ["us-west-2"] 
    } 
} 

目的即是Condition的值具有一个键,StringEquals,其值是与两个键,ec2:ResourceTag/sf_envec2:Region的对象;每个键的值都是一个或多个字符串的数组。

这样,不仅可以使用多个StringEquals测试,每个测试者的也可以匹配任何几个值,如果需要的话,当值我已经表明了数组中呈现。例如,["dev","prod"]代替["dev"]将匹配devprod

如果每个值只有一个值,IAM似乎只支持使用字符串而不是数组,例如, "dev"替换["dev"](这也是有效的JSON),但我观察到的记录的示例倾向于显示它,因为我已经记录在上面,如{ key1: [ "list" ], key2: ["list"] } ...等,如果现在以这种方式进行格式化,它将会更加直观如果你想稍后允许更多可能的值。

+1

tyvm的详细答案。我是json的新手,并撰写这些政策。我会用数组更新我的策略。这对了解json如何工作非常有帮助。 – ficestat