Skip to content

Commit 8bb95e4

Browse files
committed
Ruleset migration from aws-quickstart
1 parent 67ec8ce commit 8bb95e4

File tree

2,452 files changed

+2802264
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,452 files changed

+2802264
-2
lines changed

.coveragerc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[run]
2+
branch = True
3+
include =
4+
*cfn_mp_ql_rules*

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
__pycache__/
2+
/venv/
3+
.DS_Store
4+
*.pyc
5+
.idea
6+
*.egg-info/
7+
.coverage
8+
.python-version
9+
.vscode

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "assets/git-secrets"]
2+
path = assets/git-secrets
3+
url = https://github.com/awslabs/git-secrets.git

.pre-commit-config.yaml

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
exclude: ^(.travis.yml|.pre-commit-config.yaml)$
2+
fail_fast: true
3+
repos:
4+
#- repo: https://github.com/pre-commit/mirrors-isort
5+
# rev: v4.3.21
6+
# hooks:
7+
# - id: isort
8+
# # language_version: python3.6
9+
- repo: https://github.com/psf/black
10+
rev: 22.1.0
11+
hooks:
12+
- id: black
13+
- repo: https://github.com/pre-commit/pre-commit-hooks
14+
rev: v4.1.0
15+
hooks:
16+
- id: check-case-conflict
17+
- id: end-of-file-fixer
18+
- id: mixed-line-ending
19+
args:
20+
- --fix=lf
21+
- id: trailing-whitespace
22+
- id: check-json
23+
- id: pretty-format-json
24+
args:
25+
- --autofix
26+
- --indent
27+
- '2'
28+
- --no-sort-keys
29+
- repo: https://github.com/PyCQA/flake8
30+
rev: 4.0.1
31+
hooks:
32+
- id: flake8
33+
additional_dependencies:
34+
- flake8-bugbear>=19.3.0
35+
- flake8-builtins>=1.4.1
36+
- flake8-commas>=2.0.0
37+
- flake8-comprehensions>=2.1.0
38+
- flake8-debugger>=3.1.0
39+
- flake8-pep3101>=1.2.1
40+
- flake8-print>=3.1.0
41+
# language_version: python3.6
42+
# - id: pretty-format-json
43+
# args:
44+
# - --autofix
45+
# - --indent=4
46+
# - --no-sort-keys
47+
# - id: check-merge-conflict
48+
#- repo: https://github.com/pre-commit/pygrep-hooks
49+
# rev: v1.4.4
50+
# hooks:
51+
# - id: python-check-blanket-noqa
52+
# - id: python-check-mock-methods
53+
# - id: python-no-log-warn
54+
- repo: https://github.com/PyCQA/bandit
55+
rev: 1.7.2
56+
hooks:
57+
- id: bandit
58+
files: "^taskcat/"
59+
args: ["--skip", "B322"]
60+
#- repo: https://github.com/pre-commit/mirrors-mypy
61+
# rev: v0.761
62+
# hooks:
63+
# - id: mypy
64+
# files: "^taskcat/"
65+
- repo: local
66+
hooks:
67+
# - id: update-schema
68+
# name: update-schema
69+
# description: generate schema from dataclasses
70+
# entry: python generate_schema.py
71+
# language: system
72+
# pass_filenames: false
73+
# always_run: true
74+
# - id: git-secrets-register-aws
75+
# name: git-secrets-register-aws
76+
# description: Register AWS patterns with git-secrets
77+
# entry: git-secrets --register-aws
78+
# language: system
79+
# always_run: true
80+
# pass_filenames: false
81+
# - id: git-secrets
82+
# name: git-secrets
83+
# description: Run git-secrets
84+
# entry: git-secrets --scan
85+
# language: system
86+
# always_run: true
87+
# - id: pylint-local
88+
# name: pylint-local
89+
# description: Run pylint in the local virtualenv
90+
# entry: pylint "setup.py" "taskcat/" "bin/"
91+
# language: system
92+
# pass_filenames: false
93+
# always_run: true
94+
- id: pytest-local
95+
name: pytest-local
96+
description: Run pytest in the local virtualenv
97+
entry: pytest "./test/"
98+
language: system
99+
pass_filenames: false
100+
always_run: true

.pre-commit-hooks.yaml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
- id: qs-cfn-lint
2+
name: AWS Quick Start Linter
3+
entry: cfn-lint
4+
language: python
5+
files: \.(json|yaml|yml)$
6+
- id: qs-cfn-lint-wrapped
7+
name: AWS Quick Start Linter
8+
entry: wrapped-cfn-lint
9+
language: python
10+
files: \.(json|yaml|yml)$
11+
- id: files-are-cfn
12+
name: Validates files are CFN
13+
entry: files-are-cfn
14+
language: python
15+
types_or: [json, yaml]
16+
- id: files-are-not-cfn
17+
name: Validates files are not CFN
18+
entry: files-are-cfn
19+
language: python
20+
types_or: [json, yaml]
21+
args:
22+
- '-i'

CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @aws-ia/aws-ia

README.md

+113-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,113 @@
1-
# cfn-mp-ql-rules
2-
Custom cfn-lint ruleset
1+
# AWS Quick Start cfn-lint rules
2+
3+
This repo provides CloudFormation linting rules specific to [AWS Quick Start](https://aws.amazon.com/quickstart/)
4+
guidelines, for more information see the [Contributors Guide](https://aws-ia.github.io).
5+
6+
## Installation and Usage
7+
8+
```bash
9+
cd ~/
10+
git clone https://github.com/aws-ia/cfn-mp-ql-rules.git
11+
cd cfn-mp-ql-rules
12+
pip install -e .
13+
```
14+
15+
To add the rules when running on the command line use the `-a` flag to add the additional rules:
16+
17+
```bash
18+
cfn-lint my-cfn-template.yaml -a ~/cfn-mp-ql-rules/cfn_mp_ql_rules/
19+
```
20+
21+
To use in your IDE install the relevant
22+
[cfn-lint plugin](https://github.com/aws-cloudformation/cfn-python-lint#editor-plugins) and add the rules to your
23+
cfn-lint config file (`~/.cfnlintrc`) as follows:
24+
25+
```yaml
26+
append_rules:
27+
- ~/cfn-mp-ql-rules/cfn_mp_ql_rules/
28+
```
29+
30+
## Vim Specfic Instructions (using vundle and syntastic)
31+
32+
![image](https://user-images.githubusercontent.com/5912128/55508631-22366880-560f-11e9-867f-baa516712f63.png)
33+
34+
### Install the plugins
35+
36+
**Add to `syntastic` and `vim-cfn` your `~/.vimrc`:**
37+
38+
__Add to vundle plugin section:__
39+
40+
```vim
41+
"---------------------------=== CloudFormation ===------------------------------
42+
Plugin 'scrooloose/syntastic' " Syntax checking plugin for Vim
43+
Plugin 'speshak/vim-cfn' "CloudFormation syntax checking/highlighting
44+
```
45+
46+
#### Install plugins
47+
48+
```bash
49+
vim +PluginInstall +qall
50+
```
51+
52+
### Set statusline and triggers
53+
54+
**Append to the bottom of your `~/.vimrc`**
55+
56+
```vim
57+
"cfn-lint
58+
set statusline+=%#warningmsg#
59+
set statusline+=%{SyntasticStatuslineFlag()}
60+
set statusline+=%*
61+
62+
let g:syntastic_always_populate_loc_list = 1
63+
let g:syntastic_auto_loc_list = 1
64+
let g:syntastic_check_on_open = 1
65+
let g:syntastic_check_on_wq = 0
66+
let g:syntastic_cloudformation_checkers = ['cfn_lint']
67+
```
68+
69+
### Set FileTypes for vim-cfn
70+
71+
**Add to `~/.vim/bundle/vim-cfn/ftdetect/cloudformation.vim`**
72+
73+
```vim
74+
autocmd BufNewFile,BufRead *.template setfiletype yaml.cloudformation
75+
autocmd BufNewFile,BufRead *.template.yaml setfiletype yaml.cloudformation
76+
```
77+
78+
### Update syntastic plugin
79+
80+
Add the following to ~/.vim/after/plugin/syntastic.vim:
81+
82+
```vim
83+
let g:syntastic_cloudformation_checkers = ['cfn_lint']
84+
```
85+
86+
## Troubleshooting
87+
88+
### Custom dictionary
89+
90+
If you receive spelling error warnings [9006] for words that are spelled correctly, such as the example below, AWS service names, or words that should be excluded from all future linting, please add these words to `./cfn-mp-ql-rules/data/custom_dict.txt`.
91+
92+
```text
93+
line 93 [9006] Parameter QSS3BucketName contains spelling error(s):
94+
{'customizing'}
95+
```
96+
97+
For spelling exclusions for a specific CloudFormation template, such as partner brand names, please add these words to a `LintSpellExclude` list to the `Metadata` section.
98+
99+
```yaml
100+
Metadata:
101+
LintSpellExclude:
102+
- PartnerName
103+
```
104+
105+
### Sentence case
106+
107+
If you receive sentence case warnings [9006] for words that should be capitalized, such as partner product names, please add a `SentenceCaseExclude` list to the `Metadata` section.
108+
109+
```yaml
110+
Metadata:
111+
SentenceCaseExclude:
112+
- Pro
113+
```

archive/IAMManagedPolicyOnlyGroup.bak

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# """
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
# SPDX-License-Identifier: MIT-0
4+
# """
5+
# from cfnlint.rules import CloudFormationLintRule
6+
# from cfnlint.rules import RuleMatch
7+
8+
9+
# class IAMManagedPolicyOnlyGroup(CloudFormationLintRule):
10+
# id = 'EIAMManagedPolicyOnlyGroup' # New Rule ID
11+
# shortdesc = 'No direct user on IAM Managed policy' # A short description about the rule
12+
# description = 'IAM managed policy should not apply directly to users. Should be on group' # (Longer) description about the rule
13+
# source_url = 'https://github.com/aws-ia/cfn-mp-ql-rules/tree/main' # A url to the source of the rule, e.g. documentation, AWS Blog posts etc
14+
# tags = ["iam"]
15+
16+
# def match(self, cfn):
17+
18+
# """Check if user is mentioned in IAM policy"""
19+
20+
# resources = cfn.get_resources(['AWS::IAM::ManagedPolicy'])
21+
# matches = []
22+
# for resource_name, resource in resources.items():
23+
# path = ['Resources', resource_name, 'Properties']
24+
# properties = resource.get('Properties')
25+
# if properties:
26+
# if (len(properties.get('Users')) >= 1):
27+
# path = ['Resources', resource_name, 'Properties', 'Users']
28+
# message = 'Do not assign Managed IAM policies directly to Users'
29+
# matches.append(RuleMatch(path, message.format(resource_name)))
30+
# return matches
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# """
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
# SPDX-License-Identifier: MIT-0
4+
# """
5+
# from cfnlint.rules import CloudFormationLintRule
6+
# from cfnlint.rules import RuleMatch
7+
8+
9+
# class IAMPolicyResourceWildcardPassRole(CloudFormationLintRule):
10+
# id = 'EIAMPolicyResourceWildardPassRole' # New Rule ID
11+
# shortdesc = 'No * resource with PassRole Action on IAM Policy' # A short description about the rule
12+
# description = 'IAM Policy should not allow * resource with PassRole action on its permissions policy' # (Longer) description about the rule
13+
# source_url = 'https://github.com/aws-ia/cfn-mp-ql-rules/tree/main' # A url to the source of the rule, e.g. documentation, AWS Blog posts etc
14+
# tags = ["iam"]
15+
16+
# def match(self, cfn):
17+
18+
# """Check if IAM policy contains * Resource and PassRole Action"""
19+
20+
# resources = cfn.get_resources(['AWS::IAM::Policy'])
21+
# matches = []
22+
# for resource_name, resource in resources.items():
23+
# path = ['Resources', resource_name, 'Properties']
24+
# properties = resource.get('Properties', {})
25+
# if properties:
26+
# actions = properties.get('PolicyDocument', {}).get('Statement',[])[0].get('Action', [])
27+
# resources_wild = properties.get('PolicyDocument', {}).get('Statement', [])[0].get('Resource', [])
28+
# is_wildcard = false
29+
# if '*' in resources_wild:
30+
# is_wildcard = true
31+
# if ((actions == 'iam:PassRole') and is_wildcard):
32+
# path = ['Resources', resource_name, 'Properties', 'PolicyDocument', 'Statement', 'Action']
33+
# message = 'Do not use a resource wildcard (*) with the PassRole Action'
34+
# matches.append(RuleMatch(path, message.format(resource_name)))
35+
# else:
36+
# for action in actions:
37+
# if ((action == 'iam:PassRole') and is_wildcard):
38+
# path = ['Resources', resource_name, 'Properties', 'PolicyDocument', 'Statement', 'Action']
39+
# message = 'Do not use a resource wildcard (*) with the PassRole Action'
40+
# matches.append(RuleMatch(path, message.format(resource_name)))
41+
# return matches
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# """
2+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
# SPDX-License-Identifier: MIT-0
4+
# """
5+
# from cfnlint.rules import CloudFormationLintRule
6+
# from cfnlint.rules import RuleMatch
7+
8+
# class IAMRoleResourceWildcardPassRole(CloudFormationLintRule):
9+
# id = 'EIAMRoleResourceWildardPassRole' # New Rule ID
10+
# shortdesc = 'No * resource with PassRole Action on IAM role' # A short description about the rule
11+
# description = 'IAM role should not allow * resource with PassRole action on its permissions policy' # (Longer) description about the rule
12+
# source_url = 'https://github.com/aws-ia/cfn-mp-ql-rules/tree/main' # A url to the source of the rule, e.g. documentation, AWS Blog posts etc
13+
# tags = ["iam"]
14+
15+
# def match(self, cfn):
16+
17+
# """Check if IAM role contains * Resource and PassRole Action"""
18+
19+
# resources = cfn.get_resources(['AWS::IAM::Role'])
20+
# matches = []
21+
# for resource_name, resource in resources.items():
22+
# path = ['Resources', resource_name, 'Properties']
23+
# properties = resource.get('Properties')
24+
# if properties:
25+
# actions = properties.get('Policies')[0].get('PolicyDocument').get('Statement')[0].get('Action')
26+
# resources_wild = properties.get('Policies')[0].get('PolicyDocument').get('Statement')[0].get('Resource')
27+
# is_wildcard = ''
28+
# if '*' in resources_wild:
29+
# is_wildcard = '*'
30+
# if ((actions == 'iam:PassRole') and (is_wildcard == '*')):
31+
# path = ['Resources', resource_name, 'Properties', 'Policies', 'PolicyDocument', 'Statement', 'Action']
32+
# message = 'Do not use a resource wildcard (*) with the PassRole Action'
33+
# matches.append(RuleMatch(path, message.format(resource_name)))
34+
# else:
35+
# for action in actions:
36+
# if ((action == 'iam:PassRole') and (is_wildcard == '*')):
37+
# path = ['Resources', resource_name, 'Properties', 'Policies', 'PolicyName', 'Statement', 'Action']
38+
# message = 'Do not use a resource wildcard (*) with the PassRole Action'
39+
# matches.append(RuleMatch(path, message.format(resource_name)))
40+
# return matches

0 commit comments

Comments
 (0)