Skip to content

Commit

Permalink
Merge pull request #12 from wata727/aws_instance_subnet_deep_detector
Browse files Browse the repository at this point in the history
add invalid subnet deep detector
  • Loading branch information
wata727 committed Dec 12, 2016
2 parents 59102e0 + 622adcf commit 81cfc00
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 0 deletions.
61 changes: 61 additions & 0 deletions detector/aws_instance_invalid_subnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package detector

import (
"fmt"

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

type AwsInstanceInvalidSubnetDetector struct {
*Detector
}

func (d *Detector) CreateAwsInstanceInvalidSubnetDetector() *AwsInstanceInvalidSubnetDetector {
return &AwsInstanceInvalidSubnetDetector{d}
}

func (d *AwsInstanceInvalidSubnetDetector) Detect(issues *[]*issue.Issue) {
if !d.Config.DeepCheck {
d.Logger.Info("skip this rule.")
return
}

validSubnets := map[string]bool{}
if d.ResponseCache.DescribeSubnetsOutput == nil {
resp, err := d.AwsClient.Ec2.DescribeSubnets(&ec2.DescribeSubnetsInput{})
if err != nil {
d.Logger.Error(err)
d.Error = true
}
d.ResponseCache.DescribeSubnetsOutput = resp
}
for _, subnet := range d.ResponseCache.DescribeSubnetsOutput.Subnets {
validSubnets[*subnet.SubnetId] = true
}

for filename, list := range d.ListMap {
for _, item := range list.Filter("resource", "aws_instance").Items {
subnetToken, err := hclLiteralToken(item, "subnet_id")
if err != nil {
d.Logger.Error(err)
continue
}
subnet, err := d.evalToString(subnetToken.Text)
if err != nil {
d.Logger.Error(err)
continue
}

if !validSubnets[subnet] {
issue := &issue.Issue{
Type: "ERROR",
Message: fmt.Sprintf("\"%s\" is invalid subnet ID.", subnet),
Line: subnetToken.Pos.Line,
File: filename,
}
*issues = append(*issues, issue)
}
}
}
}
89 changes: 89 additions & 0 deletions detector/aws_instance_invalid_subnet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package detector

import (
"reflect"
"testing"

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

func TestDetectAwsInstanceInvalidSubnet(t *testing.T) {
cases := []struct {
Name string
Src string
Response []*ec2.Subnet
Issues []*issue.Issue
}{
{
Name: "Subnet ID is invalid",
Src: `
resource "aws_instance" "web" {
subnet_id = "subnet-1234abcd"
}`,
Response: []*ec2.Subnet{
&ec2.Subnet{
SubnetId: aws.String("subnet-12345678"),
},
&ec2.Subnet{
SubnetId: aws.String("subnet-abcdefgh"),
},
},
Issues: []*issue.Issue{
&issue.Issue{
Type: "ERROR",
Message: "\"subnet-1234abcd\" is invalid subnet ID.",
Line: 3,
File: "test.tf",
},
},
},
{
Name: "key name is valid",
Src: `
resource "aws_instance" "web" {
subnet_id = "subnet-1234abcd"
}`,
Response: []*ec2.Subnet{
&ec2.Subnet{
SubnetId: aws.String("subnet-1234abcd"),
},
&ec2.Subnet{
SubnetId: aws.String("subnet-abcd1234"),
},
},
Issues: []*issue.Issue{},
},
}

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

awsClient := c.NewAwsClient()
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ec2mock := awsmock.NewMockEC2API(ctrl)
ec2mock.EXPECT().DescribeSubnets(&ec2.DescribeSubnetsInput{}).Return(&ec2.DescribeSubnetsOutput{
Subnets: tc.Response,
}, nil)
awsClient.Ec2 = ec2mock

var issues = []*issue.Issue{}
TestDetectByCreatorName(
"CreateAwsInstanceInvalidSubnetDetector",
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 @@ -33,6 +33,7 @@ var detectors = map[string]string{
"aws_instance_invalid_iam_profile": "CreateAwsInstanceInvalidIAMProfileDetector",
"aws_instance_invalid_ami": "CreateAwsInstanceInvalidAMIDetector",
"aws_instance_invalid_key_name": "CreateAwsInstanceInvalidKeyNameDetector",
"aws_instance_invalid_subnet": "CreateAwsInstanceInvalidSubnetDetector",
}

func NewDetector(listMap map[string]*ast.ObjectList, c *config.Config) (*Detector, error) {
Expand Down
1 change: 1 addition & 0 deletions detector/response_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ import (
type ResponseCache struct {
DescribeImagesOutput *ec2.DescribeImagesOutput
DescribeKeyPairsOutput *ec2.DescribeKeyPairsOutput
DescribeSubnetsOutput *ec2.DescribeSubnetsOutput
ListInstanceProfilesOutput *iam.ListInstanceProfilesOutput
}
33 changes: 33 additions & 0 deletions docs/AWS_Instance_Invalid_Subnet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# AWS Instance Invalid Subnet
Report this issue if you have specified the invalid subnet ID. This issue type is ERROR. This issue is enable only with deep check.

## Example
```
resource "aws_instance" "web" {
ami = "ami-1234abcd"
instance_type = "t2.micro"
iam_instance_profile = "app-user"
key_name = "secret"
subnet_id = "subnet-1234abcd" # This subnet ID does not exists
tags {
Name = "HelloWorld"
}
}
```

The following is the execution result of TFLint:

```
$ tflint --deep
template.tf
ERROR:6 "subnet-1234abcd" is invalid subnet ID.
Result: 1 issues (1 errors , 0 warnings , 0 notices)
```

## Why
If an invalid subnet ID is specified, an error will occur at `terraform apply`.

## How to fix
Check your subnets and select a valid subnet ID again.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Issues are classified into the following three types.
- [Default Standard Volume](AWS_Instance_Default_Standard_Volume.md)
- [Invalid AMI](AWS_Instance_Invalid_AMI.md)
- [Invalid Key Name](AWS_Instance_Invalid_Key_Name.md)
- [Invalid Subnet](AWS_Instance_Invalid_Subnet.md)
- AWS DB Instance
- [Default Parameter Group](AWS_DB_Instance_Default_Parameter_Group.md)
- AWS Elasticache Cluster
Expand Down

0 comments on commit 81cfc00

Please sign in to comment.