Skip to content

Commit

Permalink
Merge pull request #24 from wata727/aws_db_instance_invalid_parameter…
Browse files Browse the repository at this point in the history
…_group

add invalid parameter group detector for RDS
  • Loading branch information
wata727 committed Dec 18, 2016
2 parents 59633dc + 9cec8d3 commit b493f8d
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 7 deletions.
60 changes: 60 additions & 0 deletions detector/aws_db_instance_invalid_parameter_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package detector

import (
"fmt"

"github.com/aws/aws-sdk-go/service/rds"
"github.com/wata727/tflint/issue"
)

type AwsDBInstanceInvalidParameterGroupDetector struct {
*Detector
}

func (d *Detector) CreateAwsDBInstanceInvalidParameterGroupDetector() *AwsDBInstanceInvalidParameterGroupDetector {
return &AwsDBInstanceInvalidParameterGroupDetector{d}
}

func (d *AwsDBInstanceInvalidParameterGroupDetector) Detect(issues *[]*issue.Issue) {
if !d.isDeepCheck("resource", "aws_db_instance") {
return
}

validDBParameterGroups := map[string]bool{}
if d.ResponseCache.DescribeDBParameterGroupsOutput == nil {
resp, err := d.AwsClient.Rds.DescribeDBParameterGroups(&rds.DescribeDBParameterGroupsInput{})
if err != nil {
d.Logger.Error(err)
d.Error = true
}
d.ResponseCache.DescribeDBParameterGroupsOutput = resp
}
for _, parameterGroup := range d.ResponseCache.DescribeDBParameterGroupsOutput.DBParameterGroups {
validDBParameterGroups[*parameterGroup.DBParameterGroupName] = true
}

for filename, list := range d.ListMap {
for _, item := range list.Filter("resource", "aws_db_instance").Items {
parameterGroupToken, err := hclLiteralToken(item, "parameter_group_name")
if err != nil {
d.Logger.Error(err)
continue
}
parameterGroup, err := d.evalToString(parameterGroupToken.Text)
if err != nil {
d.Logger.Error(err)
continue
}

if !validDBParameterGroups[parameterGroup] {
issue := &issue.Issue{
Type: "ERROR",
Message: fmt.Sprintf("\"%s\" is invalid parameter group name.", parameterGroup),
Line: parameterGroupToken.Pos.Line,
File: filename,
}
*issues = append(*issues, issue)
}
}
}
}
92 changes: 92 additions & 0 deletions detector/aws_db_instance_invalid_parameter_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package detector

import (
"reflect"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/golang/mock/gomock"
"github.com/wata727/tflint/awsmock"
"github.com/wata727/tflint/config"
"github.com/wata727/tflint/issue"
)

func TestDetectAwsDBInstanceInvalidParameterGroup(t *testing.T) {
cases := []struct {
Name string
Src string
Response []*rds.DBParameterGroup
Issues []*issue.Issue
}{
{
Name: "parameter_group_name is invalid",
Src: `
resource "aws_db_instance" "mysql" {
parameter_group_name = "app-server"
}`,
Response: []*rds.DBParameterGroup{
&rds.DBParameterGroup{
DBParameterGroupName: aws.String("app-server1"),
},
&rds.DBParameterGroup{
DBParameterGroupName: aws.String("app-server2"),
},
},
Issues: []*issue.Issue{
&issue.Issue{
Type: "ERROR",
Message: "\"app-server\" is invalid parameter group name.",
Line: 3,
File: "test.tf",
},
},
},
{
Name: "parameter_group_name is valid",
Src: `
resource "aws_db_instance" "mysql" {
parameter_group_name = "app-server"
}`,
Response: []*rds.DBParameterGroup{
&rds.DBParameterGroup{
DBParameterGroupName: aws.String("app-server1"),
},
&rds.DBParameterGroup{
DBParameterGroupName: aws.String("app-server2"),
},
&rds.DBParameterGroup{
DBParameterGroupName: aws.String("app-server"),
},
},
Issues: []*issue.Issue{},
},
}

for _, tc := range cases {
c := config.Init()
c.DeepCheck = true

awsClient := c.NewAwsClient()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
rdsmock := awsmock.NewMockRDSAPI(ctrl)
rdsmock.EXPECT().DescribeDBParameterGroups(&rds.DescribeDBParameterGroupsInput{}).Return(&rds.DescribeDBParameterGroupsOutput{
DBParameterGroups: tc.Response,
}, nil)
awsClient.Rds = rdsmock

var issues = []*issue.Issue{}
TestDetectByCreatorName(
"CreateAwsDBInstanceInvalidParameterGroupDetector",
tc.Src,
c,
awsClient,
&issues,
)

if !reflect.DeepEqual(issues, tc.Issues) {
t.Fatalf("Bad: %s\nExpected: %s\n\ntestcase: %s", issues, tc.Issues, tc.Name)
}
}
}
1 change: 1 addition & 0 deletions detector/detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var detectors = map[string]string{
"aws_db_instance_default_parameter_group": "CreateAwsDBInstanceDefaultParameterGroupDetector",
"aws_db_instance_invalid_vpc_security_group": "CreateAwsDBInstanceInvalidVPCSecurityGroupDetector",
"aws_db_instance_invalid_db_subnet_group": "CreateAwsDBInstanceInvalidDBSubnetGroupDetector",
"aws_db_instance_invalid_parameter_group": "CreateAwsDBInstanceInvalidParameterGroupDetector",
"aws_elasticache_cluster_default_parameter_group": "CreateAwsElastiCacheClusterDefaultParameterGroupDetector",
"aws_instance_invalid_iam_profile": "CreateAwsInstanceInvalidIAMProfileDetector",
"aws_instance_invalid_ami": "CreateAwsInstanceInvalidAMIDetector",
Expand Down
15 changes: 8 additions & 7 deletions detector/response_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
)

type ResponseCache struct {
DescribeImagesOutput *ec2.DescribeImagesOutput
DescribeKeyPairsOutput *ec2.DescribeKeyPairsOutput
DescribeSubnetsOutput *ec2.DescribeSubnetsOutput
DescribeSecurityGroupsOutput *ec2.DescribeSecurityGroupsOutput
ListInstanceProfilesOutput *iam.ListInstanceProfilesOutput
DescribeInstancesOutput *ec2.DescribeInstancesOutput
DescribeDBSubnetGroupsOutput *rds.DescribeDBSubnetGroupsOutput
DescribeImagesOutput *ec2.DescribeImagesOutput
DescribeKeyPairsOutput *ec2.DescribeKeyPairsOutput
DescribeSubnetsOutput *ec2.DescribeSubnetsOutput
DescribeSecurityGroupsOutput *ec2.DescribeSecurityGroupsOutput
ListInstanceProfilesOutput *iam.ListInstanceProfilesOutput
DescribeInstancesOutput *ec2.DescribeInstancesOutput
DescribeDBSubnetGroupsOutput *rds.DescribeDBSubnetGroupsOutput
DescribeDBParameterGroupsOutput *rds.DescribeDBParameterGroupsOutput
}
37 changes: 37 additions & 0 deletions docs/AWS_DB_Instance_Invalid_Parameter_Group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# AWS DB Instance Invalid Parameter Group
Report this issue if you have specified the invalid DB subnet group name. This issue type is ERROR. This issue is enable only with deep check.

## Example
```
resource "aws_db_instance" "mysql" {
identifier = "app"
allocated_storage = 50
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7.11"
instance_class = "db.m4.large"
name = "app_db"
port = 3306
publicly_accessible = false
vpc_security_group_ids = ["sg-12345678"]
db_subnet_group_name = "app-subnet-group"
parameter_group_name = "invalid_parameter_group"
multi_az = true
}
```

The following is the execution result of TFLint:

```
$ tflint --deep
template.tf
ERROR:13 "invalid_parameter_group" is invalid parameter group name.
Result: 1 issues (1 errors , 0 warnings , 0 notices)
```

## Why
If an invalid parameter group name is specified, an error will occur at `terraform apply`.

## How to fix
Check your parameter groups and select a valid name again.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ Issues are classified into the following three types.
- [Default Parameter Group](AWS_DB_Instance_Default_Parameter_Group.md)
- [Invalid VPC Security Group](AWS_DB_Instance_Invalid_VPC_Security_Group.md)
- [Invalid DB Subnet Group](AWS_DB_Instance_Invalid_DB_Subnet_Group.md)
- [Invalid Parameter Group](AWS_DB_Instance_Invalid_Parameter_Group.md)
- AWS Elasticache Cluster
- [Default Parameter Group](AWS_Elasticache_Cluster_Default_Parameter_Group.md)

0 comments on commit b493f8d

Please sign in to comment.