github.com/wata727/tflint@v0.12.2-0.20191013070026-96dd0d36f385/rules/awsrules/aws_launch_configuration_invalid_image_id.go (about) 1 package awsrules 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/awserr" 9 "github.com/aws/aws-sdk-go/service/ec2" 10 hcl "github.com/hashicorp/hcl/v2" 11 "github.com/wata727/tflint/tflint" 12 ) 13 14 // AwsLaunchConfigurationInvalidImageIDRule checks whether "aws_instance" has invalid AMI ID 15 type AwsLaunchConfigurationInvalidImageIDRule struct { 16 resourceType string 17 attributeName string 18 amiIDs map[string]bool 19 } 20 21 // NewAwsLaunchConfigurationInvalidImageIDRule returns new rule with default attributes 22 func NewAwsLaunchConfigurationInvalidImageIDRule() *AwsLaunchConfigurationInvalidImageIDRule { 23 return &AwsLaunchConfigurationInvalidImageIDRule{ 24 resourceType: "aws_launch_configuration", 25 attributeName: "image_id", 26 amiIDs: map[string]bool{}, 27 } 28 } 29 30 // Name returns the rule name 31 func (r *AwsLaunchConfigurationInvalidImageIDRule) Name() string { 32 return "aws_launch_configuration_invalid_image_id" 33 } 34 35 // Enabled returns whether the rule is enabled by default 36 func (r *AwsLaunchConfigurationInvalidImageIDRule) Enabled() bool { 37 return true 38 } 39 40 // Severity returns the rule severity 41 func (r *AwsLaunchConfigurationInvalidImageIDRule) Severity() string { 42 return tflint.ERROR 43 } 44 45 // Link returns the rule reference link 46 func (r *AwsLaunchConfigurationInvalidImageIDRule) Link() string { 47 return "" 48 } 49 50 // Check checks whether "aws_instance" has invalid AMI ID 51 func (r *AwsLaunchConfigurationInvalidImageIDRule) Check(runner *tflint.Runner) error { 52 log.Printf("[TRACE] Check `%s` rule for `%s` runner", r.Name(), runner.TFConfigPath()) 53 54 return runner.WalkResourceAttributes(r.resourceType, r.attributeName, func(attribute *hcl.Attribute) error { 55 var ami string 56 err := runner.EvaluateExpr(attribute.Expr, &ami) 57 58 return runner.EnsureNoError(err, func() error { 59 if !r.amiIDs[ami] { 60 log.Printf("[DEBUG] Fetch AMI images: %s", ami) 61 resp, err := runner.AwsClient.EC2.DescribeImages(&ec2.DescribeImagesInput{ 62 ImageIds: aws.StringSlice([]string{ami}), 63 }) 64 if err != nil { 65 if aerr, ok := err.(awserr.Error); ok { 66 switch aerr.Code() { 67 case "InvalidAMIID.Malformed": 68 fallthrough 69 case "InvalidAMIID.NotFound": 70 fallthrough 71 case "InvalidAMIID.Unavailable": 72 runner.EmitIssue( 73 r, 74 fmt.Sprintf("\"%s\" is invalid image ID.", ami), 75 attribute.Expr.Range(), 76 ) 77 return nil 78 } 79 } 80 err := &tflint.Error{ 81 Code: tflint.ExternalAPIError, 82 Level: tflint.ErrorLevel, 83 Message: "An error occurred while describing images", 84 Cause: err, 85 } 86 log.Printf("[ERROR] %s", err) 87 return err 88 } 89 90 if len(resp.Images) != 0 { 91 for _, image := range resp.Images { 92 r.amiIDs[*image.ImageId] = true 93 } 94 } else { 95 runner.EmitIssue( 96 r, 97 fmt.Sprintf("\"%s\" is invalid image ID.", ami), 98 attribute.Expr.Range(), 99 ) 100 } 101 } 102 return nil 103 }) 104 }) 105 }