我收到了以下错误,但不知道它来自哪里,希望有人可以提供帮助。
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"
]
}
}
}
}
答案 0 :(得分:1)
该错误描述了Properties成员需要JSON对象。查看代码,将两个Properties成员定义为JSON数组。根本问题是AWS::EC2::SecurityGroupIngress
和AWS::EC2::SecurityGroupEgress
资源定义了单个安全组规则,而您尝试在单个资源中定义多个规则。
我发现除了完全打开的端口80和443之外,您还尝试自我引用自定义端口(6379)的安全组。如documentation中所述,这是正确的使用AWS::EC2::SecurityGroupEgress
和AWS::EC2::SecurityGroupIngress
资源的用例:
重要强>
如果要在这些安全组的入口和出口规则中交叉引用两个安全组,请使用
AWS::EC2::SecurityGroupEgress
和AWS::EC2::SecurityGroupIngress
资源来定义规则。请勿在{{1}}中使用嵌入式入口和出口规则。如果这样做,则会导致循环依赖,AWS CloudFormation不允许这样做。
要在不定义其他资源的情况下完成此操作,您可以将完全打开的端口规则与资源内联(因为它们不会导致循环依赖),并且只为这些资源创建其他AWS::EC2::SecurityGroup
资源你想锁定到安全组:
AWS::EC2::SecurityGroup[In|E]gress
你还要确保小心Fn :: GetAtt函数的拼写和语法,我已在上面为你纠正过。