cfn-lint icon indicating copy to clipboard operation
cfn-lint copied to clipboard

Feature request: Custom rules to require a property be set

Open rjmackay opened this issue 3 years ago • 5 comments

cfn-lint version: 0.56.0

Description of issue. Custom rules can restrict the value of a property but if it's not set they are ignored.

I wanted to set a rule to ensure all SQS queues have are encrypted, ie:

AWS::SQS::Queue KmsMasterKeyId != "" WARN "Queues should always be encrypted"

However this doesn't work, because if you don't pass the property at all, then the custom rule is ignored. I can image a bunch of similar use cases just requiring encryption across all services.

rjmackay avatar Nov 25 '21 18:11 rjmackay

yea I agree.

Debating an option on the rule itself or a different rule all together that can be IS_SET or IS_NOT_SET.

kddejong avatar Jan 28 '22 22:01 kddejong

I think this issue also deserve attention.

IS_SET or IS_NOT_SET seem to make more sense in all compatibility, implementation and usability aspect, for

  • compatibility: in all previous version, values that are not set are not checked against custom rule
  • implementation: This piece of code for all operations probably not run at all if property does not exist, there is no local fix here in https://github.com/aws-cloudformation/cfn-lint/blob/main/src/cfnlint/rules/custom/Operators.py
  • usability: if needed one can always write this to ensure it is both set and equals true
AWS::SQS::Queue KmsMasterKeyId IS_SET "" WARN "Queues should always be encrypted"
AWS::SQS::Queue KmsMasterKeyId EQUALS "true" WARN "Queues should always be encrypted"

Probably need to look at where these rules are called tho, not at the rule itself.

If we can have a consensus, I can try when free.

kftsehk avatar Mar 09 '23 18:03 kftsehk

was looking for solution and found this could be done overriding the spec

https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/customize_specifications.md#customize-specifications

Had an example making Tags mandatory.

Edit:

Attach another example I can constraining lambda launch condition that

  • further restrict Runtime into fewer values that we only operate on, discarding java, dotnet, legacy node/python.
  • force Timeout to be set and >= 10, where the aws default is 3 if unset, and allowable range being [1, 900]

.cfnlintrc.yml

override_spec: ./spec-override.json

spec-override.json

{
  "ResourceTypes": {
    "AWS::Lambda::Function": {
      "Properties": {
        "Timeout": {
          "Required": true
        }
      }
    }
  },
  "ValueTypes": {
    "AWS::Lambda::Function.Timeout": {
      "NumberMax": 900,
      "NumberMin": 10
    },
    "LambdaRuntime": {
      "AllowedValues": [
        "go1.x",
        "nodejs16.x",
        "nodejs18.x",
        "python3.7",
        "python3.8",
        "python3.9"
      ]
    }
  }
}

I find this probably is a feature much more powerful than custom_rule.txt itself. But one have to go through this 7.5MB spec file to find the specific sections where changes has to be made for the desired effect..

https://github.com/aws-cloudformation/cfn-lint/blob/main/src/cfnlint/data/CloudSpecs/us-east-1.json

kftsehk avatar Mar 10 '23 03:03 kftsehk

On the other hand, I just met a case where creating an overwrite-spec is too complicated. Checking Lambda::Function.Properties.Environment.Variables.NODE_ENV is set.

It is complicated because Variables is a json primitive type that can be hard to override correctly.

kftsehk avatar Mar 23 '23 10:03 kftsehk

On the other hand, I just met a case where creating an overwrite-spec is too complicated. Checking Lambda::Function.Properties.Environment.Variables.NODE_ENV is set.

It is complicated because Variables is a json primitive type that can be hard to override correctly.

How did you end up doing it? Were you able to?

myahl-uncomn avatar Mar 23 '23 13:03 myahl-uncomn