github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_security_group_rule_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     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/resource"
    13  	"github.com/hashicorp/terraform/terraform"
    14  )
    15  
    16  func TestIpPermissionIDHash(t *testing.T) {
    17  	simple := &ec2.IpPermission{
    18  		IpProtocol: aws.String("tcp"),
    19  		FromPort:   aws.Int64(int64(80)),
    20  		ToPort:     aws.Int64(int64(8000)),
    21  		IpRanges: []*ec2.IpRange{
    22  			&ec2.IpRange{
    23  				CidrIp: aws.String("10.0.0.0/8"),
    24  			},
    25  		},
    26  	}
    27  
    28  	egress := &ec2.IpPermission{
    29  		IpProtocol: aws.String("tcp"),
    30  		FromPort:   aws.Int64(int64(80)),
    31  		ToPort:     aws.Int64(int64(8000)),
    32  		IpRanges: []*ec2.IpRange{
    33  			&ec2.IpRange{
    34  				CidrIp: aws.String("10.0.0.0/8"),
    35  			},
    36  		},
    37  	}
    38  
    39  	egress_all := &ec2.IpPermission{
    40  		IpProtocol: aws.String("-1"),
    41  		IpRanges: []*ec2.IpRange{
    42  			&ec2.IpRange{
    43  				CidrIp: aws.String("10.0.0.0/8"),
    44  			},
    45  		},
    46  	}
    47  
    48  	vpc_security_group_source := &ec2.IpPermission{
    49  		IpProtocol: aws.String("tcp"),
    50  		FromPort:   aws.Int64(int64(80)),
    51  		ToPort:     aws.Int64(int64(8000)),
    52  		UserIdGroupPairs: []*ec2.UserIdGroupPair{
    53  			&ec2.UserIdGroupPair{
    54  				UserId:  aws.String("987654321"),
    55  				GroupId: aws.String("sg-12345678"),
    56  			},
    57  			&ec2.UserIdGroupPair{
    58  				UserId:  aws.String("123456789"),
    59  				GroupId: aws.String("sg-987654321"),
    60  			},
    61  			&ec2.UserIdGroupPair{
    62  				UserId:  aws.String("123456789"),
    63  				GroupId: aws.String("sg-12345678"),
    64  			},
    65  		},
    66  	}
    67  
    68  	security_group_source := &ec2.IpPermission{
    69  		IpProtocol: aws.String("tcp"),
    70  		FromPort:   aws.Int64(int64(80)),
    71  		ToPort:     aws.Int64(int64(8000)),
    72  		UserIdGroupPairs: []*ec2.UserIdGroupPair{
    73  			&ec2.UserIdGroupPair{
    74  				UserId:    aws.String("987654321"),
    75  				GroupName: aws.String("my-security-group"),
    76  			},
    77  			&ec2.UserIdGroupPair{
    78  				UserId:    aws.String("123456789"),
    79  				GroupName: aws.String("my-security-group"),
    80  			},
    81  			&ec2.UserIdGroupPair{
    82  				UserId:    aws.String("123456789"),
    83  				GroupName: aws.String("my-other-security-group"),
    84  			},
    85  		},
    86  	}
    87  
    88  	// hardcoded hashes, to detect future change
    89  	cases := []struct {
    90  		Input  *ec2.IpPermission
    91  		Type   string
    92  		Output string
    93  	}{
    94  		{simple, "ingress", "sgrule-3403497314"},
    95  		{egress, "egress", "sgrule-1173186295"},
    96  		{egress_all, "egress", "sgrule-766323498"},
    97  		{vpc_security_group_source, "egress", "sgrule-351225364"},
    98  		{security_group_source, "egress", "sgrule-2198807188"},
    99  	}
   100  
   101  	for _, tc := range cases {
   102  		actual := ipPermissionIDHash("sg-12345", tc.Type, tc.Input)
   103  		if actual != tc.Output {
   104  			t.Errorf("input: %s - %s\noutput: %s", tc.Type, tc.Input, actual)
   105  		}
   106  	}
   107  }
   108  
   109  func TestAccAWSSecurityGroupRule_Ingress_VPC(t *testing.T) {
   110  	var group ec2.SecurityGroup
   111  
   112  	testRuleCount := func(*terraform.State) error {
   113  		if len(group.IpPermissions) != 1 {
   114  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   115  				1, len(group.IpPermissions))
   116  		}
   117  
   118  		rule := group.IpPermissions[0]
   119  		if *rule.FromPort != int64(80) {
   120  			return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
   121  				80, int(*rule.FromPort))
   122  		}
   123  
   124  		return nil
   125  	}
   126  
   127  	resource.Test(t, resource.TestCase{
   128  		PreCheck:     func() { testAccPreCheck(t) },
   129  		Providers:    testAccProviders,
   130  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   131  		Steps: []resource.TestStep{
   132  			resource.TestStep{
   133  				Config: testAccAWSSecurityGroupRuleIngressConfig,
   134  				Check: resource.ComposeTestCheckFunc(
   135  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   136  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress_1", &group, nil, "ingress"),
   137  					resource.TestCheckResourceAttr(
   138  						"aws_security_group_rule.ingress_1", "from_port", "80"),
   139  					testRuleCount,
   140  				),
   141  			},
   142  		},
   143  	})
   144  }
   145  
   146  func TestAccAWSSecurityGroupRule_Ingress_Classic(t *testing.T) {
   147  	var group ec2.SecurityGroup
   148  
   149  	testRuleCount := func(*terraform.State) error {
   150  		if len(group.IpPermissions) != 1 {
   151  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   152  				1, len(group.IpPermissions))
   153  		}
   154  
   155  		rule := group.IpPermissions[0]
   156  		if *rule.FromPort != int64(80) {
   157  			return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
   158  				80, int(*rule.FromPort))
   159  		}
   160  
   161  		return nil
   162  	}
   163  
   164  	resource.Test(t, resource.TestCase{
   165  		PreCheck:     func() { testAccPreCheck(t) },
   166  		Providers:    testAccProviders,
   167  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   168  		Steps: []resource.TestStep{
   169  			resource.TestStep{
   170  				Config: testAccAWSSecurityGroupRuleIngressClassicConfig,
   171  				Check: resource.ComposeTestCheckFunc(
   172  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   173  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress_1", &group, nil, "ingress"),
   174  					resource.TestCheckResourceAttr(
   175  						"aws_security_group_rule.ingress_1", "from_port", "80"),
   176  					testRuleCount,
   177  				),
   178  			},
   179  		},
   180  	})
   181  }
   182  
   183  func TestAccAWSSecurityGroupRule_MultiIngress(t *testing.T) {
   184  	var group ec2.SecurityGroup
   185  
   186  	testMultiRuleCount := func(*terraform.State) error {
   187  		if len(group.IpPermissions) != 2 {
   188  			return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
   189  				2, len(group.IpPermissions))
   190  		}
   191  
   192  		var rule *ec2.IpPermission
   193  		for _, r := range group.IpPermissions {
   194  			if *r.FromPort == int64(80) {
   195  				rule = r
   196  			}
   197  		}
   198  
   199  		if *rule.ToPort != int64(8000) {
   200  			return fmt.Errorf("Wrong Security Group port 2 setting, expected %d, got %d",
   201  				8000, int(*rule.ToPort))
   202  		}
   203  
   204  		return nil
   205  	}
   206  
   207  	resource.Test(t, resource.TestCase{
   208  		PreCheck:     func() { testAccPreCheck(t) },
   209  		Providers:    testAccProviders,
   210  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   211  		Steps: []resource.TestStep{
   212  			resource.TestStep{
   213  				Config: testAccAWSSecurityGroupRuleConfigMultiIngress,
   214  				Check: resource.ComposeTestCheckFunc(
   215  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   216  					testMultiRuleCount,
   217  				),
   218  			},
   219  		},
   220  	})
   221  }
   222  
   223  func TestAccAWSSecurityGroupRule_Egress(t *testing.T) {
   224  	var group ec2.SecurityGroup
   225  
   226  	resource.Test(t, resource.TestCase{
   227  		PreCheck:     func() { testAccPreCheck(t) },
   228  		Providers:    testAccProviders,
   229  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   230  		Steps: []resource.TestStep{
   231  			resource.TestStep{
   232  				Config: testAccAWSSecurityGroupRuleEgressConfig,
   233  				Check: resource.ComposeTestCheckFunc(
   234  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   235  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.egress_1", &group, nil, "egress"),
   236  				),
   237  			},
   238  		},
   239  	})
   240  }
   241  
   242  func TestAccAWSSecurityGroupRule_SelfReference(t *testing.T) {
   243  	var group ec2.SecurityGroup
   244  
   245  	resource.Test(t, resource.TestCase{
   246  		PreCheck:     func() { testAccPreCheck(t) },
   247  		Providers:    testAccProviders,
   248  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   249  		Steps: []resource.TestStep{
   250  			resource.TestStep{
   251  				Config: testAccAWSSecurityGroupRuleConfigSelfReference,
   252  				Check: resource.ComposeTestCheckFunc(
   253  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   254  				),
   255  			},
   256  		},
   257  	})
   258  }
   259  
   260  // testing partial match implementation
   261  func TestAccAWSSecurityGroupRule_PartialMatching_basic(t *testing.T) {
   262  	var group ec2.SecurityGroup
   263  
   264  	p := ec2.IpPermission{
   265  		FromPort:   aws.Int64(80),
   266  		ToPort:     aws.Int64(80),
   267  		IpProtocol: aws.String("tcp"),
   268  		IpRanges: []*ec2.IpRange{
   269  			&ec2.IpRange{CidrIp: aws.String("10.0.2.0/24")},
   270  			&ec2.IpRange{CidrIp: aws.String("10.0.3.0/24")},
   271  			&ec2.IpRange{CidrIp: aws.String("10.0.4.0/24")},
   272  		},
   273  	}
   274  
   275  	o := ec2.IpPermission{
   276  		FromPort:   aws.Int64(80),
   277  		ToPort:     aws.Int64(80),
   278  		IpProtocol: aws.String("tcp"),
   279  		IpRanges: []*ec2.IpRange{
   280  			&ec2.IpRange{CidrIp: aws.String("10.0.5.0/24")},
   281  		},
   282  	}
   283  
   284  	resource.Test(t, resource.TestCase{
   285  		PreCheck:     func() { testAccPreCheck(t) },
   286  		Providers:    testAccProviders,
   287  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   288  		Steps: []resource.TestStep{
   289  			resource.TestStep{
   290  				Config: testAccAWSSecurityGroupRulePartialMatching,
   291  				Check: resource.ComposeTestCheckFunc(
   292  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   293  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress", &group, &p, "ingress"),
   294  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.other", &group, &o, "ingress"),
   295  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.nat_ingress", &group, &o, "ingress"),
   296  				),
   297  			},
   298  		},
   299  	})
   300  }
   301  
   302  func TestAccAWSSecurityGroupRule_PartialMatching_Source(t *testing.T) {
   303  	var group ec2.SecurityGroup
   304  	var nat ec2.SecurityGroup
   305  	var p ec2.IpPermission
   306  
   307  	// This function creates the expected IPPermission with the group id from an
   308  	// external security group, needed because Security Group IDs are generated on
   309  	// AWS side and can't be known ahead of time.
   310  	setupSG := func(*terraform.State) error {
   311  		if nat.GroupId == nil {
   312  			return fmt.Errorf("Error: nat group has nil GroupID")
   313  		}
   314  
   315  		p = ec2.IpPermission{
   316  			FromPort:   aws.Int64(80),
   317  			ToPort:     aws.Int64(80),
   318  			IpProtocol: aws.String("tcp"),
   319  			UserIdGroupPairs: []*ec2.UserIdGroupPair{
   320  				&ec2.UserIdGroupPair{GroupId: nat.GroupId},
   321  			},
   322  		}
   323  
   324  		return nil
   325  	}
   326  
   327  	resource.Test(t, resource.TestCase{
   328  		PreCheck:     func() { testAccPreCheck(t) },
   329  		Providers:    testAccProviders,
   330  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   331  		Steps: []resource.TestStep{
   332  			resource.TestStep{
   333  				Config: testAccAWSSecurityGroupRulePartialMatching_Source,
   334  				Check: resource.ComposeTestCheckFunc(
   335  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
   336  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.nat", &nat),
   337  					setupSG,
   338  					testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.source_ingress", &group, &p, "ingress"),
   339  				),
   340  			},
   341  		},
   342  	})
   343  }
   344  
   345  func TestAccAWSSecurityGroupRule_Race(t *testing.T) {
   346  	var group ec2.SecurityGroup
   347  
   348  	resource.Test(t, resource.TestCase{
   349  		PreCheck:     func() { testAccPreCheck(t) },
   350  		Providers:    testAccProviders,
   351  		CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
   352  		Steps: []resource.TestStep{
   353  			resource.TestStep{
   354  				Config: testAccAWSSecurityGroupRuleRace,
   355  				Check: resource.ComposeTestCheckFunc(
   356  					testAccCheckAWSSecurityGroupRuleExists("aws_security_group.race", &group),
   357  				),
   358  			},
   359  		},
   360  	})
   361  }
   362  
   363  func testAccCheckAWSSecurityGroupRuleDestroy(s *terraform.State) error {
   364  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   365  
   366  	for _, rs := range s.RootModule().Resources {
   367  		if rs.Type != "aws_security_group" {
   368  			continue
   369  		}
   370  
   371  		// Retrieve our group
   372  		req := &ec2.DescribeSecurityGroupsInput{
   373  			GroupIds: []*string{aws.String(rs.Primary.ID)},
   374  		}
   375  		resp, err := conn.DescribeSecurityGroups(req)
   376  		if err == nil {
   377  			if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID {
   378  				return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID)
   379  			}
   380  
   381  			return nil
   382  		}
   383  
   384  		ec2err, ok := err.(awserr.Error)
   385  		if !ok {
   386  			return err
   387  		}
   388  		// Confirm error code is what we want
   389  		if ec2err.Code() != "InvalidGroup.NotFound" {
   390  			return err
   391  		}
   392  	}
   393  
   394  	return nil
   395  }
   396  
   397  func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc {
   398  	return func(s *terraform.State) error {
   399  		rs, ok := s.RootModule().Resources[n]
   400  		if !ok {
   401  			return fmt.Errorf("Not found: %s", n)
   402  		}
   403  
   404  		if rs.Primary.ID == "" {
   405  			return fmt.Errorf("No Security Group is set")
   406  		}
   407  
   408  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   409  		req := &ec2.DescribeSecurityGroupsInput{
   410  			GroupIds: []*string{aws.String(rs.Primary.ID)},
   411  		}
   412  		resp, err := conn.DescribeSecurityGroups(req)
   413  		if err != nil {
   414  			return err
   415  		}
   416  
   417  		if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID {
   418  			*group = *resp.SecurityGroups[0]
   419  			return nil
   420  		}
   421  
   422  		return fmt.Errorf("Security Group not found")
   423  	}
   424  }
   425  
   426  func testAccCheckAWSSecurityGroupRuleAttributes(n string, group *ec2.SecurityGroup, p *ec2.IpPermission, ruleType string) resource.TestCheckFunc {
   427  	return func(s *terraform.State) error {
   428  		rs, ok := s.RootModule().Resources[n]
   429  		if !ok {
   430  			return fmt.Errorf("Security Group Rule Not found: %s", n)
   431  		}
   432  
   433  		if rs.Primary.ID == "" {
   434  			return fmt.Errorf("No Security Group Rule is set")
   435  		}
   436  
   437  		if p == nil {
   438  			p = &ec2.IpPermission{
   439  				FromPort:   aws.Int64(80),
   440  				ToPort:     aws.Int64(8000),
   441  				IpProtocol: aws.String("tcp"),
   442  				IpRanges:   []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("10.0.0.0/8")}},
   443  			}
   444  		}
   445  
   446  		var matchingRule *ec2.IpPermission
   447  		var rules []*ec2.IpPermission
   448  		if ruleType == "ingress" {
   449  			rules = group.IpPermissions
   450  		} else {
   451  			rules = group.IpPermissionsEgress
   452  		}
   453  
   454  		if len(rules) == 0 {
   455  			return fmt.Errorf("No IPPerms")
   456  		}
   457  
   458  		for _, r := range rules {
   459  			if r.ToPort != nil && *p.ToPort != *r.ToPort {
   460  				continue
   461  			}
   462  
   463  			if r.FromPort != nil && *p.FromPort != *r.FromPort {
   464  				continue
   465  			}
   466  
   467  			if r.IpProtocol != nil && *p.IpProtocol != *r.IpProtocol {
   468  				continue
   469  			}
   470  
   471  			remaining := len(p.IpRanges)
   472  			for _, ip := range p.IpRanges {
   473  				for _, rip := range r.IpRanges {
   474  					if *ip.CidrIp == *rip.CidrIp {
   475  						remaining--
   476  					}
   477  				}
   478  			}
   479  
   480  			if remaining > 0 {
   481  				continue
   482  			}
   483  
   484  			remaining = len(p.UserIdGroupPairs)
   485  			for _, ip := range p.UserIdGroupPairs {
   486  				for _, rip := range r.UserIdGroupPairs {
   487  					if *ip.GroupId == *rip.GroupId {
   488  						remaining--
   489  					}
   490  				}
   491  			}
   492  
   493  			if remaining > 0 {
   494  				continue
   495  			}
   496  			matchingRule = r
   497  		}
   498  
   499  		if matchingRule != nil {
   500  			log.Printf("[DEBUG] Matching rule found : %s", matchingRule)
   501  			return nil
   502  		}
   503  
   504  		return fmt.Errorf("Error here\n\tlooking for %s, wasn't found in %s", p, rules)
   505  	}
   506  }
   507  
   508  const testAccAWSSecurityGroupRuleIngressConfig = `
   509  resource "aws_security_group" "web" {
   510    name = "terraform_acceptance_test_example"
   511    description = "Used in the terraform acceptance tests"
   512  
   513          tags {
   514                  Name = "tf-acc-test"
   515          }
   516  }
   517  
   518  resource "aws_security_group_rule" "ingress_1" {
   519    type = "ingress"
   520    protocol = "tcp"
   521    from_port = 80
   522    to_port = 8000
   523    cidr_blocks = ["10.0.0.0/8"]
   524  
   525    security_group_id = "${aws_security_group.web.id}"
   526  }
   527  `
   528  
   529  const testAccAWSSecurityGroupRuleIngressClassicConfig = `
   530  provider "aws" {
   531          region = "us-east-1"
   532  }
   533  
   534  resource "aws_security_group" "web" {
   535    name = "terraform_acceptance_test_example"
   536    description = "Used in the terraform acceptance tests"
   537  
   538          tags {
   539                  Name = "tf-acc-test"
   540          }
   541  }
   542  
   543  resource "aws_security_group_rule" "ingress_1" {
   544    type = "ingress"
   545    protocol = "tcp"
   546    from_port = 80
   547    to_port = 8000
   548    cidr_blocks = ["10.0.0.0/8"]
   549  
   550    security_group_id = "${aws_security_group.web.id}"
   551  }
   552  `
   553  
   554  const testAccAWSSecurityGroupRuleEgressConfig = `
   555  resource "aws_security_group" "web" {
   556    name = "terraform_acceptance_test_example"
   557    description = "Used in the terraform acceptance tests"
   558  
   559          tags {
   560                  Name = "tf-acc-test"
   561          }
   562  }
   563  
   564  resource "aws_security_group_rule" "egress_1" {
   565    type = "egress"
   566    protocol = "tcp"
   567    from_port = 80
   568    to_port = 8000
   569    cidr_blocks = ["10.0.0.0/8"]
   570  
   571    security_group_id = "${aws_security_group.web.id}"
   572  }
   573  `
   574  
   575  const testAccAWSSecurityGroupRuleConfigMultiIngress = `
   576  resource "aws_security_group" "web" {
   577    name = "terraform_acceptance_test_example_2"
   578    description = "Used in the terraform acceptance tests"
   579  }
   580  
   581  resource "aws_security_group" "worker" {
   582    name = "terraform_acceptance_test_example_worker"
   583    description = "Used in the terraform acceptance tests"
   584  }
   585  
   586  
   587  resource "aws_security_group_rule" "ingress_1" {
   588    type = "ingress"
   589    protocol = "tcp"
   590    from_port = 22
   591    to_port = 22
   592    cidr_blocks = ["10.0.0.0/8"]
   593  
   594    security_group_id = "${aws_security_group.web.id}"
   595  }
   596  
   597  resource "aws_security_group_rule" "ingress_2" {
   598    type = "ingress"
   599    protocol = "tcp"
   600    from_port = 80
   601    to_port = 8000
   602          self = true
   603  
   604    security_group_id = "${aws_security_group.web.id}"
   605  }
   606  `
   607  
   608  // check for GH-1985 regression
   609  const testAccAWSSecurityGroupRuleConfigSelfReference = `
   610  provider "aws" {
   611    region = "us-west-2"
   612  }
   613  
   614  resource "aws_vpc" "main" {
   615    cidr_block = "10.0.0.0/16"
   616    tags {
   617      Name = "sg-self-test"
   618    }
   619  }
   620  
   621  resource "aws_security_group" "web" {
   622    name = "main"
   623    vpc_id = "${aws_vpc.main.id}"
   624    tags {
   625      Name = "sg-self-test"
   626    }
   627  }
   628  
   629  resource "aws_security_group_rule" "self" {
   630    type = "ingress"
   631    protocol = "-1"
   632    from_port = 0
   633    to_port = 0
   634    self = true
   635    security_group_id = "${aws_security_group.web.id}"
   636  }
   637  `
   638  
   639  const testAccAWSSecurityGroupRulePartialMatching = `
   640  resource "aws_vpc" "default" {
   641    cidr_block = "10.0.0.0/16"
   642    tags {
   643      Name = "tf-sg-rule-bug"
   644    }
   645  }
   646  
   647  resource "aws_security_group" "web" {
   648      name = "tf-other"
   649      vpc_id = "${aws_vpc.default.id}"
   650      tags {
   651          Name        = "tf-other-sg"
   652      }
   653  }
   654  
   655  resource "aws_security_group" "nat" {
   656      name = "tf-nat"
   657      vpc_id = "${aws_vpc.default.id}"
   658      tags {
   659          Name        = "tf-nat-sg"
   660      }
   661  }
   662  
   663  resource "aws_security_group_rule" "ingress" {
   664      type        = "ingress"
   665      from_port   = 80
   666      to_port     = 80
   667      protocol    = "tcp"
   668      cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"]
   669  
   670     security_group_id = "${aws_security_group.web.id}"
   671  }
   672  
   673  resource "aws_security_group_rule" "other" {
   674      type        = "ingress"
   675      from_port   = 80
   676      to_port     = 80
   677      protocol    = "tcp"
   678      cidr_blocks = ["10.0.5.0/24"]
   679  
   680     security_group_id = "${aws_security_group.web.id}"
   681  }
   682  
   683  // same a above, but different group, to guard against bad hashing
   684  resource "aws_security_group_rule" "nat_ingress" {
   685      type        = "ingress"
   686      from_port   = 80
   687      to_port     = 80
   688      protocol    = "tcp"
   689      cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"]
   690  
   691     security_group_id = "${aws_security_group.nat.id}"
   692  }
   693  `
   694  
   695  const testAccAWSSecurityGroupRulePartialMatching_Source = `
   696  resource "aws_vpc" "default" {
   697    cidr_block = "10.0.0.0/16"
   698    tags {
   699      Name = "tf-sg-rule-bug"
   700    }
   701  }
   702  
   703  resource "aws_security_group" "web" {
   704      name = "tf-other"
   705      vpc_id = "${aws_vpc.default.id}"
   706      tags {
   707          Name        = "tf-other-sg"
   708      }
   709  }
   710  
   711  resource "aws_security_group" "nat" {
   712      name = "tf-nat"
   713      vpc_id = "${aws_vpc.default.id}"
   714      tags {
   715          Name        = "tf-nat-sg"
   716      }
   717  }
   718  
   719  resource "aws_security_group_rule" "source_ingress" {
   720      type        = "ingress"
   721      from_port   = 80
   722      to_port     = 80
   723      protocol    = "tcp"
   724  
   725                  source_security_group_id = "${aws_security_group.nat.id}"
   726     security_group_id = "${aws_security_group.web.id}"
   727  }
   728  
   729  resource "aws_security_group_rule" "other_ingress" {
   730      type        = "ingress"
   731      from_port   = 80
   732      to_port     = 80
   733      protocol    = "tcp"
   734      cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"]
   735  
   736     security_group_id = "${aws_security_group.web.id}"
   737  }
   738  `
   739  
   740  var testAccAWSSecurityGroupRuleRace = func() string {
   741  	var b bytes.Buffer
   742  	iterations := 50
   743  	b.WriteString(fmt.Sprintf(`
   744  		resource "aws_vpc" "default" {
   745  			cidr_block = "10.0.0.0/16"
   746  			tags { Name = "tf-sg-rule-race" }
   747  		}
   748  
   749  		resource "aws_security_group" "race" {
   750  			name   = "tf-sg-rule-race-group-%d"
   751  			vpc_id = "${aws_vpc.default.id}"
   752  		}
   753  	`, genRandInt()))
   754  	for i := 1; i < iterations; i++ {
   755  		b.WriteString(fmt.Sprintf(`
   756  			resource "aws_security_group_rule" "ingress%d" {
   757  				security_group_id = "${aws_security_group.race.id}"
   758  				type              = "ingress"
   759  				from_port         = %d
   760  				to_port           = %d
   761  				protocol          = "tcp"
   762  				cidr_blocks       = ["10.0.0.%d/32"]
   763  			}
   764  
   765  			resource "aws_security_group_rule" "egress%d" {
   766  				security_group_id = "${aws_security_group.race.id}"
   767  				type              = "egress"
   768  				from_port         = %d
   769  				to_port           = %d
   770  				protocol          = "tcp"
   771  				cidr_blocks       = ["10.0.0.%d/32"]
   772  			}
   773  		`, i, i, i, i, i, i, i, i))
   774  	}
   775  	return b.String()
   776  }()