Skip to content

Commit ed4ff6e

Browse files
feat: add aws_security_group_rule_deprecated rule (#790)
* generate rule * finish coding * finish docs * amend docs * add rule name to output * Update docs/rules/aws_security_group_rule_deprecated.md Co-authored-by: Ben Drucker <[email protected]> * fix review issues * get the resource only * Update README.md * Update README.md * Update README.md.tmpl * Update README.md --------- Co-authored-by: Ben Drucker <[email protected]>
1 parent 1538e44 commit ed4ff6e

File tree

6 files changed

+151
-0
lines changed

6 files changed

+151
-0
lines changed

docs/rules/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ These rules enforce best practices and naming conventions:
7575
|[aws_lambda_function_deprecated_runtime](aws_lambda_function_deprecated_runtime.md)|Disallow deprecated runtimes for Lambda Function||
7676
|[aws_resource_missing_tags](aws_resource_missing_tags.md)|Require specific tags for all AWS resource types that support them||
7777
|[aws_s3_bucket_name](aws_s3_bucket_name.md)|Ensures all S3 bucket names match the naming rules||
78+
|[aws_security_group_rule_deprecated](aws_security_group_rule_deprecated.md)|Disallow using `aws_security_group_rule` resource||
7879
|[aws_provider_missing_default_tags](aws_provider_missing_default_tags.md)|Require specific tags for all AWS providers default tags||
7980

8081
### SDK-based Validations

docs/rules/README.md.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ These rules enforce best practices and naming conventions:
7575
|[aws_lambda_function_deprecated_runtime](aws_lambda_function_deprecated_runtime.md)|Disallow deprecated runtimes for Lambda Function|✔|
7676
|[aws_resource_missing_tags](aws_resource_missing_tags.md)|Require specific tags for all AWS resource types that support them||
7777
|[aws_s3_bucket_name](aws_s3_bucket_name.md)|Ensures all S3 bucket names match the naming rules|✔|
78+
|[aws_security_group_rule_deprecated](aws_security_group_rule_deprecated.md)|Disallow using `aws_security_group_rule` resource||
7879
|[aws_provider_missing_default_tags](aws_provider_missing_default_tags.md)|Require specific tags for all AWS providers default tags||
7980

8081
### SDK-based Validations
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# aws_security_group_rule_deprecated
2+
3+
The `aws_security_group_rule` resource should be replaced with `aws_vpc_security_group_egress_rule` or `aws_vpc_security_group_ingress_rule`. It lacks support of unique IDs, tags, and descriptions, and has difficulties managing multiple CIDR blocks.
4+
5+
## Example
6+
7+
```hcl
8+
resource "aws_security_group_rule" "foo" {
9+
security_group_id = "sg-12345678"
10+
type = "ingress"
11+
}
12+
```
13+
14+
```sh
15+
❯ tflint
16+
1 issue(s) found:
17+
18+
Warning: Consider using aws_vpc_security_group_egress_rule or aws_vpc_security_group_ingress_rule instead. (aws_security_group_rule_deprecated)
19+
20+
on bastion.tf line 4:
21+
4: resource "aws_security_group_rule" "foo" {
22+
```
23+
24+
## Why
25+
26+
Avoid using the [`aws_security_group_rule`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) resource because it has difficulties managing multiple CIDR blocks and historically lacks unique IDs, tags, and descriptions. To prevent these issues, follow the current best practice of using the `aws_vpc_security_group_egress_rule` and `aws_vpc_security_group_ingress_rule` resources.
27+
28+
## How To Fix
29+
30+
Depending on `type`, you can fix the issue by using either `aws_vpc_security_group_egress_rule` or `aws_vpc_security_group_ingress_rule`.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package rules
2+
3+
import (
4+
"github.com/terraform-linters/tflint-plugin-sdk/hclext"
5+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
6+
"github.com/terraform-linters/tflint-ruleset-aws/project"
7+
)
8+
9+
// AwsSecurityGroupRuleDeprecatedRule checks that aws_security_group_rule is not used
10+
type AwsSecurityGroupRuleDeprecatedRule struct {
11+
tflint.DefaultRule
12+
13+
resourceType string
14+
attributeName string
15+
}
16+
17+
// NewAwsSecurityGroupRuleDeprecatedRule returns new rule with default attributes
18+
func NewAwsSecurityGroupRuleDeprecatedRule() *AwsSecurityGroupRuleDeprecatedRule {
19+
return &AwsSecurityGroupRuleDeprecatedRule{
20+
resourceType: "aws_security_group_rule",
21+
attributeName: "security_group_id",
22+
}
23+
}
24+
25+
// Name returns the rule name
26+
func (r *AwsSecurityGroupRuleDeprecatedRule) Name() string {
27+
return "aws_security_group_rule_deprecated"
28+
}
29+
30+
// Enabled returns whether the rule is enabled by default
31+
func (r *AwsSecurityGroupRuleDeprecatedRule) Enabled() bool {
32+
return false
33+
}
34+
35+
// Severity returns the rule severity
36+
func (r *AwsSecurityGroupRuleDeprecatedRule) Severity() tflint.Severity {
37+
return tflint.WARNING
38+
}
39+
40+
// Link returns the rule reference link
41+
func (r *AwsSecurityGroupRuleDeprecatedRule) Link() string {
42+
return project.ReferenceLink(r.Name())
43+
}
44+
45+
// Check that aws_security_group_rule resource is not used
46+
func (r *AwsSecurityGroupRuleDeprecatedRule) Check(runner tflint.Runner) error {
47+
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{}, nil)
48+
if err != nil {
49+
return err
50+
}
51+
52+
for _, resource := range resources.Blocks {
53+
runner.EmitIssue(
54+
r,
55+
"Consider using aws_vpc_security_group_egress_rule or aws_vpc_security_group_ingress_rule instead.",
56+
resource.DefRange,
57+
)
58+
}
59+
60+
return nil
61+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package rules
2+
3+
import (
4+
"testing"
5+
6+
hcl "github.com/hashicorp/hcl/v2"
7+
"github.com/terraform-linters/tflint-plugin-sdk/helper"
8+
)
9+
10+
func Test_AwsSecurityGroupRuleDeprecated(t *testing.T) {
11+
cases := []struct {
12+
Name string
13+
Content string
14+
Expected helper.Issues
15+
}{
16+
{
17+
Name: "resource is used",
18+
Content: `
19+
resource "aws_security_group_rule" "test" {
20+
security_group_id = "sg-12345678"
21+
}
22+
`,
23+
Expected: helper.Issues{
24+
{
25+
Rule: NewAwsSecurityGroupRuleDeprecatedRule(),
26+
Message: "Consider using aws_vpc_security_group_egress_rule or aws_vpc_security_group_ingress_rule instead.",
27+
Range: hcl.Range{
28+
Filename: "resource.tf",
29+
Start: hcl.Pos{Line: 2, Column: 1},
30+
End: hcl.Pos{Line: 2, Column: 42},
31+
},
32+
},
33+
},
34+
},
35+
{
36+
Name: "everything is fine",
37+
Content: `
38+
resource "aws_security_group" "test" {
39+
name = "test"
40+
}
41+
`,
42+
Expected: helper.Issues{},
43+
},
44+
}
45+
46+
rule := NewAwsSecurityGroupRuleDeprecatedRule()
47+
48+
for _, tc := range cases {
49+
runner := helper.TestRunner(t, map[string]string{"resource.tf": tc.Content})
50+
51+
if err := rule.Check(runner); err != nil {
52+
t.Fatalf("Unexpected error occurred: %s", err)
53+
}
54+
55+
helper.AssertIssues(t, tc.Expected, runner.Issues)
56+
}
57+
}

rules/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ var manualRules = []tflint.Rule{
4141
NewAwsSecurityGroupInvalidProtocolRule(),
4242
NewAwsSecurityGroupRuleInvalidProtocolRule(),
4343
NewAwsProviderMissingDefaultTagsRule(),
44+
NewAwsSecurityGroupRuleDeprecatedRule(),
4445
}
4546

4647
// Rules is a list of all rules

0 commit comments

Comments
 (0)