diff --git a/builtin/providers/aws/resource_aws_security_group_rule.go b/builtin/providers/aws/resource_aws_security_group_rule.go index 7a7034f98..e1de49803 100644 --- a/builtin/providers/aws/resource_aws_security_group_rule.go +++ b/builtin/providers/aws/resource_aws_security_group_rule.go @@ -110,6 +110,14 @@ func resourceAwsSecurityGroupRuleCreate(d *schema.ResourceData, meta interface{} return err } + // Verify that either 'cidr_blocks', 'self', or 'source_security_group_id' is set + // If they are not set the AWS API will silently fail. This causes TF to hit a timeout + // at 5-minutes waiting for the security group rule to appear, when it was never actually + // created. + if err := validateAwsSecurityGroupRule(d); err != nil { + return err + } + ruleType := d.Get("type").(string) isVPC := sg.VpcId != nil && *sg.VpcId != "" @@ -194,9 +202,8 @@ information and instructions for recovery. Error message: %s`, sg_id, awsErr.Mes }) if retErr != nil { - log.Printf("[DEBUG] Error finding matching %s Security Group Rule (%s) for Group %s -- NO STATE WILL BE SAVED", + return fmt.Errorf("Error finding matching %s Security Group Rule (%s) for Group %s", ruleType, id, sg_id) - return nil } d.SetId(id) @@ -595,3 +602,15 @@ func setFromIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup, rule *ec2.IpPe return nil } + +// Validates that either 'cidr_blocks', 'self', or 'source_security_group_id' is set +func validateAwsSecurityGroupRule(d *schema.ResourceData) error { + _, blocksOk := d.GetOk("cidr_blocks") + _, sourceOk := d.GetOk("source_security_group_id") + _, selfOk := d.GetOk("self") + if !blocksOk && !sourceOk && !selfOk { + return fmt.Errorf( + "One of ['cidr_blocks', 'self', 'source_security_group_id'] must be set to create an AWS Security Group Rule") + } + return nil +}