Cloudformation模板验证错误?

时间:2016-03-23 16:49:08

标签: amazon-cloudformation

我收到了以下错误,但不知道它来自哪里,希望有人可以提供帮助。

Template validation error: Template format error: Any Properties member must be a JSON object.

cloudformation脚本

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "The AWS CloudFormation template for this Serverless application's resources outside of Lambdas and Api Gateway",
  "Resources": {
    "KMSKey": {
      "Type": "AWS::KMS::Key",
      "Properties": {
        "Description": "KMS Key Dev",
        "Enabled": "True",
        "EnableKeyRotation": "True",
        "KeyPolicy": {
          "Version": "2012-10-17",
          "Id": "key-default-1",
          "Statement": {
            "Effect": "Allow",
            "Action": [
              "kms:Encrypt",
              "kms:Decrypt",
              "kms:ReEncrypt*",
              "kms:GenerateDataKey*",
              "kms:DescribeKey"
            ],
            "Resource": "*"
          }
        }
      }
    },
    "IamRoleLambda": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "lambda.amazonaws.com"
                ]
              },
              "Action": [
                "sts:AssumeRole"
              ]
            }
          ]
        },
        "Path": "*"
      }
    },
    "IamPolicyLambda": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": "dev-lambda",
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Resource": "arn:aws:logs:us-east-1:*"
            },
            {
              "Effect": "Allow",
              "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
              ],
              "Resource": {
                "Ref": "KMSKey"
              }
            },
            {
              "Effect": "Allow",
              "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DetachNetworkInterface",
                "ec2:DeleteNetworkInterface",
                "elastiCache:*"
              ],
              "Resource": "*"
            },
            {
              "Effect": "Allow",
              "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
              ],
              "Resource": [
                "arn:aws:s3:::{domain.com}/",
                "arn:aws:s3:::{domain.com}/Serverless/*"
              ]
            }
          ]
        },
        "Roles": [
          {
            "Ref": "IamRoleLambda"
          }
        ]
      }
    },
    "RedisCluster": {
      "Type": "AWS::ElastiCache::CacheCluster",
      "Properties": {
        "AutoMinorVersionUpgrade": "False",
        "AZMode": "cross-az",
        "CacheNodeType": "cache.m3.medium",
        "VpcSecurityGroupIds": {
          "Ref": "VpcSecurityGroup"
        },
        "ClusterName": "Dev",
        "Engine": "redis",
        "EngineVersion": "2.8",
        "NumCacheNodes": "1",
        "Tags": [
          {
            "Key": "CostCenter",
            "Value": "0000000000000000"
          },
          {
            "Key": "Application",
            "Value": "Appname"
          },
          {
            "Key": "Function",
            "Value": "cache"
          },
          {
            "Key": "Environment",
            "Value": "dev"
          }
        ]
      }
    },
    "VpcSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "DEV VPC Security group form",
        "SecurityGroupEgress": {
          "Ref": "SecurityGroupEgress"
        },
        "SecurityGroupInress": {
          "Ref": "SecurityGroupIngress"
        },
        "Tags": [
          {
            "Key": "CostCenter",
            "Value": "0000000000000000"
          },
          {
            "Key": "Application",
            "Value": "Appname"
          },
          {
            "Key": "Function",
            "Value": "cache"
          },
          {
            "Key": "Environment",
            "Value": "dev"
          }
        ],
        "VpcId": "vpc-8c3113e2"
      }
    },
    "SecurityGroupEgress": {
      "Type": "AWS::EC2::SecurityGroupEgress",
      "Properties": [
        {
          "CidrIp": "0.0.0.0/0",
          "FromPort": "443",
          "ToPort": "443",
          "IpProtocol": "tcp"
        },
        {
          "CidrIp": "0.0.0.0/0",
          "FromPort": "80",
          "ToPort": "80",
          "IpProtocol": "tcp"
        },
        {
          "DestinationSecurityGroupId": {
            "Fn:GetAtt": [
              "VpcSecurityGroup"
            ]
          },
          "FromPort": "6379",
          "ToPort": "6379",
          "IpProtocol": "tcp"
        }
      ]
    },
    "SecurityGroupIngress": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": [
        {
          "CidrIp": "0.0.0.0/0",
          "FromPort": "443",
          "ToPort": "443",
          "IpProtocol": "tcp"
        },
        {
          "CidrIp": "0.0.0.0/0",
          "FromPort": "80",
          "ToPort": "80",
          "IpProtocol": "tcp"
        },
        {
          "DestinationSecurityGroupId": {
            "Fn:GetAtt": [
              "VpcSecurityGroup"
            ]
          },
          "FromPort": "6379",
          "ToPort": "6379",
          "IpProtocol": "tcp"
        }
      ]
    }
  },
  "Outputs": {
    "IamRoleArnLambda": {
      "Description": "ARN of the lambda IAM role",
      "Value": {
        "Fn::GetAtt": [
          "IamRoleLambda",
          "Arn"
        ]
      }
    }
  }
}

1 个答案:

答案 0 :(得分:1)

该错误描述了Properties成员需要JSON对象。查看代码,将两个Properties成员定义为JSON数组。根本问题是AWS::EC2::SecurityGroupIngressAWS::EC2::SecurityGroupEgress资源定义了单个安全组规则,而您尝试在单个资源中定义多个规则。

我发现除了完全打开的端口80和443之外,您还尝试自我引用自定义端口(6379)的安全组。如documentation中所述,这是正确的使用AWS::EC2::SecurityGroupEgressAWS::EC2::SecurityGroupIngress资源的用例:

  

重要

     

如果要在这些安全组的入口和出口规则中交叉引用两个安全组,请使用AWS::EC2::SecurityGroupEgressAWS::EC2::SecurityGroupIngress资源来定义规则。请勿在{{1​​}}中使用嵌入式入口和出口规则。如果这样做,则会导致循环依赖,AWS CloudFormation不允许这样做。

要在不定义其他资源的情况下完成此操作,您可以将完全打开的端口规则与资源内联(因为它们不会导致循环依赖),并且只为这些资源创建其他AWS::EC2::SecurityGroup资源你想锁定到安全组:

AWS::EC2::SecurityGroup[In|E]gress

你还要确保小心Fn :: GetAtt函数的拼写和语法,我已在上面为你纠正过。