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