When I started troposphere there wasn't a resource specification formally defining the various resource and properties for CloudFormation.
The resource spec came out and it's been interesting to see it evolve. For a project like troposphere, it is sorely needed to ensure correctly reflecting the CloudFormation constrects into code (Python for troposphere). This allowed resources and properties to be auto-generated and have better accuracy.
But recently I've seen some odd usage patterns being used with it which I don't believe are correct. Below is some commentary on it.
Isssue: properties without Properties
#!/usr/bin/env python3
import json
# CloudFormation resource specification file
filename = "CloudFormationResourceSpecification.json"
def find_no_properties(spec):
props = []
for p, d in spec['PropertyTypes'].items():
if 'Properties' not in d:
props.append(p)
print('\n'.join(sorted(props)))
if __name__ == "__main__":
# read in the resource spec
spec = json.loads(open(filename).read())
find_no_properties(spec)
AWS::AppSync::GraphQLApi.AdditionalAuthenticationProviders
AWS::AppSync::GraphQLApi.Tags
AWS::CodeBuild::Project.FilterGroup
AWS::EC2::LaunchTemplate.CapacityReservationPreference
AWS::Glue::SecurityConfiguration.S3Encryptions
AWS::LakeFormation::DataLakeSettings.Admins
AWS::Transfer::User.SshPublicKey
AWS::WAFv2::RuleGroup.AllQueryArguments
AWS::WAFv2::RuleGroup.AllowAction
AWS::WAFv2::RuleGroup.BlockAction
AWS::WAFv2::RuleGroup.Body
AWS::WAFv2::RuleGroup.CountAction
AWS::WAFv2::RuleGroup.Method
AWS::WAFv2::RuleGroup.QueryString
AWS::WAFv2::RuleGroup.UriPath
AWS::WAFv2::WebACL.AllQueryArguments
AWS::WAFv2::WebACL.AllowAction
AWS::WAFv2::WebACL.BlockAction
AWS::WAFv2::WebACL.Body
AWS::WAFv2::WebACL.CountAction
AWS::WAFv2::WebACL.Method
AWS::WAFv2::WebACL.NoneAction
AWS::WAFv2::WebACL.QueryString
AWS::WAFv2::WebACL.UriPath
Let's look at a couple of these via the individual files:
$ cat spec/LakeFormationDataLakeSettingsSpecification.json
{
"PropertyTypes": {
"AWS::LakeFormation::DataLakeSettings.Admins": {
"Type": "List",
"Required": false,
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-datalakesettings-admins.html",
"ItemType": "DataLakePrincipal",
"UpdateType": "Mutable"
},
"AWS::LakeFormation::DataLakeSettings.DataLakePrincipal": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-datalakesettings-datalakeprincipal.html",
"Properties": {
"DataLakePrincipalIdentifier": {
"Required": false,
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-datalakesettings-datalakeprincipal.html#cfn-lakeformation-datalakesettings-datalakeprincipal-datalakeprincipalidentifier",
"PrimitiveType": "String",
"UpdateType": "Mutable"
}
}
}
},
"ResourceType": {
"AWS::LakeFormation::DataLakeSettings": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lakeformation-datalakesettings.html",
"Properties": {
"Admins": {
"Type": "Admins",
"Required": false,
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lakeformation-datalakesettings.html#cfn-lakeformation-datalakesettings-admins",
"UpdateType": "Mutable"
}
}
}
},
"ResourceSpecificationVersion": "9.1.1"
}
Here we have DataLakeSettings defining a Property (Admins) which is of type 'Admins'. This Property is then defined as a List of DataLakePrincipal. Why is there an intermediate Admins Propery? Why isn't "Admins" just defined as a List of DataLakePrincipal?
Issue: Empty Property
{
"PropertyTypes": {
"AWS::WAFv2::WebACL.AllowAction": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wafv2-webacl-allowaction.html"
},
"AWS::WAFv2::WebACL.BlockAction": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wafv2-webacl-blockaction.html"
},
Here we have WAFv2 properties being defined only as "Documentation". Why???
Issue: Tags