【问题标题】:Cloudformation Template validation error?Cloudformation 模板验证错误?
【发布时间】:2016-07-11 02:15:23
【问题描述】:

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

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"
        ]
      }
    }
  }
}

【问题讨论】:

    标签: amazon-cloudformation


    【解决方案1】:

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

    除了完全开放的端口 80 和 443 之外,我看到您正在尝试为自定义端口 (6379) 自引用安全组。如 documentation 中所述,这是正确的用法 -使用AWS::EC2::SecurityGroupEgressAWS::EC2::SecurityGroupIngress资源的案例:

    重要

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

    要在不定义多个额外资源的情况下完成此操作,您可以将完全开放的端口规则与资源内联(因为它们不会导致循环依赖),并为您想要的那些创建额外的 AWS::EC2::SecurityGroup[In|E]gress 资源锁定到安全组:

    "VpcSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "DEV VPC Security group form",
        "SecurityGroupEgress": [
          {
            "CidrIp": "0.0.0.0/0",
            "FromPort": "443",
            "ToPort": "443",
            "IpProtocol": "tcp"
          },
          {
            "CidrIp": "0.0.0.0/0",
            "FromPort": "80",
            "ToPort": "80",
            "IpProtocol": "tcp"
          }
        ],
        "SecurityGroupIngress": [
          {
            "CidrIp": "0.0.0.0/0",
            "FromPort": "443",
            "ToPort": "443",
            "IpProtocol": "tcp"
          },
          {
            "CidrIp": "0.0.0.0/0",
            "FromPort": "80",
            "ToPort": "80",
            "IpProtocol": "tcp"
          }
        ],
        "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": {
        "DestinationSecurityGroupId": {
          "Fn::GetAtt": [
            "VpcSecurityGroup",
            "GroupId"
          ]
        },
        "FromPort": "6379",
        "ToPort": "6379",
        "IpProtocol": "tcp"
      }
    },
    "SecurityGroupIngress": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "SourceSecurityGroupId": {
          "Fn::GetAtt": [
            "VpcSecurityGroup",
            "GroupId"
          ]
        },
        "FromPort": "6379",
        "ToPort": "6379",
        "IpProtocol": "tcp"
      }
    }
    [...etc...]
    

    您还需要确保注意 Fn::GetAtt 函数的拼写和语法,我已经在上面为您更正了。

    【讨论】:

      猜你喜欢
      • 2016-12-03
      • 2018-06-03
      • 2018-06-03
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 2016-03-19
      • 2018-12-15
      • 2020-07-10
      相关资源
      最近更新 更多