根据AWS,我的策略不起作用。JSONlint说我有一个有效的json。语法有问题,但我没看出来。
此策略包含以下错误:策略不符合IAM (Identity and Access Management)策略语法。有关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"
}
}
}
}
]
}
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的优势在于其简单的结构和约束:它有{
对象}
(键/值对,其中键是字符串,值恰好是这句话中任何地方提到的任何类型的东西之一)…[
数组]
(值列表)…"
strings "
…数字(未引用)……布尔值(true
和false
,未引号)…and 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对象中,单个键只能有一个值——记住,"值"意味着一个对象、数组、字符串、数字、布尔值或空值。当存在多个值时,必须正确地嵌套在内部结构中。
那么,正确的表示是什么呢?
"Condition": {
"StringEquals": {
"ec2:ResourceTag/sf_env": ["dev"],
"ec2:Region": ["us-west-2"]
}
}
作为Condition
的值的对象有一个键StringEquals
,它的值是一个有两个键ec2:ResourceTag/sf_env
和ec2:Region
的对象;每个键的值都是一个由一个或多个字符串组成的数组。
因此,不仅可以使用多个StringEquals
测试,如果需要,当值在我所示的数组中显示时,每个测试还可以匹配几个值中的任何一个。例如,["dev","prod"]
代替["dev"]
将匹配dev
或prod
。
如果您每个只有一个值,IAM似乎支持使用字符串而不是数组,例如"dev"
取代["dev"]
(这也是有效的JSON),但我观察到的文档示例倾向于显示它,正如我上面记录的那样,作为{ key1: [ "list" ], key2: ["list"] }
…等等,如果你现在这样格式化它,如果你以后想允许更多可能的值,它会更直观。
我最近遇到了这个问题。下面是构造它的方法:
"Condition": {
"ForAllValues:StringEquals": {
"ec2:ResourceTag/sf_env": "dev",
"ec2:Region": "us-west-2"
}
}
JSON中不能有两个StringEquals。我使用StringLike作为一种变通方法。这篇文章帮助我找到了答案。我的策略现在有正确的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"
}
}
}
]
}