Template Format Error in AWS CloudFormation can come in different forms.
Here, at Bobcares, we assist our customers with several AWS queries as part of our AWS Support Services.
Today, let us see how we can resolve the template errors.
Template Format Error in AWS CloudFormation
Moving ahead, our Support Techs discuss different error messages that we may receive. We can select accordingly.
However, to run the AWS Command Line Interface commands, make sure to have the most recent version of the AWS CLI.
-
Validate template syntax
In case of, “JSON not well-formed” or “YAML not well-formed” errors we can use this step.
In order to follow proper JSON or YAML syntax in the CloudFormation template:
- Initially, we create the stack with AWS CloudFormation Designer.
- Then, we validate the JSON syntax with a text editor or a command-line tool.
- After that, we need to validate the YAML syntax with the AWS CloudFormation validate-template command.
- Also, validate the JSON or YAML templates with the AWS CloudFormation linter on the GitHub website.
-
Validate logical and physical IDs
For “Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template” errors, we perform this.
1. First, we confirm that resource logical IDs are defined in the template.
2. Also, we need to confirm that resource physical IDs exist in the environment.
For instance, the following JSON and YAML templates do not define the resource ID correctly.
This will eventually return the error.
JSON:
{ "Parameters" : { ... }, "Resources" : { "EC2Instance01" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : {"Ref": "test"}, ... } } } }
YAML:
Parameters: Resources: EC2Instance01: Type: AWS::EC2::Instance Properties: ImageId: !Ref: test
-
Validate parameter definitions
For “Unrecognized parameter type: XXXXXXXX” or “Invalid template parameter property ‘XXXXXXXX’” errors, our Support Techs suggest:
1. To set Type to either of the following: String, Number, List<Number>, or CommaDelimitedList.
2. Then in the CloudFormation template, we verify that the parameters include only the following permitted properties:
"Parameters" : { "ParameterName" : { "AllowedPattern" : "A regular expression that represents the patterns to allow for String types.", "AllowedValues" : "An array containing the list of values allowed for the parameter", "ConstraintDescription" : "A string that explains a constraint when the constraint is violated" "Default" : "A value of the appropriate type for the template to use if no value is specified when a stack is created. If you define constraints for the parameter, you must specify a value that adheres to those constraints", "Description" : "A string of up to 4000 characters that describes the parameter", "MaxLength" : "An integer value that determines the largest number of characters you want to allow for String types", "MaxValue" : "A numeric value that determines the largest numeric value you want to allow for Number types.", "MinLength" : "An integer value that determines the smallest number of characters you want to allow for String types.", "MinValue" : "A numeric value that determines the smallest numeric value you want to allow for Number types.", "NoEcho" : "Whether to mask the parameter value when a call is made that describes the stack. If you set the value to true, the parameter value is masked with asterisks (*****).", "Type" : "The data type for the parameter (DataType)." },
3. In addition, we confirm that the Parameters section doesn’t contain any intrinsic functions.
For example, here, the default value for ParameterC has the intrinsic function, Fn::Sub. This will eventually lead us to the error.
JSON:
{ "Parameters": { "ParameterA": { "Type": "String", "Default": "abc" }, "ParameterB": { "Type": "String", "Default": "def" }, "ParameterC": { "Type": "String", "Default": { "Fn::Sub": "${ParameterA}-${ParameterB}" } } }, "Resources": { "MyS3Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": { "Ref": "ParameterC" } } } } }
YAML:
Parameters: ParameterA: Type: String Default: abc ParameterB: Type: String Default: def ParameterC: Type: String Default: !Sub '${ParameterA}-${ParameterB}' Resources: MyS3Bucket: Type: 'AWS::S3::Bucket' Properties: BucketName: !Ref ParameterC
-
Confirm that Conditions is specified as a string
Another possible error is “Every Condition member must be a string”.
To resolve this, in the CloudFormation template, we specify Conditions as a string.
For example, in the below example, the condition in the resource EC2RouteA specifies as a list of strings instead of a single string.
These templates result in a validation error.
JSON:
{ "Conditions": { "ConditionA": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] }, "ConditionB": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] } }, "Resources": { "EC2RouteA": { "Type": "AWS::EC2::Route", "Condition": [ "ConditionA", "ConditionB" ], "Properties": { ... } } } }
YAML:
Conditions: ConditionA: !Not - !Equals - '' - Sample ConditionB: !Not - !Equals - '' - Sample Resources: EC2RouteA: Type: 'AWS::EC2::Route' Condition: - ConditionA - ConditionB Properties:
To resolve this, we add ConditionAandB to the template. After that, we use ConditionAandB as the condition for the EC2RouteA resource.
For instance, see the following JSON and YAML templates:
JSON:
{ "Conditions": { "ConditionA": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] }, "ConditionB": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] }, "ConditionAandB": { "Fn::And": [ { "Condition": "ConditionA" }, { "Condition": "ConditionB" } ] } }, "Resources": { "EC2RouteA": { "Type": "AWS::EC2::Route", "Condition": "ConditionAandB", "Properties": { ... } } } }
YAML:
Conditions: ConditionA: Fn::Not: - Fn::Equals: - '' - Sample ConditionB: Fn::Not: - Fn::Equals: - '' - Sample ConditionAandB: Fn::And: - Condition: ConditionA - Condition: ConditionB Resources: EC2RouteA: Type: AWS::EC2::Route Condition: ConditionAandB Properties:
-
Verify the availability of the resource type
For “Unrecognized resource types: [XXXXXXXX]” errors our Support Techs recommend these steps.
1. Initially, we verify that the resource is available in the AWS Region.
For example, the resource type AWS::WAFRegional::IPSet in the following examples is currently unavailable in ap-south-1.
This will eventually lead us to the error.
JSON:
{ "IPSetlistA": { "Type": "AWS::WAFRegional::IPSet", "Properties": { "Name": "IPSet for IP addresses that are not allowed", "IPSetDescriptors": [ { "Type": "IPV4", "Value": "x.x.x.x/x" }, { "Type": "IPV4", "Value": "x.x.x.x/x" } ] } } }
YAML:
IPSetlistA: Type: 'AWS::WAFRegional::IPSet' Properties: Name: IPSet for IP addresses that are not allowed IPSetDescriptors: - Type: IPV4 Value: x.x.x.x/x - Type: IPV4 Value: x.x.x.x/x
2. If the template consists of any serverless resources, then we include a Transform declaration.
For example, see the following:
JSON:
{ "Transform": "AWS::Serverless-2016-10-31", "Resources": { "MyServerlessFunctionLogicalID": { "Type": "AWS::Serverless::Function", "Properties": { "Handler": "index.handler", "Runtime": "nodejs8.10", "CodeUri": "s3://testBucket/mySourceCode.zip" } } } }
YAML:
Transform: AWS::Serverless-2016-10-31 Resources: MyServerlessFunctionLogicalID: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs8.10 CodeUri: 's3://testBucket/mySourceCode.zip'
-
Validate properties, values, and value types
In the case of “Encountered unsupported property XXXXXXXX” errors, we use the valid properties, values, and value types in the template sections and resource definitions.
-
Verify that the resource exists outside the stack
For “The [environmental resource] ‘XXXXXXXX’ does not exist” errors we need to verify that the resource exists outside the stack, or validate dependencies for resources in the same stack
We need to verify the following if we are hardcoding a resource or ARN for a resource that exists outside of the CloudFormation stack into one of the stack’s resources:
- Correct resource name or ARN.
- The resource exists.
- Resource exists in the same AWS Region as the stack.
If the security group doesn’t exist or doesn’t exist in the stack’s AWS Region in your stack that’s specifying a security group, then the AWS::EC2::Instance resource fails with the error.
For example:
LinuxInstance: Type: AWS::EC2::Instance Properties: SubnetId: !Ref ServerSubnetID KeyName: !Ref EC2KeyPairName SecurityGroupIds: sg-1234567890 <This resource must exist and be in the same AWS Region
-
Include a Resources section in the template
For “At least one Resources member must be defined” errors, we must include a Resources section in the CloudFormation template.
Failure of the same will lead us to the error.
-
Verify template properties
For “Invalid template property or properties [XXXXXXXX]” errors our techs recommend the steps below.
We should only use permitted template properties in the CloudFormation template.
In the example here, the bucket resource is on the same level as the Resources section. This returns the error.
This happens because the CloudFormation template validator sees the bucket resource as a section-level specification, which isn’t allowed as a template property.
JSON:
{ "Resources": { "WaitCondition": { "Type": "AWS::CloudFormation::WaitCondition" } }, "Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "Name": "BucketName" } } }
YAML:
Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition Bucket: Type: AWS::S3::Bucket Properties: Name: BucketName
[Stuck in between? We are here to assist you any time of the day]
Conclusion
In short, we saw how our Support Techs fix the AWS CloudFormation errors for our customers.
PREVENT YOUR SERVER FROM CRASHING!
Never again lose customers to poor server speed! Let us help you.
Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.
0 Comments