根据AWS,我的政策不起作用。 JSONlint说我有一个有效的json。有一个语法问题,但我没有看到它。
此策略包含以下错误:策略不符合身份和访问管理(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"
}
}
}
}
]
}
答案 0 :(得分: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的优势在于其简单的结构和约束:它有{
个对象}
(键/值对,其中键是一个字符串,值正好是任何一个这句话中任何地方提到的事物类型)...... [
数组]
(值列表)...... "
字符串"
...数字(未加引号) )...布尔(true
和false
,未加引号)...和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对象中,单个键只能拥有一个值 - 记住"值"意味着一个对象,数组,字符串,数字,布尔值或null。当存在多个值时,它必须在内部结构内正确嵌套。
那么,正确的表现是什么?
"Condition": {
"StringEquals": {
"ec2:ResourceTag/sf_env": ["dev"],
"ec2:Region": ["us-west-2"]
}
}
作为Condition
值的对象有一个键StringEquals
,其值为具有两个键的对象ec2:ResourceTag/sf_env
和ec2:Region
;这些键中的每一个都具有一个或多个字符串的数组作为其值。
因此,不仅可以使用多个StringEquals
测试,如果需要,每个测试也可以匹配多个值中的任何一个,当我在数组中显示值时所示。例如,代替["dev","prod"]
的{{1}}将匹配["dev"]
或dev
。
如果每个只有一个值,IAM似乎只支持使用字符串而不是数组,例如prod
替换"dev"
(这也是有效的JSON),但我观察到的文档示例往往会像我上面记录的那样展示它,如["dev"]
...等等,如果你现在就这样格式化,如果你想在以后允许更多可能的值,它会更加直观。
答案 1 :(得分:0)
JSON中不能有两个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"
}
}
}
]
}
答案 2 :(得分:0)
我最近遇到了这个问题。下面是您将如何构造它:
"Condition": {
"ForAllValues:StringEquals": {
"ec2:ResourceTag/sf_env": "dev",
"ec2:Region": "us-west-2"
}
}