Skip to content

Commit 6893c81

Browse files
authored
Add lint for db_instance's engine attribute (#61)
* Add lint for db_instance engine * Add test for aws_db_instance_invalid_engine.go * Add document * Fix position aws_db_instance_invalid_engine is rule that warn of possible errors that can occur at `terraform apply`. So it should be in Possible Errors section. * Append new rule * Fix name Co-authored-by: kondo takeshi <[email protected]>
1 parent 6a45222 commit 6893c81

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-0
lines changed

docs/rules/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ These rules warn of possible errors that can occur at `terraform apply`. Rules m
1111
|aws_alb_invalid_security_group||
1212
|aws_alb_invalid_subnet||
1313
|aws_db_instance_invalid_db_subnet_group||
14+
|[aws_db_instance_invalid_engine](aws_db_instance_invalid_engine.md)||
1415
|aws_db_instance_invalid_option_group||
1516
|aws_db_instance_invalid_parameter_group||
1617
|aws_db_instance_invalid_type||
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# aws_db_instance_invalid_engine
2+
3+
Disallow using invalid engine name.
4+
5+
## Example
6+
7+
```hcl
8+
resource "aws_db_instance" "default" {
9+
allocated_storage = 20
10+
engine = "mysql57" // invalid engine name!
11+
engine_version = "5.7"
12+
instance_class = "db.t2.micro"
13+
name = "mydb"
14+
username = "foo"
15+
password = "bar"
16+
db_subnet_group_name = "my_database_subnet_group"
17+
parameter_group_name = "default.mysql5.6"
18+
}
19+
```
20+
21+
```
22+
$ tflint
23+
1 issue(s) found:
24+
25+
Warning: "mysql57" is invalid engine. (aws_db_invalid_engine)
26+
27+
on template.tf line 3:
28+
3: engine = "mysql57" // invalid engine name!
29+
30+
```
31+
32+
## Why
33+
34+
Apply will fail. (Plan will succeed with the invalid value though)
35+
36+
## How To Fix
37+
38+
Select valid engine name according to the [document](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html#options)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package rules
2+
3+
import (
4+
"fmt"
5+
6+
hcl "github.com/hashicorp/hcl/v2"
7+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
8+
"github.com/terraform-linters/tflint-ruleset-aws/project"
9+
)
10+
11+
// AwsDBInstanceInvalidEngineRule checks whether "aws_db_instance" has invalid engine.
12+
type AwsDBInstanceInvalidEngineRule struct {
13+
resource string
14+
attributeName string
15+
engines map[string]bool
16+
}
17+
18+
// NewAwsDBInstanceInvalidEngineRule returns new rule with default attributes
19+
func NewAwsDBInstanceInvalidEngineRule() *AwsDBInstanceInvalidEngineRule {
20+
return &AwsDBInstanceInvalidEngineRule{
21+
resource: "aws_db_instance",
22+
attributeName: "engine",
23+
engines: map[string]bool{
24+
// https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-engine-versions.html#options
25+
"aurora": true,
26+
"aurora-mysql": true,
27+
"aurora-postgresql": true,
28+
"mariadb": true,
29+
"mysql": true,
30+
"oracle-ee": true,
31+
"oracle-se2": true,
32+
"oracle-se1": true,
33+
"oracle-se": true,
34+
"postgres": true,
35+
"sqlserver-ee": true,
36+
"sqlserver-se": true,
37+
"sqlserver-ex": true,
38+
"sqlserver-web": true,
39+
},
40+
}
41+
}
42+
43+
// Name returns the rule name
44+
func (r *AwsDBInstanceInvalidEngineRule) Name() string {
45+
return "aws_db_instance_invalid_engine"
46+
}
47+
48+
// Enabled returns whether the rule is enabled by default
49+
func (r *AwsDBInstanceInvalidEngineRule) Enabled() bool {
50+
return true
51+
}
52+
53+
// Severity returns the rule severity
54+
func (r *AwsDBInstanceInvalidEngineRule) Severity() string {
55+
return tflint.ERROR
56+
}
57+
58+
// Link returns the rule reference link
59+
func (r *AwsDBInstanceInvalidEngineRule) Link() string {
60+
return project.ReferenceLink(r.Name())
61+
}
62+
63+
// Check checks whether "aws_db_instance" has invalid engine.
64+
func (r *AwsDBInstanceInvalidEngineRule) Check(runner tflint.Runner) error {
65+
return runner.WalkResourceAttributes(r.resource, r.attributeName, func(attribute *hcl.Attribute) error {
66+
var engine string
67+
err := runner.EvaluateExpr(attribute.Expr, &engine, nil)
68+
69+
return runner.EnsureNoError(err, func() error {
70+
if !r.engines[engine] {
71+
runner.EmitIssueOnExpr(
72+
r,
73+
fmt.Sprintf("\"%s\" is invalid engine.", engine),
74+
attribute.Expr,
75+
)
76+
}
77+
return nil
78+
})
79+
})
80+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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_AwsDBInstanceInvalidEngine(t *testing.T) {
11+
cases := []struct {
12+
Name string
13+
Content string
14+
Expected helper.Issues
15+
}{
16+
{
17+
Name: "aurora-postgres is invalid",
18+
Content: `
19+
resource "aws_db_instance" "aurora_postgresql" {
20+
engine = "aurora-postgres"
21+
}`,
22+
Expected: helper.Issues{
23+
{
24+
Rule: NewAwsDBInstanceInvalidEngineRule(),
25+
Message: "\"aurora-postgres\" is invalid engine.",
26+
Range: hcl.Range{
27+
Filename: "resource.tf",
28+
Start: hcl.Pos{Line: 3, Column: 14},
29+
End: hcl.Pos{Line: 3, Column: 31},
30+
},
31+
},
32+
},
33+
},
34+
{
35+
Name: "aurora-postgresql is valid",
36+
Content: `
37+
resource "aws_db_instance" "aurora_postgresql" {
38+
engine = "aurora-postgresql"
39+
}`,
40+
Expected: helper.Issues{},
41+
},
42+
}
43+
44+
rule := NewAwsDBInstanceInvalidEngineRule()
45+
46+
for _, tc := range cases {
47+
runner := helper.TestRunner(t, map[string]string{"resource.tf": tc.Content})
48+
49+
if err := rule.Check(runner); err != nil {
50+
t.Fatalf("Unexpected error occurred: %s", err)
51+
}
52+
53+
helper.AssertIssues(t, tc.Expected, runner.Issues)
54+
}
55+
}

rules/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
// Rules is a list of all rules
99
var Rules = append([]tflint.Rule{
1010
NewAwsDBInstanceDefaultParameterGroupRule(),
11+
NewAwsDBInstanceInvalidEngineRule(),
1112
NewAwsDBInstanceInvalidTypeRule(),
1213
NewAwsDBInstancePreviousTypeRule(),
1314
NewAwsDynamoDBTableInvalidStreamViewTypeRule(),

0 commit comments

Comments
 (0)