github.com/subuk/terraform@v0.6.14-0.20160317140351-de1567c2e732/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_Issue5310(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: testAccAWSSecurityGroupRuleIssue5310, 356 Check: resource.ComposeTestCheckFunc( 357 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.issue_5310", &group), 358 ), 359 }, 360 }, 361 }) 362 } 363 364 func TestAccAWSSecurityGroupRule_Race(t *testing.T) { 365 var group ec2.SecurityGroup 366 367 resource.Test(t, resource.TestCase{ 368 PreCheck: func() { testAccPreCheck(t) }, 369 Providers: testAccProviders, 370 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 371 Steps: []resource.TestStep{ 372 resource.TestStep{ 373 Config: testAccAWSSecurityGroupRuleRace, 374 Check: resource.ComposeTestCheckFunc( 375 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.race", &group), 376 ), 377 }, 378 }, 379 }) 380 } 381 382 func testAccCheckAWSSecurityGroupRuleDestroy(s *terraform.State) error { 383 conn := testAccProvider.Meta().(*AWSClient).ec2conn 384 385 for _, rs := range s.RootModule().Resources { 386 if rs.Type != "aws_security_group" { 387 continue 388 } 389 390 // Retrieve our group 391 req := &ec2.DescribeSecurityGroupsInput{ 392 GroupIds: []*string{aws.String(rs.Primary.ID)}, 393 } 394 resp, err := conn.DescribeSecurityGroups(req) 395 if err == nil { 396 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID { 397 return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID) 398 } 399 400 return nil 401 } 402 403 ec2err, ok := err.(awserr.Error) 404 if !ok { 405 return err 406 } 407 // Confirm error code is what we want 408 if ec2err.Code() != "InvalidGroup.NotFound" { 409 return err 410 } 411 } 412 413 return nil 414 } 415 416 func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc { 417 return func(s *terraform.State) error { 418 rs, ok := s.RootModule().Resources[n] 419 if !ok { 420 return fmt.Errorf("Not found: %s", n) 421 } 422 423 if rs.Primary.ID == "" { 424 return fmt.Errorf("No Security Group is set") 425 } 426 427 conn := testAccProvider.Meta().(*AWSClient).ec2conn 428 req := &ec2.DescribeSecurityGroupsInput{ 429 GroupIds: []*string{aws.String(rs.Primary.ID)}, 430 } 431 resp, err := conn.DescribeSecurityGroups(req) 432 if err != nil { 433 return err 434 } 435 436 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID { 437 *group = *resp.SecurityGroups[0] 438 return nil 439 } 440 441 return fmt.Errorf("Security Group not found") 442 } 443 } 444 445 func testAccCheckAWSSecurityGroupRuleAttributes(n string, group *ec2.SecurityGroup, p *ec2.IpPermission, ruleType string) resource.TestCheckFunc { 446 return func(s *terraform.State) error { 447 rs, ok := s.RootModule().Resources[n] 448 if !ok { 449 return fmt.Errorf("Security Group Rule Not found: %s", n) 450 } 451 452 if rs.Primary.ID == "" { 453 return fmt.Errorf("No Security Group Rule is set") 454 } 455 456 if p == nil { 457 p = &ec2.IpPermission{ 458 FromPort: aws.Int64(80), 459 ToPort: aws.Int64(8000), 460 IpProtocol: aws.String("tcp"), 461 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("10.0.0.0/8")}}, 462 } 463 } 464 465 var matchingRule *ec2.IpPermission 466 var rules []*ec2.IpPermission 467 if ruleType == "ingress" { 468 rules = group.IpPermissions 469 } else { 470 rules = group.IpPermissionsEgress 471 } 472 473 if len(rules) == 0 { 474 return fmt.Errorf("No IPPerms") 475 } 476 477 for _, r := range rules { 478 if r.ToPort != nil && *p.ToPort != *r.ToPort { 479 continue 480 } 481 482 if r.FromPort != nil && *p.FromPort != *r.FromPort { 483 continue 484 } 485 486 if r.IpProtocol != nil && *p.IpProtocol != *r.IpProtocol { 487 continue 488 } 489 490 remaining := len(p.IpRanges) 491 for _, ip := range p.IpRanges { 492 for _, rip := range r.IpRanges { 493 if *ip.CidrIp == *rip.CidrIp { 494 remaining-- 495 } 496 } 497 } 498 499 if remaining > 0 { 500 continue 501 } 502 503 remaining = len(p.UserIdGroupPairs) 504 for _, ip := range p.UserIdGroupPairs { 505 for _, rip := range r.UserIdGroupPairs { 506 if *ip.GroupId == *rip.GroupId { 507 remaining-- 508 } 509 } 510 } 511 512 if remaining > 0 { 513 continue 514 } 515 matchingRule = r 516 } 517 518 if matchingRule != nil { 519 log.Printf("[DEBUG] Matching rule found : %s", matchingRule) 520 return nil 521 } 522 523 return fmt.Errorf("Error here\n\tlooking for %s, wasn't found in %s", p, rules) 524 } 525 } 526 527 const testAccAWSSecurityGroupRuleIngressConfig = ` 528 resource "aws_security_group" "web" { 529 name = "terraform_acceptance_test_example" 530 description = "Used in the terraform acceptance tests" 531 532 tags { 533 Name = "tf-acc-test" 534 } 535 } 536 537 resource "aws_security_group_rule" "ingress_1" { 538 type = "ingress" 539 protocol = "tcp" 540 from_port = 80 541 to_port = 8000 542 cidr_blocks = ["10.0.0.0/8"] 543 544 security_group_id = "${aws_security_group.web.id}" 545 } 546 ` 547 548 const testAccAWSSecurityGroupRuleIssue5310 = ` 549 provider "aws" { 550 region = "us-east-1" 551 } 552 553 resource "aws_security_group" "issue_5310" { 554 name = "terraform-test-issue_5310" 555 description = "SG for test of issue 5310" 556 } 557 558 resource "aws_security_group_rule" "issue_5310" { 559 type = "ingress" 560 from_port = 0 561 to_port = 65535 562 protocol = "tcp" 563 security_group_id = "${aws_security_group.issue_5310.id}" 564 self = true 565 } 566 ` 567 568 const testAccAWSSecurityGroupRuleIngressClassicConfig = ` 569 provider "aws" { 570 region = "us-east-1" 571 } 572 573 resource "aws_security_group" "web" { 574 name = "terraform_acceptance_test_example" 575 description = "Used in the terraform acceptance tests" 576 577 tags { 578 Name = "tf-acc-test" 579 } 580 } 581 582 resource "aws_security_group_rule" "ingress_1" { 583 type = "ingress" 584 protocol = "tcp" 585 from_port = 80 586 to_port = 8000 587 cidr_blocks = ["10.0.0.0/8"] 588 589 security_group_id = "${aws_security_group.web.id}" 590 } 591 ` 592 593 const testAccAWSSecurityGroupRuleEgressConfig = ` 594 resource "aws_security_group" "web" { 595 name = "terraform_acceptance_test_example" 596 description = "Used in the terraform acceptance tests" 597 598 tags { 599 Name = "tf-acc-test" 600 } 601 } 602 603 resource "aws_security_group_rule" "egress_1" { 604 type = "egress" 605 protocol = "tcp" 606 from_port = 80 607 to_port = 8000 608 cidr_blocks = ["10.0.0.0/8"] 609 610 security_group_id = "${aws_security_group.web.id}" 611 } 612 ` 613 614 const testAccAWSSecurityGroupRuleConfigMultiIngress = ` 615 resource "aws_security_group" "web" { 616 name = "terraform_acceptance_test_example_2" 617 description = "Used in the terraform acceptance tests" 618 } 619 620 resource "aws_security_group" "worker" { 621 name = "terraform_acceptance_test_example_worker" 622 description = "Used in the terraform acceptance tests" 623 } 624 625 626 resource "aws_security_group_rule" "ingress_1" { 627 type = "ingress" 628 protocol = "tcp" 629 from_port = 22 630 to_port = 22 631 cidr_blocks = ["10.0.0.0/8"] 632 633 security_group_id = "${aws_security_group.web.id}" 634 } 635 636 resource "aws_security_group_rule" "ingress_2" { 637 type = "ingress" 638 protocol = "tcp" 639 from_port = 80 640 to_port = 8000 641 self = true 642 643 security_group_id = "${aws_security_group.web.id}" 644 } 645 ` 646 647 // check for GH-1985 regression 648 const testAccAWSSecurityGroupRuleConfigSelfReference = ` 649 provider "aws" { 650 region = "us-west-2" 651 } 652 653 resource "aws_vpc" "main" { 654 cidr_block = "10.0.0.0/16" 655 tags { 656 Name = "sg-self-test" 657 } 658 } 659 660 resource "aws_security_group" "web" { 661 name = "main" 662 vpc_id = "${aws_vpc.main.id}" 663 tags { 664 Name = "sg-self-test" 665 } 666 } 667 668 resource "aws_security_group_rule" "self" { 669 type = "ingress" 670 protocol = "-1" 671 from_port = 0 672 to_port = 0 673 self = true 674 security_group_id = "${aws_security_group.web.id}" 675 } 676 ` 677 678 const testAccAWSSecurityGroupRulePartialMatching = ` 679 resource "aws_vpc" "default" { 680 cidr_block = "10.0.0.0/16" 681 tags { 682 Name = "tf-sg-rule-bug" 683 } 684 } 685 686 resource "aws_security_group" "web" { 687 name = "tf-other" 688 vpc_id = "${aws_vpc.default.id}" 689 tags { 690 Name = "tf-other-sg" 691 } 692 } 693 694 resource "aws_security_group" "nat" { 695 name = "tf-nat" 696 vpc_id = "${aws_vpc.default.id}" 697 tags { 698 Name = "tf-nat-sg" 699 } 700 } 701 702 resource "aws_security_group_rule" "ingress" { 703 type = "ingress" 704 from_port = 80 705 to_port = 80 706 protocol = "tcp" 707 cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] 708 709 security_group_id = "${aws_security_group.web.id}" 710 } 711 712 resource "aws_security_group_rule" "other" { 713 type = "ingress" 714 from_port = 80 715 to_port = 80 716 protocol = "tcp" 717 cidr_blocks = ["10.0.5.0/24"] 718 719 security_group_id = "${aws_security_group.web.id}" 720 } 721 722 // same a above, but different group, to guard against bad hashing 723 resource "aws_security_group_rule" "nat_ingress" { 724 type = "ingress" 725 from_port = 80 726 to_port = 80 727 protocol = "tcp" 728 cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] 729 730 security_group_id = "${aws_security_group.nat.id}" 731 } 732 ` 733 734 const testAccAWSSecurityGroupRulePartialMatching_Source = ` 735 resource "aws_vpc" "default" { 736 cidr_block = "10.0.0.0/16" 737 tags { 738 Name = "tf-sg-rule-bug" 739 } 740 } 741 742 resource "aws_security_group" "web" { 743 name = "tf-other" 744 vpc_id = "${aws_vpc.default.id}" 745 tags { 746 Name = "tf-other-sg" 747 } 748 } 749 750 resource "aws_security_group" "nat" { 751 name = "tf-nat" 752 vpc_id = "${aws_vpc.default.id}" 753 tags { 754 Name = "tf-nat-sg" 755 } 756 } 757 758 resource "aws_security_group_rule" "source_ingress" { 759 type = "ingress" 760 from_port = 80 761 to_port = 80 762 protocol = "tcp" 763 764 source_security_group_id = "${aws_security_group.nat.id}" 765 security_group_id = "${aws_security_group.web.id}" 766 } 767 768 resource "aws_security_group_rule" "other_ingress" { 769 type = "ingress" 770 from_port = 80 771 to_port = 80 772 protocol = "tcp" 773 cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] 774 775 security_group_id = "${aws_security_group.web.id}" 776 } 777 ` 778 779 var testAccAWSSecurityGroupRuleRace = func() string { 780 var b bytes.Buffer 781 iterations := 50 782 b.WriteString(fmt.Sprintf(` 783 resource "aws_vpc" "default" { 784 cidr_block = "10.0.0.0/16" 785 tags { Name = "tf-sg-rule-race" } 786 } 787 788 resource "aws_security_group" "race" { 789 name = "tf-sg-rule-race-group-%d" 790 vpc_id = "${aws_vpc.default.id}" 791 } 792 `, acctest.RandInt())) 793 for i := 1; i < iterations; i++ { 794 b.WriteString(fmt.Sprintf(` 795 resource "aws_security_group_rule" "ingress%d" { 796 security_group_id = "${aws_security_group.race.id}" 797 type = "ingress" 798 from_port = %d 799 to_port = %d 800 protocol = "tcp" 801 cidr_blocks = ["10.0.0.%d/32"] 802 } 803 804 resource "aws_security_group_rule" "egress%d" { 805 security_group_id = "${aws_security_group.race.id}" 806 type = "egress" 807 from_port = %d 808 to_port = %d 809 protocol = "tcp" 810 cidr_blocks = ["10.0.0.%d/32"] 811 } 812 `, i, i, i, i, i, i, i, i)) 813 } 814 return b.String() 815 }()