From dfd5c7335569f5063594af337aa87eb7956bcfce Mon Sep 17 00:00:00 2001 From: Kevin DeJong Date: Wed, 1 May 2024 08:56:06 -0700 Subject: [PATCH] Clean docs and some rule links (#3175) --- .github/ISSUE_TEMPLATE/1.bug_report.yaml | 2 +- README.md | 134 ++++++++-------- docs/cfn-resource-specification.md | 27 ---- docs/cfn-schema-specification.md | 48 +++--- docs/internal.md | 147 +++--------------- .../rules/resources/properties/NumberRange.py | 2 +- .../resources/properties/StringLength.py | 2 +- 7 files changed, 123 insertions(+), 239 deletions(-) delete mode 100644 docs/cfn-resource-specification.md diff --git a/.github/ISSUE_TEMPLATE/1.bug_report.yaml b/.github/ISSUE_TEMPLATE/1.bug_report.yaml index d31b43fc39..bd90c29846 100644 --- a/.github/ISSUE_TEMPLATE/1.bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/1.bug_report.yaml @@ -9,7 +9,7 @@ body: For reference, the current version of cfn-lint is . - Cfn-lint uses the [CloudFormation Resource Specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) as the base to do validation. These files are included as part of the application version. Please update to the latest version of `cfn-lint` or update the spec files manually (`cfn-lint -u`) + Cfn-lint uses the [CloudFormation resource provider schemas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-type-schemas.html) as the base to do validation. These files are included as part of the application version. Please update to the latest version of `cfn-lint` or update the spec files manually (`cfn-lint -u`) - type: input attributes: label: CloudFormation Lint Version diff --git a/README.md b/README.md index 42c07ff771..ff298f4dab 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,12 @@ [![codecov](https://codecov.io/gh/aws-cloudformation/cfn-lint/branch/main/graph/badge.svg)](https://codecov.io/gh/aws-cloudformation/cfn-python-lint) [![Discord Shield](https://img.shields.io/discord/981586120448020580?logo=discord)](https://discord.gg/KENDm6DHCv) -Validate AWS CloudFormation yaml/json templates against the [AWS CloudFormation Resource Specification](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) and additional -checks. Includes checking valid values for resource properties and best practices. +Validate AWS CloudFormation yaml/json templates against the [AWS CloudFormation resource provider schemas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-type-schemas.html) and additional checks. Includes checking valid values for resource properties and best practices. ### Warning This is an attempt to provide validation for AWS CloudFormation templates properties and -their values. For values things can get pretty complicated (mappings, joins, splits, +their values. For values things can get pretty complicated (mappings, joins, splits, conditions, and nesting those functions inside each other) so it's a best effort to validate those values but the promise is to not fail if we can't understand or translate all the things that could be going on. @@ -70,15 +69,15 @@ docker run --rm -v `pwd`:/data cfn-python-lint:latest /data/template.yaml There are IDE plugins available to get direct linter feedback from you favorite editor: -* [Atom](https://atom.io/packages/atom-cfn-lint) -* [Emacs](https://www.emacswiki.org/emacs/CfnLint) -* NeoVim 0.2.0+/Vim 8 - * [ALE](https://github.com/w0rp/ale#supported-languages) - * [Coc](https://github.com/joenye/coc-cfn-lint) - * [Syntastic](https://github.com/speshak/vim-cfn) -* [Sublime](https://packagecontrol.io/packages/SublimeLinter-contrib-cloudformation) -* [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint) -* [IntelliJ IDEA](https://plugins.jetbrains.com/plugin/10973-cfn-lint) +- [Atom](https://atom.io/packages/atom-cfn-lint) +- [Emacs](https://www.emacswiki.org/emacs/CfnLint) +- NeoVim 0.2.0+/Vim 8 + - [ALE](https://github.com/w0rp/ale#supported-languages) + - [Coc](https://github.com/joenye/coc-cfn-lint) + - [Syntastic](https://github.com/speshak/vim-cfn) +- [Sublime](https://packagecontrol.io/packages/SublimeLinter-contrib-cloudformation) +- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=kddejong.vscode-cfn-lint) +- [IntelliJ IDEA](https://plugins.jetbrains.com/plugin/10973-cfn-lint) ### [GitHub Action](https://github.com/marketplace/actions/cfn-lint-action) @@ -104,11 +103,12 @@ Lint all `yaml` files in `path` and all subdirectories (recursive): - `cfn-lint path/**/*.yaml` -*Note*: If using sh/bash/zsh, you must enable globbing. +_Note_: If using sh/bash/zsh, you must enable globbing. (`shopt -s globstar` for sh/bash, `setopt extended_glob` for zsh). ##### Exit Codes -`cfn-lint` will return a non zero exit if there are any issues with your template. The value is dependent on the severity of the issues found. For each level of discovered error `cfn-lint` will use bitwise OR to determine the final exit code. This will result in these possibilities. + +`cfn-lint` will return a non zero exit if there are any issues with your template. The value is dependent on the severity of the issues found. For each level of discovered error `cfn-lint` will use bitwise OR to determine the final exit code. This will result in these possibilities. - 0 is no issue was found - 2 is an error @@ -120,13 +120,15 @@ Lint all `yaml` files in `path` and all subdirectories (recursive): - 14 is an error and a warning and an informational ###### Configuring Exit Codes + `cfn-lint` allows you to configure exit codes. You can provide the parameter `--non-zero-exit-code` with a value of `informational`, `warning`, `error`, or `none`. `cfn-lint` will determine the exit code based on the match severity being the value of the parameter `--non-zero-exit-code` and higher. The exit codes will remain the same as above. The order of severity is as follows: -1. `informational` *default* + +1. `informational` _default_ 1. `warning` 1. `error` -1. `none` *Exit code will always be 0 unless there is a syntax error* +1. `none` _Exit code will always be 0 unless there is a syntax error_ ##### Specifying the template as an input stream @@ -170,38 +172,39 @@ custom_rules: custom_rules.txt Optional parameters: -| Command Line | Metadata | Options | Description | -| ------------- | ------------- | ------------- | ------------- | -| -h, --help | | | Get description of cfn-lint | -| -z, --custom-rules | | filename | Text file containing user-defined custom rules. See [here](#Custom-Rules) for more information | -| -t, --template | | filename | Alternative way to specify Template file path to the file that needs to be tested by cfn-lint | -| -f, --format | format | quiet, parseable, json, junit, pretty, sarif | Output format | -| -l, --list-rules | | | List all the rules | -| -r, --regions | regions | [REGIONS [REGIONS ...]], ALL_REGIONS | Test the template against many regions. [Supported regions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) | -| -b, --ignore-bad-template | ignore_bad_template | | Ignores bad template errors | -| --ignore-templates | | IGNORE_TEMPLATES [IGNORE_TEMPLATES ...] | Ignore templates from being scanned -| -a, --append-rules | append_rules | [RULESPATH [RULESPATH ...]] | Specify one or more rules paths using one or more --append-rules arguments. Each path can be either a directory containing python files, or an import path to a module. | -| -i, --ignore-checks | ignore_checks | [IGNORE_CHECKS [IGNORE_CHECKS ...]] | Only check rules whose ID do not match or prefix these values. Examples:
- A value of `W` will disable all warnings
- `W2` disables all Warnings for Parameter rules.
- `W2001` will disable rule `W2001` | -| -e, --include-experimental | include_experimental | | Whether rules that still in an experimental state should be included in the checks | -| -c, --include-checks | | INCLUDE_CHECKS [INCLUDE_CHECKS ...] | Include rules whose id match these values -| -m, --mandatory-checks | | | Rules to check regardless of ignore configuration | -| --non-zero-exit-code | | informational (default), warning, error, none] | Exit code will be non zero from the specified rule class and higher | -| -x, --configure-rule | | CONFIGURE_RULES [CONFIGURE_RULES ...] | Provide configuration for a rule. Format RuleId:key=value. Example: E3012:strict=true -| -D, --debug | | | Specify to enable debug logging. Debug logging outputs detailed information about rules processing, useful for debugging rules. | -| -I, --info | | | Specify to enable logging. Outputs additional information about the template processing. | -| -u, --update-specs | | | Update the [CloudFormation Resource Specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html). You may need sudo to run this. You will need internet access when running this command | -| -o, --override-spec | | filename | Spec-style file containing custom definitions. Can be used to override CloudFormation specifications. More info [here](#customize-specifications) | -| -g, --build-graph | | | Creates a file in the same directory as the template that models the template's resources in [DOT format](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) | -| -s, --registry-schemas | | | one or more directories of [CloudFormation Registry](https://aws.amazon.com/blogs/aws/cloudformation-update-cli-third-party-resource-support-registry/) [Resource Schemas](https://github.com/aws-cloudformation/aws-cloudformation-resource-schema/) -| -v, --version | | | Version of cfn-lint | +| Command Line | Metadata | Options | Description | +| -------------------------- | -------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| -h, --help | | | Get description of cfn-lint | +| -z, --custom-rules | | filename | Text file containing user-defined custom rules. See [here](#Custom-Rules) for more information | +| -t, --template | | filename | Alternative way to specify Template file path to the file that needs to be tested by cfn-lint | +| -f, --format | format | quiet, parseable, json, junit, pretty, sarif | Output format | +| -l, --list-rules | | | List all the rules | +| -r, --regions | regions | [REGIONS [REGIONS ...]], ALL_REGIONS | Test the template against many regions. [Supported regions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-type-schemas.html) | +| -b, --ignore-bad-template | ignore_bad_template | | Ignores bad template errors | +| --ignore-templates | | IGNORE_TEMPLATES [IGNORE_TEMPLATES ...] | Ignore templates from being scanned | +| -a, --append-rules | append_rules | [RULESPATH [RULESPATH ...]] | Specify one or more rules paths using one or more --append-rules arguments. Each path can be either a directory containing python files, or an import path to a module. | +| -i, --ignore-checks | ignore_checks | [IGNORE_CHECKS [IGNORE_CHECKS ...]] | Only check rules whose ID do not match or prefix these values. Examples:
- A value of `W` will disable all warnings
- `W2` disables all Warnings for Parameter rules.
- `W2001` will disable rule `W2001` | +| -e, --include-experimental | include_experimental | | Whether rules that still in an experimental state should be included in the checks | +| -c, --include-checks | | INCLUDE_CHECKS [INCLUDE_CHECKS ...] | Include rules whose id match these values | +| -m, --mandatory-checks | | | Rules to check regardless of ignore configuration | +| --non-zero-exit-code | | informational (default), warning, error, none] | Exit code will be non zero from the specified rule class and higher | +| -x, --configure-rule | | CONFIGURE_RULES [CONFIGURE_RULES ...] | Provide configuration for a rule. Format RuleId:key=value. Example: E3012:strict=true | +| -D, --debug | | | Specify to enable debug logging. Debug logging outputs detailed information about rules processing, useful for debugging rules. | +| -I, --info | | | Specify to enable logging. Outputs additional information about the template processing. | +| -u, --update-specs | | | Update the [CloudFormation resource provider schemas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-type-schemas.html). You may need sudo to run this. You will need internet access when running this command | +| -o, --override-spec | | filename | Spec-style file containing custom definitions. Can be used to override CloudFormation specifications. More info [here](#customize-specifications) | +| -g, --build-graph | | | Creates a file in the same directory as the template that models the template's resources in [DOT format]() | +| -s, --registry-schemas | | | one or more directories of [CloudFormation Registry](https://aws.amazon.com/blogs/aws/cloudformation-update-cli-third-party-resource-support-registry/) [Resource Schemas](https://github.com/aws-cloudformation/aws-cloudformation-resource-schema/) | +| -v, --version | | | Version of cfn-lint | ### Info Rules -To maintain backwards compatibility `info` rules are not included by default. To include these rules you will need to include `-c I` or `--include-checks I` +To maintain backwards compatibility `info` rules are not included by default. To include these rules you will need to include `-c I` or `--include-checks I` ### Metadata #### Template Based Metadata + Inside the root level Metadata key you can configure cfn-lint using the supported parameters. ```yaml @@ -216,7 +219,8 @@ Metadata: ``` #### Resource Based Metadata -Inside a resources Metadata key you can configure cfn-lint to ignore checks. This will filter out failures for the resource in which the Metadata belongs. Keep in mind that [`AWS::Serverless` resources may lose metadata during the Serverless transform](https://github.com/awslabs/serverless-application-model/issues/450#issuecomment-643420308) + +Inside a resources Metadata key you can configure cfn-lint to ignore checks. This will filter out failures for the resource in which the Metadata belongs. Keep in mind that [`AWS::Serverless` resources may lose metadata during the Serverless transform](https://github.com/awslabs/serverless-application-model/issues/450#issuecomment-643420308) ```yaml Resources: @@ -235,6 +239,7 @@ Resources: ### Precedence cfn-lint applies configurations from several sources. The rules at lower levels are overridden by those at higher levels. + 1. cfnlintrc configurations 2. Template Metadata configurations 3. CLI parameters @@ -272,29 +277,33 @@ More information describing how rules are set up and an overview of all the Rule ## Custom Rules The linter supports the creation of custom one-line rules which compare any resource with a property using pre-defined operators. These custom rules take the following format: + ``` [Error Level] [Custom Error Message] ``` ### Example + A separate custom rule text file must be created. The example below validates `example_template.yml` does not use any EC2 instances of size `m4.16xlarge` _custom_rule.txt_ + ``` AWS::EC2::Instance InstanceType NOT_EQUALS "m4.16xlarge" WARN "This is an expensive instance type, don't use it" ``` _example_template.yml_ -``` + +```yaml AWSTemplateFormatVersion: "2010-09-09" Resources: - myInstance: - Type: AWS::EC2::Instance - Properties: - InstanceType: m4.16xlarge - ImageId: ami-asdfef + myInstance: + Type: AWS::EC2::Instance + Properties: + InstanceType: m4.16xlarge + ImageId: ami-asdfef ``` The custom rule can be added to the [configuration file](#Config-File) or ran as a [command line argument](#Parameters) @@ -306,12 +315,11 @@ W9001 This is an expensive instance type, don't use it mqtemplate.yml:6:17 ``` - More information describing how custom rules are setup and an overview of all operators available is documented [here](docs/custom_rules.md). ## Customize specifications -The linter follows the [AWS CloudFormation Resource Specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) by default. However, for your use case specific requirements might exist. For example, within your organisation it might be mandatory to use [Tagging](https://aws.amazon.com/answers/account-management/aws-tagging-strategies/). +The linter follows the [AWS CloudFormation resource provider schemas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-type-schemas.html) by default. However, for your use case specific requirements might exist. For example, within your organisation it might be mandatory to use [Tagging](https://aws.amazon.com/answers/account-management/aws-tagging-strategies/). The linter provides the possibility to implement these customized specifications using the `--override-spec` argument. @@ -323,22 +331,24 @@ If you'd like cfn-lint to be run automatically when making changes to files in y ```yaml repos: -- repo: https://github.com/aws-cloudformation/cfn-lint - rev: v0.87.1 # The version of cfn-lint to use - hooks: - - id: cfn-lint - files: path/to/cfn/dir/.*\.(json|yml|yaml)$ + - repo: https://github.com/aws-cloudformation/cfn-lint + rev: v0.87.1 # The version of cfn-lint to use + hooks: + - id: cfn-lint + files: path/to/cfn/dir/.*\.(json|yml|yaml)$ ``` If you are using a `.cfnlintrc` and specifying the `templates` or `ignore_templates` we would recommend using the `.cfnlintrc` exlusively to determine which files should be scanned and then using: + ```yaml repos: -- repo: https://github.com/aws-cloudformation/cfn-lint - rev: v0.87.1 # The version of cfn-lint to use - hooks: - - id: cfn-lint-rc + - repo: https://github.com/aws-cloudformation/cfn-lint + rev: v0.87.1 # The version of cfn-lint to use + hooks: + - id: cfn-lint-rc ``` -*Note: When mixing .cfnlintrc ignore_templates and files option in your .pre-commit-config.yaml cfn-lint may return a file not found error* -* If you exclude the `files:` line above, every json/yml/yaml file will be checked. -* You can see available cfn-lint versions on the [releases page](https://github.com/aws-cloudformation/cfn-python-lint/releases). +_Note: When mixing .cfnlintrc ignore_templates and files option in your .pre-commit-config.yaml cfn-lint may return a file not found error_ + +- If you exclude the `files:` line above, every json/yml/yaml file will be checked. +- You can see available cfn-lint versions on the [releases page](https://github.com/aws-cloudformation/cfn-python-lint/releases). diff --git a/docs/cfn-resource-specification.md b/docs/cfn-resource-specification.md deleted file mode 100644 index 787d8b3709..0000000000 --- a/docs/cfn-resource-specification.md +++ /dev/null @@ -1,27 +0,0 @@ -# CloudFormation Resource Specification -The core linting of `cfn-lint` is based on the [CloudFormation Resource Specification](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html). The AWS CloudFormation resource specifications are JSON-formatted text files that defines the resources and properties that AWS CloudFormation supports. - -These specification files contain information about the supported resources (per region) and information about the layout of these resources and it's properties. - -## Rules based on the Specifications -There are multiple rules that are based on information from the specification files. - -### Required -The Required rule ([`E3003`](/docs/rules.md#E3003)) checks if properties that are marked as required in the [property specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification-format.html#cfn-resource-specification-format-propertytypes) are specified. - -### ValuePrimitiveType -The ValuePrimitiveType rule ([`E3012`](/docs/rules.md#E3012)) checks if the value of a property is of the same type as specified in the [property specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification-format.html#cfn-resource-specification-format-propertytypes) thus enforcing strict typing of CloudFormation templates. In short this means a number is a number, string is a string, etc. By default, strict typing is **NOT** enforced. - -Although there are situations in which a warning would be sufficient (Python/YAML does implicit conversions) this could also result in errors (More information in issues [42](https://github.com/aws-cloudformation/cfn-python-lint/issues/42) and [180](https://github.com/aws-cloudformation/cfn-python-lint/issues/180)). Since the Specification contains a mapping to the underlying API's this is out of control of cfn-lint. cfn-lint doesn't have an exception process so all instances of this issue are considered errors. - -### Properties -The Properties rule ([`E3002`](/docs/rules.md#E3002)) checks if the basic property configuration of resources is correct. It checks the properties from the [Resource Specification](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification-format.html#cfn-resource-specification-format-resourcetype) and [property specifications](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification-format.html#cfn-resource-specification-format-propertytypes) to check if the specified properties are valid and performs basic checks on the Type (e.g. sub-properties and Lists). - -### AllowedValue -There are properties that need to specified with a specific enumerator, like the [Lambda Runtime](https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html#SSS-CreateFunction-request-Runtime). This information is not part of the default Specification. -The linter extends the specification with these allowed values. The AllowedValue rule ([E3030](/docs/rules.md#E3030)) checks if specified values contain allowed values. - -### AllowedPattern -There are properties that are restricted with a pattern ([Regular Expression](https://en.wikipedia.org/wiki/Regular_expression)), like the [Cognito Userpool EmailVerificationMessage](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-EmailVerificationMessage). This information is not part of the default specification. -The Linter extends the specification with these patterns in a generic rule. The AllowedPattern rule ([E3031](/docs/rules.md#E3031)) checks if specific values adhere to the specified regex. -*Since regular expression can be complex to read, the rules also supports the specification of a "human readable" value that is used in the error message* diff --git a/docs/cfn-schema-specification.md b/docs/cfn-schema-specification.md index 49ad32a7b0..57f550d3d9 100644 --- a/docs/cfn-schema-specification.md +++ b/docs/cfn-schema-specification.md @@ -38,32 +38,52 @@ Resource types may have complex rules to define what a valid resource configurat To make schema writing easier across hundereds of resources we have extend the schemas to include some additional keywords. While these keywords can be covered under the JSON schema they have to be done with a combination of `if`s, `onlyOne`s, `anyOf`s, etc. By using these keywords we can extend the schema for common scenarios when writing CloudFormation schemas. -#### pattern +#### type -_pattern_ keyword is used to validate a string against a regular expression. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/string#regexp) +_type_ specifies the data type for a schema. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/type) #### enum _enum_ is used to restrict a value to a fixed set of values. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/string#enum) -#### number range +#### Strings + +##### pattern + +_pattern_ keyword is used to validate a string against a regular expression. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/string#regexp) + +#### length + +_minLength_ and _maxLength_ are used to are used to constrain the size of a string. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/string#length) + +#### Numbers or Integers + +##### number range _minimum_ and _maximum_ is used to define the inclusive range for a number or integer. _exclusiveMinimum_ and _exclusiveMaximum_ is used to define the exlusive range for a number or integer. -#### array length +#### Arrays + +##### array length _minItems_ and _maxItems_ is used to provide the inclusive length of an array. -#### properties +##### prefixItems + +_prefixItems_ is similar to the definition of [prefixItems](https://json-schema.org/understanding-json-schema/reference/array#tupleValidation) but doesn't actually do the prefix. The current resource schema doesn't support [items](https://json-schema.org/understanding-json-schema/reference/array#items) being an array. We use `prefixItems` to validate array items where ordering matters. + +#### Objects + +##### properties _properties_ provides the key names and a value that represents the schema to validate the property for an object. [JSON Schema Docs](https://json-schema.org/understanding-json-schema/reference/object#properties) -#### required +##### required _required_ defines a list of required properties. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/object#required) -#### requiredXor +##### requiredXor _requiredXor_ is used to define when only one property from a set properties is required. @@ -106,7 +126,7 @@ is equivalent to the JSON schema } ``` -#### propertiesNand +##### propertiesNand _propertiesNand_ is used to define when none or only one property from a set properties can be defined. @@ -156,11 +176,11 @@ is equivalent to the JSON schema } ``` -#### dependentRequired +##### dependentRequired _dependentRequired_ has been backported into cfn-lint. You can read the definition [here](https://json-schema.org/understanding-json-schema/reference/conditionals#dependentRequired) -#### dependentExcluded +##### dependentExcluded _dependentExcluded_ is the opposite of dependentRequired. The list of properties should not be specified when the key property is specified. @@ -201,11 +221,3 @@ is equivalent to the JSON schema } } ``` - -#### prefixItems - -_prefixItems_ is similar to the definition of [prefixItems](https://json-schema.org/understanding-json-schema/reference/array#tupleValidation) but doesn't actually do the prefix. The current resource schema doesn't support [items](https://json-schema.org/understanding-json-schema/reference/array#items) being an array. We use `prefixItems` to validate array items where ordering matters. - -#### type - -_type_ specifies the data type for a schema. [JSON Schema docs](https://json-schema.org/understanding-json-schema/reference/type) diff --git a/docs/internal.md b/docs/internal.md index 87810f92cb..b5330b2217 100644 --- a/docs/internal.md +++ b/docs/internal.md @@ -34,139 +34,28 @@ cfn-lint --update-documentation The official resource specifications are one source of data, the other two are the "extended specs" which are "patches" to the spec that enforce more constraints, and the "additional specs" which are rules written in JSON format that are then picked up by their respective Python class. -#### CloudSpecs - -The command `cfn-lint --update-specs` pulls down the official resource specifications into folder `CloudSpecs` and patches the JSON files with the contents of the files in `ExtendedSpecs`. The merged results are stored in `CloudSpecs`. - -#### ExtendedSpecs - -These files follow the [JsonPatch format](http://jsonpatch.com/) and are merged with the official specs. They support the following syntax: - -- Allowed patterns. [Example](https://github.com/aws-cloudformation/cfn-python-lint/blob/a46773c752247c51effef415bd3462eaec10ab0b/src/cfnlint/data/ExtendedSpecs/all/03_value_types.json#L33-L36): - - ```json - { - "op": "add", - "path": "/ValueTypes", - "value": { - "CidrIp": { - "AllowedPattern": "x.x.x.x/y", - "AllowedPatternRegex": "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(/([0-9]|[1-2][0-9]|3[0-2]))$" - } - } - } - ``` - -- Allowed values. One example: [`ExtendedSpecs/$REGION/05_pricing_property_values.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/ExtendedSpecs/all/05_pricing_property_values.json) validates EMR instance types and is generated by [`scripts/update_specs_from_pricing.py`](https://github.com/aws-cloudformation/cfn-python-lint/blob/cc6ac28ff7deba86cb82813733cceec4bdff68a2/scripts/update_specs_from_pricing.py#L235). [Another example](https://github.com/aws-cloudformation/cfn-python-lint/blob/6cce9222c89056f1546f6fee068ce6dc9dfa394e/src/cfnlint/data/ExtendedSpecs/all/03_value_types/aws_codebuild.json#L2-L11): - - ```json - { - "op": "add", - "path": "/ValueTypes/AWS::CodeBuild::Project.Artifacts.Packaging", - "value": { - "AllowedValues": [ - "NONE", - "ZIP" - ] - } - } - ``` - -- List size constraints. [Example](https://github.com/aws-cloudformation/cfn-python-lint/blob/6cce9222c89056f1546f6fee068ce6dc9dfa394e/src/cfnlint/data/ExtendedSpecs/all/03_value_types/aws_iam.json#L71-L78): - - ```json - { - "op": "add", - "path": "/ValueTypes/AWS::IAM::Group.Names", - "value": { - "ListMax": 10, - "ListMin": 0 - } - } - ``` - -- Number size constraints. [Example](https://github.com/aws-cloudformation/cfn-python-lint/blob/df8d065380e49e53dad9513dab41c2438e105f43/src/cfnlint/data/ExtendedSpecs/all/03_value_types/aws_sqs.json#L17-L24): - - ```json - { - "op": "add", - "path": "/ValueTypes/AWS::SQS::Queue.MaximumMessageSize", - "value": { - "NumberMax": 262144, - "NumberMin": 1024 - } - } - ``` - -- String size constraints. [Example](https://github.com/aws-cloudformation/cfn-python-lint/blob/67fc5bb210b020e3226261f966a01726d574475d/src/cfnlint/data/ExtendedSpecs/all/03_value_types/aws_logs.json#L2-L9): - - ```json - { - "op": "add", - "path": "/ValueTypes/AWS::Logs::LogGroup.LogGroupName", - "value": { - "StringMax": 512, - "StringMin": 1 - } - } - ``` - -There should be no functional difference, but [`src/cfnlint/data/ExtendedSpecs/all/03_value_types`](https://github.com/aws-cloudformation/cfn-python-lint/tree/main/src/cfnlint/data/ExtendedSpecs/all/03_value_types) and [`src/cfnlint/data/ExtendedSpecs/all/04_property_values`](https://github.com/aws-cloudformation/cfn-python-lint/tree/main/src/cfnlint/data/ExtendedSpecs/all/04_property_values) are more organized than [`src/cfnlint/data/ExtendedSpecs/all/03_value_types.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/ExtendedSpecs/all/03_value_types.json) and [`src/cfnlint/data/ExtendedSpecs/all/04_property_values.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/ExtendedSpecs/all/04_property_values.json), so they should be preferred locations for new constraints. - -[`ExtendedSpecs/$REGION/06_ssm_service_removal.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/ExtendedSpecs/us-gov-east-1/06_ssm_service_removal.json) is written by [`scripts/update_specs_services_from_ssm.py`](https://github.com/aws-cloudformation/cfn-python-lint/blob/cc6ac28ff7deba86cb82813733cceec4bdff68a2/scripts/update_specs_services_from_ssm.py#L165) and [`ExtendedSpecs/$REGION/07_ssm_service_addition.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/ExtendedSpecs/us-gov-east-1/07_ssm_service_addition.json) is written by [`scripts/update_specs_services_from_ssm.py`](https://github.com/aws-cloudformation/cfn-python-lint/blob/cc6ac28ff7deba86cb82813733cceec4bdff68a2/scripts/update_specs_services_from_ssm.py#L204). - -If we push changes to these files, customers will have to update `cfn-lint`. The person changing the file(s) can also see the changes by running the following: +#### Schemas -```shell -pip3 install -e . -cfn-lint --update-specs # https://github.com/aws-cloudformation/cfn-python-lint/pull/1383#issuecomment-629891506 -``` +The command `cfn-lint --update-specs` pulls down the official resource specifications into folder `schemas` and patches the JSON files with the contents of the files in `patches` folder. The merged results are stored in `providers`. + +##### Extensions + +Extensions are used to extend the provider schemas. We use these schemas for specific tests where it can be hard to nest it in the resource provider schema. Using extensions allow us to create separate rule IDs for each extension which allows the customer to ignore the error or for us to change the rule level (example: warning) + +##### Other + +The other folder has any schema used for validation that isn't under a resources properties. This includes schemas for the overall template structure of a CloudFormation template, IAM policy schemas, CFN Init schemas, and more. + +##### Patches + +Patches contain all the patches we apply to the provider schemas when they are downloaded. There are two folders inside patches. _providers_ patch issues in the provider schema itself and _extensions_ apply additions to the provider schema to create better linting results. + +##### Providers + +Providers stores all the regional resource provider schemas after they are patched. Files are deduplicated so that we are storing as little as possible. If you look at the `__init__.py` file you will see what resources are cached. #### AdditionalSpecs If we push changes to these files, customers will have to update their version of `cfn-lint`. They support the following syntax: -- [At least one of these properties must be specified](https://github.com/aws-cloudformation/cfn-python-lint/blob/b788cc9bd3d49ed20d5f2e58602755a0ef37f52c/src/cfnlint/data/AdditionalSpecs/AtLeastOne.json#L20-L25), used by rule [E2522](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/rules/resources/properties/AtLeastOne.py). Example: - - ```json - "AWS::EC2::Instance": [ - [ - "ImageId", - "LaunchTemplate" - ] - ] - ``` - -- [Only one of these properties may be specified](https://github.com/aws-cloudformation/cfn-python-lint/blob/b788cc9bd3d49ed20d5f2e58602755a0ef37f52c/src/cfnlint/data/AdditionalSpecs/OnlyOne.json#L79-L84), used by rule [E2523](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/rules/resources/properties/OnlyOne.py). Example: - - ```json - "AWS::CloudWatch::Alarm": [ - [ - "MetricName", - "Metrics" - ] - ] - ``` - -- [If this property is specified, these properties must be excluded](https://github.com/aws-cloudformation/cfn-python-lint/blob/b788cc9bd3d49ed20d5f2e58602755a0ef37f52c/src/cfnlint/data/AdditionalSpecs/Exclusive.json#L102-L107), used by rule [E2520](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/rules/resources/properties/Exclusive.py). Example: - - ```json - "AWS::RDS::DBCluster": { - "SnapshotIdentifier": [ - "MasterUsername", - "MasterUserPassword" - ] - } - ``` - -- [If this property is specified, these properties must be included](https://github.com/aws-cloudformation/cfn-python-lint/blob/b788cc9bd3d49ed20d5f2e58602755a0ef37f52c/src/cfnlint/data/AdditionalSpecs/Inclusive.json#L48-L52), used by rule [E2521](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/rules/resources/properties/Inclusive.py). Example: - - ```json - "AWS::OpsWorks::Stack": { - "VpcId": [ - "DefaultSubnetId" - ] - } - ``` - [`AdditionalSpecs/RdsProperties.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/AdditionalSpecs/RdsProperties.json) is written by [`scripts/update_specs_from_pricing.py`](https://github.com/aws-cloudformation/cfn-python-lint/blob/cc6ac28ff7deba86cb82813733cceec4bdff68a2/scripts/update_specs_from_pricing.py#L189) and used by rule [E3025](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/rules/resources/rds/InstanceSize.py) and [`AdditionalSpecs/Policies.json`](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/data/AdditionalSpecs/Policies.json) is written by [`cfn-lint --update-iam-policies`](https://github.com/aws-cloudformation/cfn-python-lint/blob/cc6ac28ff7deba86cb82813733cceec4bdff68a2/src/cfnlint/maintenance.py#L173) and used by rule [W3037](https://github.com/aws-cloudformation/cfn-python-lint/blob/main/src/cfnlint/rules/resources/iam/Permissions.py). diff --git a/src/cfnlint/rules/resources/properties/NumberRange.py b/src/cfnlint/rules/resources/properties/NumberRange.py index a798a7e5bd..8e42c769a3 100644 --- a/src/cfnlint/rules/resources/properties/NumberRange.py +++ b/src/cfnlint/rules/resources/properties/NumberRange.py @@ -21,7 +21,7 @@ class NumberRange(CloudFormationLintRule): "Check numbers (integers and floats) for its value being between the minimum" " and maximum" ) - source_url = "https://github.com/awslabs/cfn-python-lint/blob/main/docs/cfn-resource-specification.md#allowedpattern" + source_url = "https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/cfn-schema-specification.md#number-range" tags = ["resources", "property", "number", "size"] child_rules = { "W3034": None, diff --git a/src/cfnlint/rules/resources/properties/StringLength.py b/src/cfnlint/rules/resources/properties/StringLength.py index ebf59c95e5..f278d26ad7 100644 --- a/src/cfnlint/rules/resources/properties/StringLength.py +++ b/src/cfnlint/rules/resources/properties/StringLength.py @@ -20,7 +20,7 @@ class StringLength(CloudFormationLintRule): id = "E3033" shortdesc = "Check if a string has between min and max number of values specified" description = "Check strings for its length between the minimum and maximum" - source_url = "https://github.com/awslabs/cfn-python-lint/blob/main/docs/cfn-resource-specification.md#allowedpattern" + source_url = "https://github.com/aws-cloudformation/cfn-lint/blob/v1/docs/cfn-schema-specification.md#length" tags = ["resources", "property", "string", "size"] def _serialize_date(self, obj):