aws-cloudformation / cfn-lint

CloudFormation Linter
MIT No Attribution
2.4k stars 576 forks source link

Altering validation for property of AWS resource type #3460

Closed randybasrs closed 1 day ago

randybasrs commented 4 days ago

version 1.5.0

We've been working through the lint errors since the 1.0 update and and are running into an issue trying to alter the AWS::EC2::Instance resource type to change the validation of ImageId to a regex pattern. I have been able to get the validation to properly change by providing a full schema file (using the one AWS provides as a base) but this would require us to maintain this merged version of the schema file. I have been unable to find a combination of custom rules or override specifications that allowed me to change the validation.

Here's the only part of the resource schema we changed to get the change we want:

From:

"ImageId": { "format": "AWS::EC2::Image.Id", "type": "string" }

To:

"ImageId": { "pattern": "{resolveEC2ImageID:.+}", "type": "string" }

If I pare down the schema file, it appears to break all sorts of things. I have tried this with/without merge-configs but am not sure it applies in this scenario.

Any help would be appreciated.

kddejong commented 3 days ago

PR on doc changes incoming. I had to change how the patching works because the massive change to the structure of the schema files.

We still support the ability to add/remove resource types but to patch a schema you need to do this. Patches/ResourceType and then a list of patches in json patch format.

{
    "Patches": {
        "AWS::EC2::Instance": [
            {
                "op": "remove",
                "path": "/properties/ImageId/format",
                "value": "true"
            }
        ]
    }
}

I'm not sure I get the pattern you are trying to put there resolveEC2ImageID:. If this is suppose to be a dynamic reference we shouldn't be failing the format and if it is a dynamic reference we would skip any of those validation keywords (pattern, enum, length, etc.) even if you patch them in. If you are requiring a certain set of image IDs to be present you could do:

{
    "Patches": {
        "AWS::EC2::Instance": [
            {
                "op": "add",
                "path": "/properties/ImageId/enum",
                "value": [
                    "ami-12345678"
                ]
            }
        ]
    }
}
kddejong commented 3 days ago

Made an initial swipe at updating the docs to talk about how to do the patching. We can make improvements from there.

randybasrs commented 2 days ago

Thank you, That helped out tremendously. We use a cloudformation macro to resolve our AMI IDs at the point of deploying the template due to the complexity of managing specific images in our environment and our desire to keep templates from being updated every time an AMI ID changes. The macro looks for a specific regex pattern in order to replace: "{resolveEC2ImageID:windowsServer}" for example. Thankfully the feedback you provided was enough for me to realize my folly and this override spec solved my problem:

{
     "Patches": {
         "AWS::EC2::Instance": [
             {
                 "op": "remove",
                 "path": "/properties/ImageId/format",
                 "value": "true"
             },
             {
                 "op": "add",
                 "path": "/properties/ImageId/pattern",
                 "value": "{resolveEC2ImageID:.+}"
             }
         ]
     }
 }

I will probably update that property to look for either a valid EC2 image ID OR this regex string but for now I'm quite happy with this.

Thanks again!