Giter Site home page Giter Site logo

cfval's People

Contributors

jagregory avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

jmhobbs jsueper

cfval's Issues

AWS::RDS::DBSubnetGroup Ref value

The Ref docs and the DBSubnetGroup docs both have no mention of a Ref value for a DBSubnetGroup (although the Ref docs do list DBSecurityGroup twice which could be an oversight).

However, there is a sample template VPC_WordPress_Single_Instance_With_RDS.template which does use a Ref of an DBSubnetGroup and it appears to be the Name.

CLI core functionality

The CLI tool itself is very bare bones. It literally does nothing apart from receive JSON from STDIN.

The minimum the CLI should do is:

  • Support reading JSON from a file, with error handling for bad filenames etc...
  • Support reading JSON from STDIN
  • Fail appropriately if neither file nor STDIN are used
  • Use exit codes for success/fail
  • Help/usage examples
  • Version number

Using String for Index in Select is an Error

template:

{
  "Parameters": {
    "subnetIds": {
      "Type": "List<AWS::EC2::Subnet::Id>"
    }
  },
  "Resources": {
    "ElasticacheSubnetGroup": {
      "Type": "AWS::ElastiCache::SubnetGroup",
      "Properties": {
        "Description": ".",
        "SubnetIds": [
         { "Fn::Select": [ "0", { "Ref": "subnetIds" } ] }
        ]
      }
    }
  }
}

yields error:

ERROR   Resources.ElasticacheSubnetGroup.SubnetIds.0.Fn::Select.Index   Wrong type for index string

using cfval version e7af583dbdc0f7641678070a176c82a7a9ffe996.

Dangerous coersions seem to usually be warnings, so the only thing that seems out of place to me here is that this is reported as an error.

CloudFormation Init service ensureRunning and enabled are Number instead of Bool

The Cloudformation Init services UserGuide documents both ensureRunning and enabled as boolean.

The template:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "instance": {
      "Type": "AWS::EC2::Instance",
      "Metadata": {
        "AWS::CloudFormation::Init": {
          "foo": {
            "services": {
              "sysvinit": {
                "bar": {
                  "ensureRunning": true,
                  "enabled": true
                }
              }
            }
          }
        }
      }
    }
  }
}

Yields these undesired errors:

Resources.instance.Metadata.AWS::CloudFormation::Init.foo.services.sysvinit.bar.enabled ......... Value of Bool used in Number property
Resources.instance.Metadata.AWS::CloudFormation::Init.foo.services.sysvinit.bar.ensureRunning ... Value of Bool used in Number property

version: 87b495da21cbd389ad5532a2824919a5b674361c

Deeper inspections of Ref and GetAtt

Step 1. Validate that uses of Ref and GetAtt will return a value of the correct type

"KeyName": { "Ref": "MaxInstanceCount" } // should fail due to MaxInstanceCount being an int

Step 2. Introduce richer types to further help with validations

"SecurityGroupId": { "Ref": "SecurityGroup" } // should fail because Ref on a SecurityGroup returns the NAME not the ID
"SecurityGroupName": { "Fn::GetAtt": ["SecurityGroup", "GroupId"] } // ditto

AWS::NoValue and conditional properties

It's possible to use AWS::NoValue with conditions to "unset" a property, allowing you to have otherwise conflicting properties together.

e.g.

"VPCSecurityGroups": { "Fn::If" : [ "Is-EC2-VPC", [ { "Fn::GetAtt": [ "DBEC2SecurityGroup", "GroupId" ] } ], { "Ref" : "AWS::NoValue"}]},
"DBSecurityGroups": { "Fn::If" : [ "Is-EC2-Classic", [ { "Ref": "DBSecurityGroup" } ], { "Ref" : "AWS::NoValue"}]}

Currently we fail on this, because you've specified both properties where you're only allowed to specify one.

The simple implementation of this would be to downgrade a conflict to a warning if it's body is a condition containing AWS::NoValue. The warning would be more that there could be something wrong, but we can't reliably tell.

A more advanced implementation would be to evaluate the conditionals and see if they ever would result in the two properties being present at once. This will be pretty complicated with nested conditions.

Fn::FindInMap causes panic

I am able to cause a panic when validating this template:

{
  "Resources": {
    "x": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "Properties": {
        "VPCZoneIdentifier": {
          "Fn::FindInMap": ["mapName", { "Ref": "something" }, "secondKey"]
        }
      } 
    } 
  } 
}

Panic:

panic: interface conversion: interface is map[string]interface {}, not []interface {}

goroutine 1 [running]:
github.com/jagregory/cfval/schema.Schema.Validate(0x1, 0x0, 0x0, 0x0, 0x0, 0x7fe5af1d0378, 0xc8200a6780, 0x7fe5af1d02f8, 0xc82000d4a0, 0x0, ...)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/schema.go:63 +0x143
github.com/jagregory/cfval/schema.Properties.Validate(0xc82000d3e0, 0x7fe5af1d0a98, 0xc820086bd0, 0x0, 0x0, 0x0, 0x90)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/properties.go:41 +0xa95
github.com/jagregory/cfval/schema.Resource.Validate(0x6b2320, 0x22, 0x0, 0xc82000d3e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/resource.go:18 +0xfa
github.com/jagregory/cfval/schema.resourceValidate(0xc820175b00, 0x22, 0xc820175b30, 0x0, 0x7fe5af1d09f8, 0xc820086b40, 0xc820086b40, 0x0, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/template.go:49 +0x284
github.com/jagregory/cfval/schema.TemplateValidate(0xc82018f5c0, 0x7fe5af1d09c8, 0xc820175740, 0x7fe5af1d09c8, 0x0, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/template.go:15 +0x3c0
main.ValidateCommand.Run(0xc82000a070, 0x0, 0x0, 0xc820173d40)
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:174 +0x788
main.(*ValidateCommand).Run(0x7d3c58, 0xc82000a070, 0x0, 0x0, 0x6e2ff0)
        <autogenerated>:6 +0xab
github.com/mitchellh/cli.(*CLI).Run(0xc8200b83c0, 0xc820175830, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/mitchellh/cli/cli.go:153 +0x538
main.main()
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:201 +0x181

goroutine 5 [runnable]:
os/signal.loop()
        /usr/lib/go/src/os/signal/signal_unix.go:20
created by os/signal.init.1
        /usr/lib/go/src/os/signal/signal_unix.go:28 +0x37

Fn::FindInMap validation against Mappings collection

Where possible, we should validate that the map names/keys are valid in a Fn::FindInMap call. This will only work up to the point of where we encounter a non-string value.

{ "Fn::FindInMap": ["mapName", "topKey", "secondKey"] } // should be validatable
{ "Fn::FindInMap": ["mapName", { "Ref": "something" }, "secondKey"] } // won't be

AccessKey.Status should not be mandatory

The docs say it is, but the sample templates don't specify it so perhaps it isn't; either that, or it is mandatory but didn't used to be. Maybe creating a test stack would flush this one out?

Deprecated properties

Probably a precursor to #14

Certain properties, such as AWS::ElasticBeanstalk::Application ApplicationVersions are deprecated. Old templates still include them and they still work, but we should warn or error on their use (and not just error with "unexpected property").

GetAtt GroupId of SecurityGroup causes panic

When I validate this template:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "sg": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
      }
    },
    "elb": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
        "SecurityGroups": [ { "Fn::GetAtt": [ "sg", "GroupId" ] } ]
      }
    }
  }
}

I get this error:

panic: interface conversion: interface is parse.IntrinsicFunction, not string

goroutine 1 [running]:
github.com/jagregory/cfval/schema.resourceID.Validate(0x696a30, 0xf, 0xc82003e580, 0x39, 0xc8200683c0, 0x64dc40, 0xc82018f8c0, 0x7ff5981caa68, 0xc820089320, 0x0, ...)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/value_id.go:41 +0x19a
github.com/jagregory/cfval/schema.(*resourceID).Validate(0xc8200db200, 0x64dc40, 0xc82018f8c0, 0x7ff5981caa68, 0xc820089320, 0x0, 0x0, 0x0, 0x0, 0x0)
        <autogenerated>:90 +0xfa
github.com/jagregory/cfval/schema.validateValue(0x64dc40, 0xc82018f8c0, 0x7ff5981caa68, 0xc820089320, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/schema.go:116 +0x11e
github.com/jagregory/cfval/schema.Schema.Validate(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7ff5981c6350, 0xc8200db200, 0x0, 0x64dc40, ...)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/schema.go:54 +0x197
github.com/jagregory/cfval/schema.validateArray(0x7ff5981c6350, 0xc8200db200, 0x5e6ce0, 0xc82018f8e0, 0x7ff5981caa68, 0xc820089200, 0x0, 0x0, 0x0, 0x0, ...)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/schema.go:67 +0x45d
github.com/jagregory/cfval/schema.Schema.Validate(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7ff5981c6288, 0xc8200cb770, 0x0, 0x5e6ce0, ...)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/schema.go:52 +0x136
github.com/jagregory/cfval/schema.Properties.Validate(0xc8200db260, 0x7ff5981ca9f8, 0xc820089050, 0x0, 0x0, 0x0, 0x90)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/properties.go:41 +0xa95
github.com/jagregory/cfval/schema.Resource.Validate(0x6cc180, 0x27, 0xc8200db170, 0xc8200db260, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/resource.go:18 +0x119
github.com/jagregory/cfval/schema.resourceValidate(0xc8201e80f0, 0x27, 0xc8201e83f0, 0xc8201e9170, 0x7ff5981ca950, 0xc820088fc0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/template.go:49 +0x293
github.com/jagregory/cfval/schema.TemplateValidate(0xc82018f5a0, 0x7ff5981ca920, 0xc820175770, 0xc8201e91a0, 0xc8201e91a0, 0x0, 0x0, 0x0)
        /home/vagrant/golang/src/github.com/jagregory/cfval/schema/template.go:15 +0x3db
main.ValidateCommand.Run(0xc82000a070, 0x0, 0x0, 0xc820173d40)
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:180 +0x81b
main.(*ValidateCommand).Run(0x7f5d60, 0xc82000a070, 0x0, 0x0, 0x6ff3f8)
        <autogenerated>:6 +0xab
github.com/mitchellh/cli.(*CLI).Run(0xc8200bc3c0, 0xc820175860, 0x0, 0x0)
        /home/vagrant/golang/src/github.com/mitchellh/cli/cli.go:153 +0x538
main.main()
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:207 +0x181

goroutine 5 [runnable]:
os/signal.loop()
        /usr/lib/go/src/os/signal/signal_unix.go:20
created by os/signal.init.1
        /usr/lib/go/src/os/signal/signal_unix.go:28 +0x37

Using this version a1b2fef9596d0677dff72479f5ce6de9047ee5ad

MasterDb.Engine not case sensitive

The docs indicate that MySQL is the correct value for Engine. Of course, mysql works too. Who knows if it's just case-insensitive, or if this is just a special case. I guess since it works, it would be nice if it didn't error.

template:

{ 
  "Resources": { 
    "MasterDb": { 
      "Type": "AWS::RDS::DBInstance", 
      "Properties": { 
        "Engine": "mysql", 
        "AllocatedStorage": "10", 
        "DBInstanceClass": "db.m1.medium", 
        "DBSubnetGroupName": "foo" 
      } 
    } 
  } 
}

error:

ERROR   Resources.MasterDb.Engine       Invalid enum option mysql, expected one of [MySQL, mariadb, oracle-se1, oracle-se, oracle-ee, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web, postgres, aurora]

version: e7af583dbdc0f7641678070a176c82a7a9ffe996

AWS Account ID type

There's a couple of places where you can stipulate an AWS account something belongs to. We treat these as ValueString right now; a more restrictive AwsAccountID type might be useful.

Rich ARN validation and constraints

There's a bunch of places where we're using ValueString to represent an ARN.

  • Create a general purpose ARN type so you can't just assign any arbitrary string to an ARN
  • Constrain ARNs by resource types, so you can't assign a SecurityGroup ARN to a property expecting a LoadBalancer ARN

Tip: grep for "ARN" and "Name" there's a heap of comments and TODOs. Mostly it's in the ReturnValue of resources marked as // Name.

Be more stringent with which functions can be called in certain places

Currently Intrinsic Functions can be substituted in place of a value, but this is not strictly always correct. Certain functions are only valid in particular places, especially when nesting them. e.g. You can't use an Fn::GetAtt within an Fn::FindInMap.

Function support/restrictions are currently implemented in:

  • Fn::And
  • Fn::Base64
  • Fn::Equals
  • Fn::FindInMap
  • Fn::GetAtt
  • Fn::GetAZs
  • Fn::If
  • Fn::Join
  • Fn::Not
  • Fn::Or
  • Fn::Select
  • Ref

Undocumented use of AWS::RDS::DBSecurityGroup.DBSecurityGroupIngress causes panic

Whilst the documentation[1] suggests an array is required in DBSecurityGroupIngress, it also supports a map. A template such as this will create successfully in cloudformation:

{   
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "test",
  "Resources": {
    "dbsg": {
      "Type": "AWS::RDS::DBSecurityGroup",
      "Properties": {
        "DBSecurityGroupIngress": {     
          "EC2SecurityGroupId": {         
            "Ref": "sg"
          }
        },
        "EC2VpcId": "vpc-xxxxxx",     
        "GroupDescription": "xxx"
      }
    },
    "sg": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "VpcId": "vpc-xxxxxx",        
        "GroupDescription": "xxx"
      }
    }
  }
} 

And it will result in a panic:

panic: interface conversion: interface is map[string]interface {}, not []interface {}

goroutine 1 [running]:
github.com/jagregory/cfval/schema.Schema.Validate(0x1, 0x0, 0x0, 0x0, 0x0, 0x7f75a3707210, 0xc820010310, 0x7f75a37073a8, 0xc82018e940, 0x0, ...)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/schema.go:63 +0x143
github.com/jagregory/cfval/schema.Properties.Validate(0xc8201748d0, 0x7f75a3707a20, 0xc8200870e0, 0x0, 0x0, 0x0, 0x90)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/properties.go:41 +0xa95
github.com/jagregory/cfval/schema.Resource.Validate(0x6a9f20, 0x19, 0x0, 0xc8201748d0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/resource.go:18 +0xfa
github.com/jagregory/cfval/schema.resourceValidate(0xc82018f720, 0x19, 0xc820175b30, 0x0, 0x7f75a3707980, 0xc820087050, 0xc820087050, 0x0, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/template.go:49 +0x284
github.com/jagregory/cfval/schema.TemplateValidate(0xc82018f5c0, 0x7f75a3707950, 0xc820175740, 0x7f75a3707950, 0x0, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/template.go:15 +0x3c0
main.ValidateCommand.Run(0xc82000a070, 0x0, 0x0, 0xc820173d40)
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:174 +0x788
main.(*ValidateCommand).Run(0x7d3c58, 0xc82000a070, 0x0, 0x0, 0x6e2ff0)
        <autogenerated>:6 +0xab
github.com/mitchellh/cli.(*CLI).Run(0xc8200b83c0, 0xc820175830, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/mitchellh/cli/cli.go:153 +0x538
main.main()
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:201 +0x181

goroutine 5 [runnable]:
os/signal.loop()
        /usr/lib/go/src/os/signal/signal_unix.go:20
created by os/signal.init.1
        /usr/lib/go/src/os/signal/signal_unix.go:28 +0x37

Using cfval built from dba9c5fc82c1dafbe858ad427872e113be8d013e

VPC mode

There are a bunch of non-enforceable "required if being used in a VPC" properties. We can sometimes tell if a resource is in a VPC based on other properties, and sometimes by finding owning resources (e.g. an EC2 Instance in a Subnet which is in a VPC); however, quite often these resources won't be available to us to interrogate because they may be defined elsewhere outside of the template. For this we either need active interrogation (e.g. query AWS) or we can flick a flag to let the user say "yes all these resources are going to be in a VPC, trust me".

For now, the latter -vpc flag is probably a sensible idea.

Fn::GetAtt attribute validation

Check that the attribute in a Fn::GetAtt call is actually a valid attribute for the resource specified (if we can drill in).

{ "Fn::GetAtt": ["MyEc2Instance", "PublicIp"] }   // valid "PublicIp" is an exposed attribute of an AWS::EC2::Instance
{ "Fn::GetAtt": ["MyEc2Instance", "InstanceId"] } // fail "InstanceId" is not exposed

This will require tracking the exposed attributes of each resource, see: Return Values.

Functions can return arrays and be used in place of arrays

Certain functions can return arrays and therefore be used in place of an entire array sub-resource.

"AvailabilityZones": ["ap-southeast-2a","ap-southeast-2b","ap-southeast-2c"]

Can be replaced with:

"AvailabilityZones": { "Ref": "myAvailabilityZones" }

Fn::FindInMap, Fn::GetAZs, Fn::GetAtt, and Ref (if the attribute/parameter/pseudo-parameter is an array) all can potentially return arrays.

AWS::CloudFormation::CustomResource requires more flexiblility

AWS::CloudFormation::CustomResource introduces some concepts we don't support right now.

  • Type of a resource can be arbitrary (e.g. Custom::*)
  • Properties of a resource are a combination of known properties and arbitrary names from the provider of the custom resource
  • Attributes are also not known, and from the provider

Possible solutions:

  • AllowUnexpectedProperties flag on the Resource, to indicate alternate behaviour when a property isn't found
  • An * property, which behaves the same as above; this might be harder due to the Schema having an explicit type.

Deep nested Intrinsic Function gets confused with what it's being assigned to

"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }

In this case, the Ref is being passed a PropertyContext(ImageId) and creating a Warning based on a AWS::Region not being assignable to an InstanceId, when in actual fact the Ref is just being used as a String in a FindInMap.

This can probably be solved by creating a pseudo-property context when a Intrinsic Function is nested.

Fixed for:

  • Fn::And
  • Fn::Base64
  • Fn::Equals
  • Fn::FindInMap
  • Fn::GetAtt
  • Fn::GetAZs
  • Fn::If
  • Fn::Join
  • Fn::Not
  • Fn::Or
  • Fn::Select

SecurityGroup ReturnValue ambiguous

The Ref/ReturnValue of a EC2::SecurityGroup is the ID if the SecurityGroup is in a VPC, or the Name if it isn't. This is annoying, because you always get a coercion warning.

Resources.ELB.SecurityGroups.0.Ref ...... Ref value of 'ElbSecurityGroup' is String but is being dangerously coerced to a SecurityGroupID property

Replacement properties

This is pretty low priority, as so far there's only one property I've seen documented as replaced

"This property replaces the MinAdjustmentStep property".

MinAdjustmentStep isn't a known property and will report it as unexpected; however, if we really wanted we could be a bit more sophisticated and say this property is no longer supported and has been superseded by MinAdjustmentMagnitude.

AWS Resource support

Below is the status of all the current (as of Feb 2016) AWS resources.

  • Fully supported (including property validation, conflicting and complimentary properties, etc...)
  • Not supported
  • ๐Ÿ•’ Partial support (usually just basic property definitions with required flags, no complex validations or conflict support)

Resources

  • AWS::AutoScaling::AutoScalingGroup
  • AWS::AutoScaling::LaunchConfiguration
  • AWS::AutoScaling::LifecycleHook
  • AWS::AutoScaling::ScalingPolicy
  • AWS::AutoScaling::ScheduledAction
  • AWS::CloudFront::Distribution
  • AWS::CloudTrail::Trail
  • AWS::CloudWatch::Alarm
  • AWS::CloudFormation - #58
  • AWS::CodeDeploy - #59
  • AWS::CodePipeline - #60
  • AWS::Config - #61
  • AWS::DataPipeline::Pipeline
  • AWS::DirectoryService - #62
  • AWS::DynamoDB::Table
  • AWS::EC2::CustomerGateway
  • AWS::EC2::DHCPOptions
  • AWS::EC2::EIP
  • AWS::EC2::EIPAssociation
  • AWS::EC2::Instance
  • AWS::EC2::InternetGateway
  • AWS::EC2::NatGateway
  • AWS::EC2::NetworkAcl
  • AWS::EC2::NetworkAclEntry
  • AWS::EC2::NetworkInterface
  • AWS::EC2::NetworkInterfaceAttachment
  • AWS::EC2::PlacementGroup
  • AWS::EC2::Route
  • AWS::EC2::RouteTable
  • AWS::EC2::SecurityGroup
  • AWS::EC2::SecurityGroupEgress
  • AWS::EC2::SecurityGroupIngress
  • AWS::EC2::SpotFleet
  • AWS::EC2::Subnet
  • AWS::EC2::SubnetNetworkAclAssociation
  • AWS::EC2::SubnetRouteTableAssociation
  • AWS::EC2::Volume
  • AWS::EC2::VolumeAttachment
  • AWS::EC2::VPC
  • AWS::EC2::VPCDHCPOptionsAssociation
  • AWS::EC2::VPCEndpoint
  • AWS::EC2::VPCGatewayAttachment
  • AWS::EC2::VPCPeeringConnection
  • AWS::EC2::VPNConnection
  • AWS::EC2::VPNConnectionRoute
  • AWS::EC2::VPNGateway
  • AWS::EC2::VPNGatewayRoutePropagation
  • AWS::ECS::Cluster
  • AWS::ECS::Service
  • AWS::ECS::TaskDefinition
  • AWS::EFS::FileSystem
  • AWS::EFS::MountTarget
  • AWS::ElastiCache::CacheCluster
  • AWS::ElastiCache::ParameterGroup
  • AWS::ElastiCache::ReplicationGroup
  • AWS::ElastiCache::SecurityGroup
  • AWS::ElastiCache::SecurityGroupIngress
  • AWS::ElastiCache::SubnetGroup
  • AWS::ElasticBeanstalk::Application
  • AWS::ElasticBeanstalk::ApplicationVersion
  • AWS::ElasticBeanstalk::ConfigurationTemplate
  • AWS::ElasticBeanstalk::Environment
  • AWS::ElasticLoadBalancing::LoadBalancer
  • AWS::IAM::AccessKey
  • AWS::IAM::Group
  • AWS::IAM::InstanceProfile
  • AWS::IAM::ManagedPolicy
  • AWS::IAM::Policy
  • AWS::IAM::Role
  • AWS::IAM::User
  • AWS::IAM::UserToGroupAddition
  • AWS::Kinesis::Stream
  • AWS::KMS::Key
  • AWS::Lambda::EventSourceMapping
  • AWS::Lambda::Function
  • AWS::Lambda::Permission
  • AWS::Logs::Destination
  • AWS::Logs::LogGroup
  • AWS::Logs::LogStream
  • AWS::Logs::MetricFilter
  • AWS::Logs::SubscriptionFilter
  • AWS::OpsWorks - #63
  • AWS::RDS::DBCluster
  • AWS::RDS::DBClusterParameterGroup
  • AWS::RDS::DBInstance
  • AWS::RDS::DBParameterGroup
  • AWS::RDS::DBSecurityGroup
  • AWS::RDS::DBSecurityGroupIngress
  • AWS::RDS::DBSubnetGroup
  • AWS::RDS::EventSubscription
  • AWS::RDS::OptionGroup
  • AWS::Redshift - #64
  • AWS::Route53::HealthCheck
  • AWS::Route53::HostedZone
  • AWS::Route53::RecordSet
  • AWS::Route53::RecordSetGroup
  • AWS::S3::Bucket
  • AWS::S3::BucketPolicy
  • AWS::SDB::Domain
  • AWS::SNS::Topic
  • AWS::SNS::TopicPolicy
  • AWS::SQS::Queue
  • AWS::SQS::QueuePolicy
  • AWS::SSM::Document
  • AWS::WAF - #65
  • AWS::WorkSpaces::Workspace

Validations on coerced values

Validations don't run on coerced values - deliberately. An integer validation won't run on a string coerced into an integer property (so a IntegerRange(0, 5) won't be applied to the value "10" and thus will pass).

We could or should try converting the value, rather than just warning about a coercion.

Intrinsic Functions results should be typed

  • Fn::And - Boolean
  • Fn::Base64 - String
  • Fn::Equals - Boolean
  • Fn::FindInMap - String?
  • Fn::GetAtt - Attribute Type
  • Fn::GetAZs - List<AZ>
  • Fn::If - Type of arguments if same, else common supertype of arguments
  • Fn::Join - String
  • Fn::Not - Boolean
  • Fn::Or - Boolean
  • Fn::Select - Array item type
  • Ref - ReturnValue

AWS::EC2::Volume.VolumeType causes panic

When I enter this template:

{                              
  "Resources": {               
    "Volume": {                
      "Type": "AWS::EC2::Volume",     
      "Properties": {          
        "VolumeType": "standard"        
      }
    }
  }
}

cfval shows this error:

panic: interface conversion: interface is string, not []interface {}

goroutine 1 [running]:
github.com/jagregory/cfval/schema.Schema.Validate(0x1, 0x0, 0x0, 0x0, 0x0, 0x7f84f932a210, 0xc820010310, 0x7f84f932a2b8, 0xc8200da0c0, 0x0, ...)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/schema.go:63 +0x143
github.com/jagregory/cfval/schema.Properties.Validate(0xc8200da060, 0x7f84f932a980, 0xc820086bd0, 0x0, 0x0, 0x0, 0x90)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/properties.go:41 +0xa95
github.com/jagregory/cfval/schema.Resource.Validate(0x69eb80, 0x10, 0x0, 0xc8200da060, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/resource.go:18 +0xfa
github.com/jagregory/cfval/schema.resourceValidate(0xc82018f590, 0x10, 0xc820175b00, 0x0, 0x7f84f932a8e0, 0xc820086b40, 0xc820086b40, 0x0, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/template.go:49 +0x284
github.com/jagregory/cfval/schema.TemplateValidate(0xc82018d5e0, 0x7f84f932a8b0, 0xc820175740, 0x7f84f932a8b0, 0x0, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/jagregory/cfval/schema/template.go:15 +0x3c0
main.ValidateCommand.Run(0xc82000a070, 0x0, 0x0, 0xc820173d40)
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:174 +0x788
main.(*ValidateCommand).Run(0x7d3c58, 0xc82000a070, 0x0, 0x0, 0x6e2ff0)
        <autogenerated>:6 +0xab
github.com/mitchellh/cli.(*CLI).Run(0xc8200b83c0, 0xc820175830, 0x0, 0x0)
        /home/vagrant/cfval/src/github.com/mitchellh/cli/cli.go:153 +0x538
main.main()
        /home/vagrant/golang/src/github.com/jagregory/cfval/main.go:201 +0x181

goroutine 5 [runnable]:
os/signal.loop()
        /usr/lib/go/src/os/signal/signal_unix.go:20
created by os/signal.init.1
        /usr/lib/go/src/os/signal/signal_unix.go:28 +0x37

Using version dba9c5fc82c1dafbe858ad427872e113be8d013e of cfval.

Parameter value validation

This is a bit beyond the current functionality, but it could be useful to be able to pass values for Parameters from the CLI to validate them too.

e.g. cfval -param='VpcID="abc"' template.json

Not sure about the syntax.

We can then throw errors if a parameter looks incorrect ("abc" is not a valid VPC ID).

Support for all Intrinsic Functions

Currently implemented:

  • Fn::And
  • Fn::Base64
  • Fn::Equals
  • Fn::FindInMap (except: #4)
  • Fn::GetAtt
  • Fn::GetAZs
  • Fn::If
  • Fn::Join
  • Fn::Not
  • Fn::Or
  • Fn::Select
  • Ref

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.