Skip to content

Commit

Permalink
Merge pull request #478 from miparnisari/patch-1
Browse files Browse the repository at this point in the history
Properly highlight code snippets in documentation
  • Loading branch information
thegonch authored Jun 26, 2020
2 parents afe36b4 + 6879faf commit e9a47b0
Showing 1 changed file with 28 additions and 20 deletions.
48 changes: 28 additions & 20 deletions custom_rule_development.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
## Crash Course in (New) Rule Development

1. Create a class that ends with the name Rule. This is a convention that must be observed in order for cfn-nag to load
the rule. Additionally, derive this class from BaseRule:
the rule. Additionally, derive this class from `BaseRule`:

require 'cfn-nag/violation'
require_relative 'base'
```ruby
require 'cfn-nag/violation'
require_relative 'base'

class IamManagedPolicyNotActionRule < BaseRule
class IamManagedPolicyNotActionRule < BaseRule
```

2. Define methods that describe some of the bookkeeping for the rule, like whether it is a WARNING/FAILING_VIOLATION, its
unique identifier among rules, and error text shown when it matches:

def rule_text
'IAM managed policy should not allow Allow+NotAction'
end
```ruby
def rule_text
'IAM managed policy should not allow Allow+NotAction'
end
def rule_type
Violation::WARNING
end
def rule_type
Violation::WARNING
end
def rule_id
'W17'
end
def rule_id
'W17'
end
```

3. Define the `audit_impl` method to do the actual work of the analysis. This method should return an array of
logical resource identifiers from the CloudFormation template:

def audit_impl(cfn_model)
violating_policies = cfn_model.resources_by_type('AWS::IAM::ManagedPolicy').select do |policy|
!policy.policy_document.allows_not_action.empty?
end
```ruby
def audit_impl(cfn_model)
violating_policies = cfn_model.resources_by_type('AWS::IAM::ManagedPolicy').select do |policy|
!policy.policy_document.allows_not_action.empty?
end
violating_policies.map { |policy| policy.logical_resource_id }
end
violating_policies.map { |policy| policy.logical_resource_id }
end
```

4. The cfn_model object passed into the `audit_impl` method is where a majority of the improvement lies. When
a CloudFormation document is parsed, it is mapped into a collection of objects that mirror the resource types.
Expand All @@ -43,13 +49,15 @@
* Attributes/properties are returned in camelCase.
* For example, if dealing with an object type of 'AWS::RDS::DBCluster', and needing to write logic against the 'StorageEncrypted' property, then an example `audit_impl` might look like this:

```ruby
def audit_impl(cfn_model)
violating_rdscluster = cfn_model.resources_by_type('AWS::RDS::DBCluster').select do |cluster|
cluster.storageEncrypted.nil? || cluster.storageEncrypted.to_s.downcase == 'false'
end
violating_rdscluster.map { |cluster| cluster.logical_resource_id }
end
```

* cfn-model provides special handling for a subset of objects whereby properties may be transformed into something
simpler and/or objects may be linked together.
Expand Down Expand Up @@ -114,4 +122,4 @@ install` to install dependencies.
For any generic rules you want to share with the community, submit a PR of the rule to `lib/custom_rules`.
Code should be linted using [Rubocop](https://github.com/rubocop-hq/rubocop). Please be sure to use a unique
`rule_id` and write the rule according section 1 of the above "Where to Place Rule Files" area.
`rule_id` and write the rule according section 1 of the above "Where to Place Rule Files" area.

0 comments on commit e9a47b0

Please sign in to comment.