github.com/mikesimons/terraform@v0.6.13-0.20160304043642-f11448c69214/builtin/providers/aws/resource_aws_security_group_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/ec2"
    12  	"github.com/hashicorp/terraform/helper/acctest"
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/helper/schema"
    15  	"github.com/hashicorp/terraform/terraform"
    16  )
    17  
    18  func TestResourceAwsSecurityGroupIPPermGather(t *testing.T) {
    19  	raw := []*ec2.IpPermission{
    20  		&ec2.IpPermission{
    21  			IpProtocol: aws.String("tcp"),
    22  			FromPort:   aws.Int64(int64(1)),
    23  			ToPort:     aws.Int64(int64(-1)),
    24  			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}},
    25  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
    26  				&ec2.UserIdGroupPair{
    27  					GroupId: aws.String("sg-22222"),
    28  				},
    29  			},
    30  		},
    31  		&ec2.IpPermission{
    32  			IpProtocol: aws.String("tcp"),
    33  			FromPort:   aws.Int64(int64(80)),
    34  			ToPort:     aws.Int64(int64(80)),
    35  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
    36  				&ec2.UserIdGroupPair{
    37  					GroupId: aws.String("foo"),
    38  				},
    39  			},
    40  		},
    41  	}
    42  
    43  	local := []map[string]interface{}{
    44  		map[string]interface{}{
    45  			"protocol":    "tcp",
    46  			"from_port":   int64(1),
    47  			"to_port":     int64(-1),
    48  			"cidr_blocks": []string{"0.0.0.0/0"},
    49  			"self":        true,
    50  		},
    51  		map[string]interface{}{
    52  			"protocol":  "tcp",
    53  			"from_port": int64(80),
    54  			"to_port":   int64(80),
    55  			"security_groups": schema.NewSet(schema.HashString, []interface{}{
    56  				"foo",
    57  			}),
    58  		},
    59  	}
    60  
    61  	out := resourceAwsSecurityGroupIPPermGather("sg-22222", raw)
    62  	for _, i := range out {
    63  		// loop and match rules, because the ordering is not guarneteed
    64  		for _, l := range local {
    65  			if i["from_port"] == l["from_port"] {
    66  
    67  				if i["to_port"] != l["to_port"] {
    68  					t.Fatalf("to_port does not match")
    69  				}
    70  
    71  				if _, ok := i["cidr_blocks"]; ok {
    72  					if !reflect.DeepEqual(i["cidr_blocks"], l["cidr_blocks"]) {
    73  						t.Fatalf("error matching cidr_blocks")
    74  					}
    75  				}
    76  
    77  				if _, ok := i["security_groups"]; ok {
    78  					outSet := i["security_groups"].(*schema.Set)
    79  					localSet := l["security_groups"].(*schema.Set)
    80  
    81  					if !outSet.Equal(localSet) {
    82  						t.Fatalf("Security Group sets are not equal")
    83  					}
    84  				}
    85  			}
    86  		}
    87  	}
    88  }
    89  
    90  func TestAccAWSSecurityGroup_basic(t *testing.T) {
    91  	var group ec2.SecurityGroup
    92  
    93  	resource.Test(t, resource.TestCase{
    94  		PreCheck:     func() { testAccPreCheck(t) },
    95  		Providers:    testAccProviders,
    96  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
    97  		Steps: []resource.TestStep{
    98  			resource.TestStep{
    99  				Config: testAccAWSSecurityGroupConfig,
   100  				Check: resource.ComposeTestCheckFunc(
   101  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   102  					testAccCheckAWSSecurityGroupAttributes(&group),
   103  					resource.TestCheckResourceAttr(
   104  						"aws_security_group.web", "name", "terraform_acceptance_test_example"),
   105  					resource.TestCheckResourceAttr(
   106  						"aws_security_group.web", "description", "Used in the terraform acceptance tests"),
   107  					resource.TestCheckResourceAttr(
   108  						"aws_security_group.web", "ingress.3629188364.protocol", "tcp"),
   109  					resource.TestCheckResourceAttr(
   110  						"aws_security_group.web", "ingress.3629188364.from_port", "80"),
   111  					resource.TestCheckResourceAttr(
   112  						"aws_security_group.web", "ingress.3629188364.to_port", "8000"),
   113  					resource.TestCheckResourceAttr(
   114  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.#", "1"),
   115  					resource.TestCheckResourceAttr(
   116  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.0", "10.0.0.0/8"),
   117  				),
   118  			},
   119  		},
   120  	})
   121  }
   122  
   123  func TestAccAWSSecurityGroup_namePrefix(t *testing.T) {
   124  	var group ec2.SecurityGroup
   125  
   126  	resource.Test(t, resource.TestCase{
   127  		PreCheck:     func() { testAccPreCheck(t) },
   128  		Providers:    testAccProviders,
   129  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   130  		Steps: []resource.TestStep{
   131  			resource.TestStep{
   132  				Config: testAccAWSSecurityGroupPrefixNameConfig,
   133  				Check: resource.ComposeTestCheckFunc(
   134  					testAccCheckAWSSecurityGroupExists("aws_security_group.baz", &group),
   135  					testAccCheckAWSSecurityGroupGeneratedNamePrefix(
   136  						"aws_security_group.baz", "baz-"),
   137  				),
   138  			},
   139  		},
   140  	})
   141  }
   142  
   143  func TestAccAWSSecurityGroup_self(t *testing.T) {
   144  	var group ec2.SecurityGroup
   145  
   146  	checkSelf := func(s *terraform.State) (err error) {
   147  		defer func() {
   148  			if e := recover(); e != nil {
   149  				err = fmt.Errorf("bad: %#v", group)
   150  			}
   151  		}()
   152  
   153  		if *group.IpPermissions[0].UserIdGroupPairs[0].GroupId != *group.GroupId {
   154  			return fmt.Errorf("bad: %#v", group)
   155  		}
   156  
   157  		return nil
   158  	}
   159  
   160  	resource.Test(t, resource.TestCase{
   161  		PreCheck:     func() { testAccPreCheck(t) },
   162  		Providers:    testAccProviders,
   163  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   164  		Steps: []resource.TestStep{
   165  			resource.TestStep{
   166  				Config: testAccAWSSecurityGroupConfigSelf,
   167  				Check: resource.ComposeTestCheckFunc(
   168  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   169  					resource.TestCheckResourceAttr(
   170  						"aws_security_group.web", "name", "terraform_acceptance_test_example"),
   171  					resource.TestCheckResourceAttr(
   172  						"aws_security_group.web", "description", "Used in the terraform acceptance tests"),
   173  					resource.TestCheckResourceAttr(
   174  						"aws_security_group.web", "ingress.3971148406.protocol", "tcp"),
   175  					resource.TestCheckResourceAttr(
   176  						"aws_security_group.web", "ingress.3971148406.from_port", "80"),
   177  					resource.TestCheckResourceAttr(
   178  						"aws_security_group.web", "ingress.3971148406.to_port", "8000"),
   179  					resource.TestCheckResourceAttr(
   180  						"aws_security_group.web", "ingress.3971148406.self", "true"),
   181  					checkSelf,
   182  				),
   183  			},
   184  		},
   185  	})
   186  }
   187  
   188  func TestAccAWSSecurityGroup_vpc(t *testing.T) {
   189  	var group ec2.SecurityGroup
   190  
   191  	testCheck := func(*terraform.State) error {
   192  		if *group.VpcId == "" {
   193  			return fmt.Errorf("should have vpc ID")
   194  		}
   195  
   196  		return nil
   197  	}
   198  
   199  	resource.Test(t, resource.TestCase{
   200  		PreCheck:     func() { testAccPreCheck(t) },
   201  		Providers:    testAccProviders,
   202  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   203  		Steps: []resource.TestStep{
   204  			resource.TestStep{
   205  				Config: testAccAWSSecurityGroupConfigVpc,
   206  				Check: resource.ComposeTestCheckFunc(
   207  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   208  					testAccCheckAWSSecurityGroupAttributes(&group),
   209  					resource.TestCheckResourceAttr(
   210  						"aws_security_group.web", "name", "terraform_acceptance_test_example"),
   211  					resource.TestCheckResourceAttr(
   212  						"aws_security_group.web", "description", "Used in the terraform acceptance tests"),
   213  					resource.TestCheckResourceAttr(
   214  						"aws_security_group.web", "ingress.3629188364.protocol", "tcp"),
   215  					resource.TestCheckResourceAttr(
   216  						"aws_security_group.web", "ingress.3629188364.from_port", "80"),
   217  					resource.TestCheckResourceAttr(
   218  						"aws_security_group.web", "ingress.3629188364.to_port", "8000"),
   219  					resource.TestCheckResourceAttr(
   220  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.#", "1"),
   221  					resource.TestCheckResourceAttr(
   222  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.0", "10.0.0.0/8"),
   223  					resource.TestCheckResourceAttr(
   224  						"aws_security_group.web", "egress.3629188364.protocol", "tcp"),
   225  					resource.TestCheckResourceAttr(
   226  						"aws_security_group.web", "egress.3629188364.from_port", "80"),
   227  					resource.TestCheckResourceAttr(
   228  						"aws_security_group.web", "egress.3629188364.to_port", "8000"),
   229  					resource.TestCheckResourceAttr(
   230  						"aws_security_group.web", "egress.3629188364.cidr_blocks.#", "1"),
   231  					resource.TestCheckResourceAttr(
   232  						"aws_security_group.web", "egress.3629188364.cidr_blocks.0", "10.0.0.0/8"),
   233  					testCheck,
   234  				),
   235  			},
   236  		},
   237  	})
   238  }
   239  
   240  func TestAccAWSSecurityGroup_vpcNegOneIngress(t *testing.T) {
   241  	var group ec2.SecurityGroup
   242  
   243  	testCheck := func(*terraform.State) error {
   244  		if *group.VpcId == "" {
   245  			return fmt.Errorf("should have vpc ID")
   246  		}
   247  
   248  		return nil
   249  	}
   250  
   251  	resource.Test(t, resource.TestCase{
   252  		PreCheck:     func() { testAccPreCheck(t) },
   253  		Providers:    testAccProviders,
   254  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   255  		Steps: []resource.TestStep{
   256  			resource.TestStep{
   257  				Config: testAccAWSSecurityGroupConfigVpcNegOneIngress,
   258  				Check: resource.ComposeTestCheckFunc(
   259  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   260  					testAccCheckAWSSecurityGroupAttributesNegOneProtocol(&group),
   261  					resource.TestCheckResourceAttr(
   262  						"aws_security_group.web", "name", "terraform_acceptance_test_example"),
   263  					resource.TestCheckResourceAttr(
   264  						"aws_security_group.web", "description", "Used in the terraform acceptance tests"),
   265  					resource.TestCheckResourceAttr(
   266  						"aws_security_group.web", "ingress.956249133.protocol", "-1"),
   267  					resource.TestCheckResourceAttr(
   268  						"aws_security_group.web", "ingress.956249133.from_port", "0"),
   269  					resource.TestCheckResourceAttr(
   270  						"aws_security_group.web", "ingress.956249133.to_port", "0"),
   271  					resource.TestCheckResourceAttr(
   272  						"aws_security_group.web", "ingress.956249133.cidr_blocks.#", "1"),
   273  					resource.TestCheckResourceAttr(
   274  						"aws_security_group.web", "ingress.956249133.cidr_blocks.0", "10.0.0.0/8"),
   275  					testCheck,
   276  				),
   277  			},
   278  		},
   279  	})
   280  }
   281  func TestAccAWSSecurityGroup_MultiIngress(t *testing.T) {
   282  	var group ec2.SecurityGroup
   283  
   284  	resource.Test(t, resource.TestCase{
   285  		PreCheck:     func() { testAccPreCheck(t) },
   286  		Providers:    testAccProviders,
   287  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   288  		Steps: []resource.TestStep{
   289  			resource.TestStep{
   290  				Config: testAccAWSSecurityGroupConfigMultiIngress,
   291  				Check: resource.ComposeTestCheckFunc(
   292  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   293  				),
   294  			},
   295  		},
   296  	})
   297  }
   298  
   299  func TestAccAWSSecurityGroup_Change(t *testing.T) {
   300  	var group ec2.SecurityGroup
   301  
   302  	resource.Test(t, resource.TestCase{
   303  		PreCheck:     func() { testAccPreCheck(t) },
   304  		Providers:    testAccProviders,
   305  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   306  		Steps: []resource.TestStep{
   307  			resource.TestStep{
   308  				Config: testAccAWSSecurityGroupConfig,
   309  				Check: resource.ComposeTestCheckFunc(
   310  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   311  				),
   312  			},
   313  			resource.TestStep{
   314  				Config: testAccAWSSecurityGroupConfigChange,
   315  				Check: resource.ComposeTestCheckFunc(
   316  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   317  					testAccCheckAWSSecurityGroupAttributesChanged(&group),
   318  				),
   319  			},
   320  		},
   321  	})
   322  }
   323  
   324  func TestAccAWSSecurityGroup_generatedName(t *testing.T) {
   325  	var group ec2.SecurityGroup
   326  
   327  	resource.Test(t, resource.TestCase{
   328  		PreCheck:     func() { testAccPreCheck(t) },
   329  		Providers:    testAccProviders,
   330  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   331  		Steps: []resource.TestStep{
   332  			resource.TestStep{
   333  				Config: testAccAWSSecurityGroupConfig_generatedName,
   334  				Check: resource.ComposeTestCheckFunc(
   335  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   336  					resource.TestCheckResourceAttr(
   337  						"aws_security_group.web", "description", "Managed by Terraform"),
   338  					func(s *terraform.State) error {
   339  						if group.GroupName == nil {
   340  							return fmt.Errorf("bad: No SG name")
   341  						}
   342  						if !strings.HasPrefix(*group.GroupName, "terraform-") {
   343  							return fmt.Errorf("No terraform- prefix: %s", *group.GroupName)
   344  						}
   345  						return nil
   346  					},
   347  				),
   348  			},
   349  		},
   350  	})
   351  }
   352  
   353  func TestAccAWSSecurityGroup_DefaultEgress(t *testing.T) {
   354  
   355  	// VPC
   356  	resource.Test(t, resource.TestCase{
   357  		PreCheck:     func() { testAccPreCheck(t) },
   358  		Providers:    testAccProviders,
   359  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   360  		Steps: []resource.TestStep{
   361  			resource.TestStep{
   362  				Config: testAccAWSSecurityGroupConfigDefaultEgress,
   363  				Check: resource.ComposeTestCheckFunc(
   364  					testAccCheckAWSSecurityGroupExistsWithoutDefault("aws_security_group.worker"),
   365  				),
   366  			},
   367  		},
   368  	})
   369  
   370  	// Classic
   371  	var group ec2.SecurityGroup
   372  	resource.Test(t, resource.TestCase{
   373  		PreCheck:     func() { testAccPreCheck(t) },
   374  		Providers:    testAccProviders,
   375  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   376  		Steps: []resource.TestStep{
   377  			resource.TestStep{
   378  				Config: testAccAWSSecurityGroupConfigClassic,
   379  				Check: resource.ComposeTestCheckFunc(
   380  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   381  				),
   382  			},
   383  		},
   384  	})
   385  }
   386  
   387  // Testing drift detection with groups containing the same port and types
   388  func TestAccAWSSecurityGroup_drift(t *testing.T) {
   389  	var group ec2.SecurityGroup
   390  	resource.Test(t, resource.TestCase{
   391  		PreCheck:     func() { testAccPreCheck(t) },
   392  		Providers:    testAccProviders,
   393  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   394  		Steps: []resource.TestStep{
   395  			resource.TestStep{
   396  				Config: testAccAWSSecurityGroupConfig_drift(),
   397  				Check: resource.ComposeTestCheckFunc(
   398  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   399  					resource.TestCheckResourceAttr(
   400  						"aws_security_group.web", "description", "Used in the terraform acceptance tests"),
   401  					resource.TestCheckResourceAttr(
   402  						"aws_security_group.web", "ingress.3629188364.protocol", "tcp"),
   403  					resource.TestCheckResourceAttr(
   404  						"aws_security_group.web", "ingress.3629188364.from_port", "80"),
   405  					resource.TestCheckResourceAttr(
   406  						"aws_security_group.web", "ingress.3629188364.to_port", "8000"),
   407  					resource.TestCheckResourceAttr(
   408  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.#", "1"),
   409  					resource.TestCheckResourceAttr(
   410  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.0", "10.0.0.0/8"),
   411  				),
   412  			},
   413  		},
   414  	})
   415  }
   416  
   417  func TestAccAWSSecurityGroup_drift_complex(t *testing.T) {
   418  	var group ec2.SecurityGroup
   419  
   420  	resource.Test(t, resource.TestCase{
   421  		PreCheck:     func() { testAccPreCheck(t) },
   422  		Providers:    testAccProviders,
   423  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   424  		Steps: []resource.TestStep{
   425  			resource.TestStep{
   426  				Config: testAccAWSSecurityGroupConfig_drift_complex(),
   427  				Check: resource.ComposeTestCheckFunc(
   428  					testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group),
   429  					resource.TestCheckResourceAttr(
   430  						"aws_security_group.web", "description", "Used in the terraform acceptance tests"),
   431  					resource.TestCheckResourceAttr(
   432  						"aws_security_group.web", "ingress.3629188364.protocol", "tcp"),
   433  					resource.TestCheckResourceAttr(
   434  						"aws_security_group.web", "ingress.3629188364.from_port", "80"),
   435  					resource.TestCheckResourceAttr(
   436  						"aws_security_group.web", "ingress.3629188364.to_port", "8000"),
   437  					resource.TestCheckResourceAttr(
   438  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.#", "1"),
   439  					resource.TestCheckResourceAttr(
   440  						"aws_security_group.web", "ingress.3629188364.cidr_blocks.0", "10.0.0.0/8"),
   441  				),
   442  			},
   443  		},
   444  	})
   445  }
   446  
   447  func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error {
   448  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   449  
   450  	for _, rs := range s.RootModule().Resources {
   451  		if rs.Type != "aws_security_group" {
   452  			continue
   453  		}
   454  
   455  		// Retrieve our group
   456  		req := &ec2.DescribeSecurityGroupsInput{
   457  			GroupIds: []*string{aws.String(rs.Primary.ID)},
   458  		}
   459  		resp, err := conn.DescribeSecurityGroups(req)
   460  		if err == nil {
   461  			if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID {
   462  				return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID)
   463  			}
   464  
   465  			return nil
   466  		}
   467  
   468  		ec2err, ok := err.(awserr.Error)
   469  		if !ok {
   470  			return err
   471  		}
   472  		// Confirm error code is what we want
   473  		if ec2err.Code() != "InvalidGroup.NotFound" {
   474  			return err
   475  		}
   476  	}
   477  
   478  	return nil
   479  }
   480  
   481  func testAccCheckAWSSecurityGroupGeneratedNamePrefix(
   482  	resource, prefix string) resource.TestCheckFunc {
   483  	return func(s *terraform.State) error {
   484  		r, ok := s.RootModule().Resources[resource]
   485  		if !ok {
   486  			return fmt.Errorf("Resource not found")
   487  		}
   488  		name, ok := r.Primary.Attributes["name"]
   489  		if !ok {
   490  			return fmt.Errorf("Name attr not found: %#v", r.Primary.Attributes)
   491  		}
   492  		if !strings.HasPrefix(name, prefix) {
   493  			return fmt.Errorf("Name: %q, does not have prefix: %q", name, prefix)
   494  		}
   495  		return nil
   496  	}
   497  }
   498  
   499  func testAccCheckAWSSecurityGroupExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc {
   500  	return func(s *terraform.State) error {
   501  		rs, ok := s.RootModule().Resources[n]
   502  		if !ok {
   503  			return fmt.Errorf("Not found: %s", n)
   504  		}
   505  
   506  		if rs.Primary.ID == "" {
   507  			return fmt.Errorf("No Security Group is set")
   508  		}
   509  
   510  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   511  		req := &ec2.DescribeSecurityGroupsInput{
   512  			GroupIds: []*string{aws.String(rs.Primary.ID)},
   513  		}
   514  		resp, err := conn.DescribeSecurityGroups(req)
   515  		if err != nil {
   516  			return err
   517  		}
   518  
   519  		if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID {
   520  			*group = *resp.SecurityGroups[0]
   521  			return nil
   522  		}
   523  
   524  		return fmt.Errorf("Security Group not found")
   525  	}
   526  }
   527  
   528  func testAccCheckAWSSecurityGroupAttributes(group *ec2.SecurityGroup) resource.TestCheckFunc {
   529  	return func(s *terraform.State) error {
   530  		p := &ec2.IpPermission{
   531  			FromPort:   aws.Int64(80),
   532  			ToPort:     aws.Int64(8000),
   533  			IpProtocol: aws.String("tcp"),
   534  			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("10.0.0.0/8")}},
   535  		}
   536  
   537  		if *group.GroupName != "terraform_acceptance_test_example" {
   538  			return fmt.Errorf("Bad name: %s", *group.GroupName)
   539  		}
   540  
   541  		if *group.Description != "Used in the terraform acceptance tests" {
   542  			return fmt.Errorf("Bad description: %s", *group.Description)
   543  		}
   544  
   545  		if len(group.IpPermissions) == 0 {
   546  			return fmt.Errorf("No IPPerms")
   547  		}
   548  
   549  		// Compare our ingress
   550  		if !reflect.DeepEqual(group.IpPermissions[0], p) {
   551  			return fmt.Errorf(
   552  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   553  				group.IpPermissions[0],
   554  				p)
   555  		}
   556  
   557  		return nil
   558  	}
   559  }
   560  
   561  func testAccCheckAWSSecurityGroupAttributesNegOneProtocol(group *ec2.SecurityGroup) resource.TestCheckFunc {
   562  	return func(s *terraform.State) error {
   563  		p := &ec2.IpPermission{
   564  			IpProtocol: aws.String("-1"),
   565  			IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("10.0.0.0/8")}},
   566  		}
   567  
   568  		if *group.GroupName != "terraform_acceptance_test_example" {
   569  			return fmt.Errorf("Bad name: %s", *group.GroupName)
   570  		}
   571  
   572  		if *group.Description != "Used in the terraform acceptance tests" {
   573  			return fmt.Errorf("Bad description: %s", *group.Description)
   574  		}
   575  
   576  		if len(group.IpPermissions) == 0 {
   577  			return fmt.Errorf("No IPPerms")
   578  		}
   579  
   580  		// Compare our ingress
   581  		if !reflect.DeepEqual(group.IpPermissions[0], p) {
   582  			return fmt.Errorf(
   583  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   584  				group.IpPermissions[0],
   585  				p)
   586  		}
   587  
   588  		return nil
   589  	}
   590  }
   591  
   592  func TestAccAWSSecurityGroup_tags(t *testing.T) {
   593  	var group ec2.SecurityGroup
   594  
   595  	resource.Test(t, resource.TestCase{
   596  		PreCheck:     func() { testAccPreCheck(t) },
   597  		Providers:    testAccProviders,
   598  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   599  		Steps: []resource.TestStep{
   600  			resource.TestStep{
   601  				Config: testAccAWSSecurityGroupConfigTags,
   602  				Check: resource.ComposeTestCheckFunc(
   603  					testAccCheckAWSSecurityGroupExists("aws_security_group.foo", &group),
   604  					testAccCheckTags(&group.Tags, "foo", "bar"),
   605  				),
   606  			},
   607  
   608  			resource.TestStep{
   609  				Config: testAccAWSSecurityGroupConfigTagsUpdate,
   610  				Check: resource.ComposeTestCheckFunc(
   611  					testAccCheckAWSSecurityGroupExists("aws_security_group.foo", &group),
   612  					testAccCheckTags(&group.Tags, "foo", ""),
   613  					testAccCheckTags(&group.Tags, "bar", "baz"),
   614  				),
   615  			},
   616  		},
   617  	})
   618  }
   619  
   620  func TestAccAWSSecurityGroup_CIDRandGroups(t *testing.T) {
   621  	var group ec2.SecurityGroup
   622  
   623  	resource.Test(t, resource.TestCase{
   624  		PreCheck:     func() { testAccPreCheck(t) },
   625  		Providers:    testAccProviders,
   626  		CheckDestroy: testAccCheckAWSSecurityGroupDestroy,
   627  		Steps: []resource.TestStep{
   628  			resource.TestStep{
   629  				Config: testAccAWSSecurityGroupCombindCIDRandGroups,
   630  				Check: resource.ComposeTestCheckFunc(
   631  					testAccCheckAWSSecurityGroupExists("aws_security_group.mixed", &group),
   632  					// testAccCheckAWSSecurityGroupAttributes(&group),
   633  				),
   634  			},
   635  		},
   636  	})
   637  }
   638  
   639  func testAccCheckAWSSecurityGroupAttributesChanged(group *ec2.SecurityGroup) resource.TestCheckFunc {
   640  	return func(s *terraform.State) error {
   641  		p := []*ec2.IpPermission{
   642  			&ec2.IpPermission{
   643  				FromPort:   aws.Int64(80),
   644  				ToPort:     aws.Int64(9000),
   645  				IpProtocol: aws.String("tcp"),
   646  				IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("10.0.0.0/8")}},
   647  			},
   648  			&ec2.IpPermission{
   649  				FromPort:   aws.Int64(80),
   650  				ToPort:     aws.Int64(8000),
   651  				IpProtocol: aws.String("tcp"),
   652  				IpRanges: []*ec2.IpRange{
   653  					&ec2.IpRange{
   654  						CidrIp: aws.String("0.0.0.0/0"),
   655  					},
   656  					&ec2.IpRange{
   657  						CidrIp: aws.String("10.0.0.0/8"),
   658  					},
   659  				},
   660  			},
   661  		}
   662  
   663  		if *group.GroupName != "terraform_acceptance_test_example" {
   664  			return fmt.Errorf("Bad name: %s", *group.GroupName)
   665  		}
   666  
   667  		if *group.Description != "Used in the terraform acceptance tests" {
   668  			return fmt.Errorf("Bad description: %s", *group.Description)
   669  		}
   670  
   671  		// Compare our ingress
   672  		if len(group.IpPermissions) != 2 {
   673  			return fmt.Errorf(
   674  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   675  				group.IpPermissions,
   676  				p)
   677  		}
   678  
   679  		if *group.IpPermissions[0].ToPort == 8000 {
   680  			group.IpPermissions[1], group.IpPermissions[0] =
   681  				group.IpPermissions[0], group.IpPermissions[1]
   682  		}
   683  
   684  		if !reflect.DeepEqual(group.IpPermissions, p) {
   685  			return fmt.Errorf(
   686  				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
   687  				group.IpPermissions,
   688  				p)
   689  		}
   690  
   691  		return nil
   692  	}
   693  }
   694  
   695  func testAccCheckAWSSecurityGroupExistsWithoutDefault(n string) resource.TestCheckFunc {
   696  	return func(s *terraform.State) error {
   697  		rs, ok := s.RootModule().Resources[n]
   698  		if !ok {
   699  			return fmt.Errorf("Not found: %s", n)
   700  		}
   701  
   702  		if rs.Primary.ID == "" {
   703  			return fmt.Errorf("No Security Group is set")
   704  		}
   705  
   706  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   707  		req := &ec2.DescribeSecurityGroupsInput{
   708  			GroupIds: []*string{aws.String(rs.Primary.ID)},
   709  		}
   710  		resp, err := conn.DescribeSecurityGroups(req)
   711  		if err != nil {
   712  			return err
   713  		}
   714  
   715  		if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID {
   716  			group := *resp.SecurityGroups[0]
   717  
   718  			if len(group.IpPermissionsEgress) != 1 {
   719  				return fmt.Errorf("Security Group should have only 1 egress rule, got %d", len(group.IpPermissionsEgress))
   720  			}
   721  		}
   722  
   723  		return nil
   724  	}
   725  }
   726  
   727  const testAccAWSSecurityGroupConfig = `
   728  resource "aws_security_group" "web" {
   729    name = "terraform_acceptance_test_example"
   730    description = "Used in the terraform acceptance tests"
   731  
   732    ingress {
   733      protocol = "tcp"
   734      from_port = 80
   735      to_port = 8000
   736      cidr_blocks = ["10.0.0.0/8"]
   737    }
   738  
   739    egress {
   740      protocol = "tcp"
   741      from_port = 80
   742      to_port = 8000
   743      cidr_blocks = ["10.0.0.0/8"]
   744    }
   745  
   746  	tags {
   747  		Name = "tf-acc-test"
   748  	}
   749  }
   750  `
   751  
   752  const testAccAWSSecurityGroupConfigChange = `
   753  resource "aws_security_group" "web" {
   754    name = "terraform_acceptance_test_example"
   755    description = "Used in the terraform acceptance tests"
   756  
   757    ingress {
   758      protocol = "tcp"
   759      from_port = 80
   760      to_port = 9000
   761      cidr_blocks = ["10.0.0.0/8"]
   762    }
   763  
   764    ingress {
   765      protocol = "tcp"
   766      from_port = 80
   767      to_port = 8000
   768      cidr_blocks = ["0.0.0.0/0", "10.0.0.0/8"]
   769    }
   770  
   771    egress {
   772      protocol = "tcp"
   773      from_port = 80
   774      to_port = 8000
   775      cidr_blocks = ["10.0.0.0/8"]
   776    }
   777  }
   778  `
   779  
   780  const testAccAWSSecurityGroupConfigSelf = `
   781  resource "aws_security_group" "web" {
   782    name = "terraform_acceptance_test_example"
   783    description = "Used in the terraform acceptance tests"
   784  
   785    ingress {
   786      protocol = "tcp"
   787      from_port = 80
   788      to_port = 8000
   789      self = true
   790    }
   791  
   792    egress {
   793      protocol = "tcp"
   794      from_port = 80
   795      to_port = 8000
   796      cidr_blocks = ["10.0.0.0/8"]
   797    }
   798  }
   799  `
   800  
   801  const testAccAWSSecurityGroupConfigVpc = `
   802  resource "aws_vpc" "foo" {
   803    cidr_block = "10.1.0.0/16"
   804  }
   805  
   806  resource "aws_security_group" "web" {
   807    name = "terraform_acceptance_test_example"
   808    description = "Used in the terraform acceptance tests"
   809    vpc_id = "${aws_vpc.foo.id}"
   810  
   811    ingress {
   812      protocol = "tcp"
   813      from_port = 80
   814      to_port = 8000
   815      cidr_blocks = ["10.0.0.0/8"]
   816    }
   817  
   818  	egress {
   819  		protocol = "tcp"
   820  		from_port = 80
   821  		to_port = 8000
   822  		cidr_blocks = ["10.0.0.0/8"]
   823  	}
   824  }
   825  `
   826  
   827  const testAccAWSSecurityGroupConfigVpcNegOneIngress = `
   828  resource "aws_vpc" "foo" {
   829  	cidr_block = "10.1.0.0/16"
   830  }
   831  
   832  resource "aws_security_group" "web" {
   833  	name = "terraform_acceptance_test_example"
   834  	description = "Used in the terraform acceptance tests"
   835  	vpc_id = "${aws_vpc.foo.id}"
   836  
   837  	ingress {
   838  		protocol = "-1"
   839  		from_port = 0
   840  		to_port = 0
   841  		cidr_blocks = ["10.0.0.0/8"]
   842  	}
   843  }
   844  `
   845  const testAccAWSSecurityGroupConfigMultiIngress = `
   846  resource "aws_security_group" "worker" {
   847    name = "terraform_acceptance_test_example_1"
   848    description = "Used in the terraform acceptance tests"
   849  
   850    ingress {
   851      protocol = "tcp"
   852      from_port = 80
   853      to_port = 8000
   854      cidr_blocks = ["10.0.0.0/8"]
   855    }
   856  
   857    egress {
   858      protocol = "tcp"
   859      from_port = 80
   860      to_port = 8000
   861      cidr_blocks = ["10.0.0.0/8"]
   862    }
   863  }
   864  
   865  resource "aws_security_group" "web" {
   866    name = "terraform_acceptance_test_example_2"
   867    description = "Used in the terraform acceptance tests"
   868  
   869    ingress {
   870      protocol = "tcp"
   871      from_port = 22
   872      to_port = 22
   873      cidr_blocks = ["10.0.0.0/8"]
   874    }
   875  
   876    ingress {
   877      protocol = "tcp"
   878      from_port = 800
   879      to_port = 800
   880      cidr_blocks = ["10.0.0.0/8"]
   881    }
   882  
   883    ingress {
   884      protocol = "tcp"
   885      from_port = 80
   886      to_port = 8000
   887      security_groups = ["${aws_security_group.worker.id}"]
   888    }
   889  
   890    egress {
   891      protocol = "tcp"
   892      from_port = 80
   893      to_port = 8000
   894      cidr_blocks = ["10.0.0.0/8"]
   895    }
   896  }
   897  `
   898  
   899  const testAccAWSSecurityGroupConfigTags = `
   900  resource "aws_security_group" "foo" {
   901  	name = "terraform_acceptance_test_example"
   902    description = "Used in the terraform acceptance tests"
   903  
   904    ingress {
   905      protocol = "tcp"
   906      from_port = 80
   907      to_port = 8000
   908      cidr_blocks = ["10.0.0.0/8"]
   909    }
   910  
   911    egress {
   912      protocol = "tcp"
   913      from_port = 80
   914      to_port = 8000
   915      cidr_blocks = ["10.0.0.0/8"]
   916    }
   917  
   918    tags {
   919      foo = "bar"
   920    }
   921  }
   922  `
   923  
   924  const testAccAWSSecurityGroupConfigTagsUpdate = `
   925  resource "aws_security_group" "foo" {
   926    name = "terraform_acceptance_test_example"
   927    description = "Used in the terraform acceptance tests"
   928  
   929    ingress {
   930      protocol = "tcp"
   931      from_port = 80
   932      to_port = 8000
   933      cidr_blocks = ["10.0.0.0/8"]
   934    }
   935  
   936    egress {
   937      protocol = "tcp"
   938      from_port = 80
   939      to_port = 8000
   940      cidr_blocks = ["10.0.0.0/8"]
   941    }
   942  
   943    tags {
   944      bar = "baz"
   945    }
   946  }
   947  `
   948  
   949  const testAccAWSSecurityGroupConfig_generatedName = `
   950  resource "aws_security_group" "web" {
   951    ingress {
   952      protocol = "tcp"
   953      from_port = 80
   954      to_port = 8000
   955      cidr_blocks = ["10.0.0.0/8"]
   956    }
   957  
   958    egress {
   959      protocol = "tcp"
   960      from_port = 80
   961      to_port = 8000
   962      cidr_blocks = ["10.0.0.0/8"]
   963    }
   964  
   965  	tags {
   966  		Name = "tf-acc-test"
   967  	}
   968  }
   969  `
   970  
   971  const testAccAWSSecurityGroupConfigDefaultEgress = `
   972  resource "aws_vpc" "tf_sg_egress_test" {
   973          cidr_block = "10.0.0.0/16"
   974          tags {
   975                  Name = "tf_sg_egress_test"
   976          }
   977  }
   978  
   979  resource "aws_security_group" "worker" {
   980    name = "terraform_acceptance_test_example_1"
   981    description = "Used in the terraform acceptance tests"
   982          vpc_id = "${aws_vpc.tf_sg_egress_test.id}"
   983  
   984    egress {
   985      protocol = "tcp"
   986      from_port = 80
   987      to_port = 8000
   988      cidr_blocks = ["10.0.0.0/8"]
   989    }
   990  }
   991  `
   992  
   993  const testAccAWSSecurityGroupConfigClassic = `
   994  provider "aws" {
   995    region = "us-east-1"
   996  }
   997  
   998  resource "aws_security_group" "web" {
   999    name = "terraform_acceptance_test_example_1"
  1000    description = "Used in the terraform acceptance tests"
  1001  }
  1002  `
  1003  
  1004  const testAccAWSSecurityGroupPrefixNameConfig = `
  1005  provider "aws" {
  1006    region = "us-east-1"
  1007  }
  1008  
  1009  resource "aws_security_group" "baz" {
  1010     name_prefix = "baz-"
  1011     description = "Used in the terraform acceptance tests"
  1012  }
  1013  `
  1014  
  1015  func testAccAWSSecurityGroupConfig_drift() string {
  1016  	return fmt.Sprintf(`
  1017  resource "aws_security_group" "web" {
  1018    name = "tf_acc_%d"
  1019    description = "Used in the terraform acceptance tests"
  1020  
  1021    ingress {
  1022      protocol = "tcp"
  1023      from_port = 80
  1024      to_port = 8000
  1025      cidr_blocks = ["10.0.0.0/8"]
  1026    }
  1027  
  1028    ingress {
  1029      protocol = "tcp"
  1030      from_port = 80
  1031      to_port = 8000
  1032      cidr_blocks = ["206.0.0.0/8"]
  1033    }
  1034  
  1035          tags {
  1036                  Name = "tf-acc-test"
  1037          }
  1038  }
  1039  `, acctest.RandInt())
  1040  }
  1041  
  1042  func testAccAWSSecurityGroupConfig_drift_complex() string {
  1043  	return fmt.Sprintf(`
  1044  resource "aws_security_group" "otherweb" {
  1045    name        = "tf_acc_%d"
  1046    description = "Used in the terraform acceptance tests"
  1047  }
  1048  
  1049  resource "aws_security_group" "web" {
  1050    name        = "tf_acc_%d"
  1051    description = "Used in the terraform acceptance tests"
  1052  
  1053    ingress {
  1054      protocol    = "tcp"
  1055      from_port   = 80
  1056      to_port     = 8000
  1057      cidr_blocks = ["10.0.0.0/8"]
  1058    }
  1059  
  1060    ingress {
  1061      protocol    = "tcp"
  1062      from_port   = 80
  1063      to_port     = 8000
  1064      cidr_blocks = ["206.0.0.0/8"]
  1065    }
  1066  
  1067    ingress {
  1068      protocol        = "tcp"
  1069      from_port       = 22
  1070      to_port         = 22
  1071      security_groups = ["${aws_security_group.otherweb.id}"]
  1072    }
  1073  
  1074    egress {
  1075      protocol    = "tcp"
  1076      from_port   = 80
  1077      to_port     = 8000
  1078      cidr_blocks = ["206.0.0.0/8"]
  1079    }
  1080  
  1081    egress {
  1082      protocol    = "tcp"
  1083      from_port   = 80
  1084      to_port     = 8000
  1085      cidr_blocks = ["10.0.0.0/8"]
  1086    }
  1087  
  1088    egress {
  1089      protocol        = "tcp"
  1090      from_port       = 22
  1091      to_port         = 22
  1092      security_groups = ["${aws_security_group.otherweb.id}"]
  1093    }
  1094  
  1095    tags {
  1096      Name = "tf-acc-test"
  1097    }
  1098  }`, acctest.RandInt(), acctest.RandInt())
  1099  }
  1100  
  1101  const testAccAWSSecurityGroupCombindCIDRandGroups = `
  1102  resource "aws_security_group" "two" {
  1103  	name = "tf-test-1"
  1104  	tags {
  1105  		Name = "tf-test-1"
  1106  	}
  1107  }
  1108  
  1109  resource "aws_security_group" "one" {
  1110  	name = "tf-test-2"
  1111  	tags {
  1112  		Name = "tf-test-w"
  1113  	}
  1114  }
  1115  
  1116  resource "aws_security_group" "three" {
  1117  	name = "tf-test-3"
  1118  	tags {
  1119  		Name = "tf-test-3"
  1120  	}
  1121  }
  1122  
  1123  resource "aws_security_group" "mixed" {
  1124    name = "tf-mix-test"
  1125  
  1126    ingress {
  1127      from_port   = 80
  1128      to_port     = 80
  1129      protocol    = "tcp"
  1130      cidr_blocks = ["10.0.0.0/16", "10.1.0.0/16", "10.7.0.0/16"]
  1131  
  1132      security_groups = [
  1133        "${aws_security_group.one.id}",
  1134        "${aws_security_group.two.id}",
  1135        "${aws_security_group.three.id}",
  1136      ]
  1137    }
  1138  
  1139    tags {
  1140      Name = "tf-mix-test"
  1141    }
  1142  }
  1143  `