github.com/peterbale/terraform@v0.9.0-beta2.0.20170315142748-5723acd55547/builtin/providers/aws/resource_aws_security_group_rule_test.go (about) 1 package aws 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "regexp" 8 "testing" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/aws/awserr" 12 "github.com/aws/aws-sdk-go/service/ec2" 13 "github.com/hashicorp/terraform/helper/acctest" 14 "github.com/hashicorp/terraform/helper/resource" 15 "github.com/hashicorp/terraform/terraform" 16 ) 17 18 func TestIpPermissionIDHash(t *testing.T) { 19 simple := &ec2.IpPermission{ 20 IpProtocol: aws.String("tcp"), 21 FromPort: aws.Int64(int64(80)), 22 ToPort: aws.Int64(int64(8000)), 23 IpRanges: []*ec2.IpRange{ 24 { 25 CidrIp: aws.String("10.0.0.0/8"), 26 }, 27 }, 28 } 29 30 egress := &ec2.IpPermission{ 31 IpProtocol: aws.String("tcp"), 32 FromPort: aws.Int64(int64(80)), 33 ToPort: aws.Int64(int64(8000)), 34 IpRanges: []*ec2.IpRange{ 35 { 36 CidrIp: aws.String("10.0.0.0/8"), 37 }, 38 }, 39 } 40 41 egress_all := &ec2.IpPermission{ 42 IpProtocol: aws.String("-1"), 43 IpRanges: []*ec2.IpRange{ 44 { 45 CidrIp: aws.String("10.0.0.0/8"), 46 }, 47 }, 48 } 49 50 vpc_security_group_source := &ec2.IpPermission{ 51 IpProtocol: aws.String("tcp"), 52 FromPort: aws.Int64(int64(80)), 53 ToPort: aws.Int64(int64(8000)), 54 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 55 { 56 UserId: aws.String("987654321"), 57 GroupId: aws.String("sg-12345678"), 58 }, 59 { 60 UserId: aws.String("123456789"), 61 GroupId: aws.String("sg-987654321"), 62 }, 63 { 64 UserId: aws.String("123456789"), 65 GroupId: aws.String("sg-12345678"), 66 }, 67 }, 68 } 69 70 security_group_source := &ec2.IpPermission{ 71 IpProtocol: aws.String("tcp"), 72 FromPort: aws.Int64(int64(80)), 73 ToPort: aws.Int64(int64(8000)), 74 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 75 { 76 UserId: aws.String("987654321"), 77 GroupName: aws.String("my-security-group"), 78 }, 79 { 80 UserId: aws.String("123456789"), 81 GroupName: aws.String("my-security-group"), 82 }, 83 { 84 UserId: aws.String("123456789"), 85 GroupName: aws.String("my-other-security-group"), 86 }, 87 }, 88 } 89 90 // hardcoded hashes, to detect future change 91 cases := []struct { 92 Input *ec2.IpPermission 93 Type string 94 Output string 95 }{ 96 {simple, "ingress", "sgrule-3403497314"}, 97 {egress, "egress", "sgrule-1173186295"}, 98 {egress_all, "egress", "sgrule-766323498"}, 99 {vpc_security_group_source, "egress", "sgrule-351225364"}, 100 {security_group_source, "egress", "sgrule-2198807188"}, 101 } 102 103 for _, tc := range cases { 104 actual := ipPermissionIDHash("sg-12345", tc.Type, tc.Input) 105 if actual != tc.Output { 106 t.Errorf("input: %s - %s\noutput: %s", tc.Type, tc.Input, actual) 107 } 108 } 109 } 110 111 func TestAccAWSSecurityGroupRule_Ingress_VPC(t *testing.T) { 112 var group ec2.SecurityGroup 113 rInt := acctest.RandInt() 114 115 testRuleCount := func(*terraform.State) error { 116 if len(group.IpPermissions) != 1 { 117 return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d", 118 1, len(group.IpPermissions)) 119 } 120 121 rule := group.IpPermissions[0] 122 if *rule.FromPort != int64(80) { 123 return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d", 124 80, int(*rule.FromPort)) 125 } 126 127 return nil 128 } 129 130 resource.Test(t, resource.TestCase{ 131 PreCheck: func() { testAccPreCheck(t) }, 132 Providers: testAccProviders, 133 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 134 Steps: []resource.TestStep{ 135 { 136 Config: testAccAWSSecurityGroupRuleIngressConfig(rInt), 137 Check: resource.ComposeTestCheckFunc( 138 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 139 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress_1", &group, nil, "ingress"), 140 resource.TestCheckResourceAttr( 141 "aws_security_group_rule.ingress_1", "from_port", "80"), 142 testRuleCount, 143 ), 144 }, 145 }, 146 }) 147 } 148 149 func TestAccAWSSecurityGroupRule_Ingress_Protocol(t *testing.T) { 150 var group ec2.SecurityGroup 151 152 testRuleCount := func(*terraform.State) error { 153 if len(group.IpPermissions) != 1 { 154 return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d", 155 1, len(group.IpPermissions)) 156 } 157 158 rule := group.IpPermissions[0] 159 if *rule.FromPort != int64(80) { 160 return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d", 161 80, int(*rule.FromPort)) 162 } 163 164 return nil 165 } 166 167 resource.Test(t, resource.TestCase{ 168 PreCheck: func() { testAccPreCheck(t) }, 169 Providers: testAccProviders, 170 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 171 Steps: []resource.TestStep{ 172 { 173 Config: testAccAWSSecurityGroupRuleIngress_protocolConfig, 174 Check: resource.ComposeTestCheckFunc( 175 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 176 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress_1", &group, nil, "ingress"), 177 resource.TestCheckResourceAttr( 178 "aws_security_group_rule.ingress_1", "from_port", "80"), 179 testRuleCount, 180 ), 181 }, 182 }, 183 }) 184 } 185 186 func TestAccAWSSecurityGroupRule_Ingress_Ipv6(t *testing.T) { 187 var group ec2.SecurityGroup 188 189 testRuleCount := func(*terraform.State) error { 190 if len(group.IpPermissions) != 1 { 191 return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d", 192 1, len(group.IpPermissions)) 193 } 194 195 rule := group.IpPermissions[0] 196 if *rule.FromPort != int64(80) { 197 return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d", 198 80, int(*rule.FromPort)) 199 } 200 201 ipv6Address := rule.Ipv6Ranges[0] 202 if *ipv6Address.CidrIpv6 != "::/0" { 203 return fmt.Errorf("Wrong Security Group IPv6 address, expected %s, got %s", 204 "::/0", *ipv6Address.CidrIpv6) 205 } 206 207 return nil 208 } 209 210 resource.Test(t, resource.TestCase{ 211 PreCheck: func() { testAccPreCheck(t) }, 212 Providers: testAccProviders, 213 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 214 Steps: []resource.TestStep{ 215 { 216 Config: testAccAWSSecurityGroupRuleIngress_ipv6Config, 217 Check: resource.ComposeTestCheckFunc( 218 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 219 testRuleCount, 220 ), 221 }, 222 }, 223 }) 224 } 225 226 func TestAccAWSSecurityGroupRule_Ingress_Classic(t *testing.T) { 227 var group ec2.SecurityGroup 228 rInt := acctest.RandInt() 229 230 testRuleCount := func(*terraform.State) error { 231 if len(group.IpPermissions) != 1 { 232 return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d", 233 1, len(group.IpPermissions)) 234 } 235 236 rule := group.IpPermissions[0] 237 if *rule.FromPort != int64(80) { 238 return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d", 239 80, int(*rule.FromPort)) 240 } 241 242 return nil 243 } 244 245 resource.Test(t, resource.TestCase{ 246 PreCheck: func() { testAccPreCheck(t) }, 247 Providers: testAccProviders, 248 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 249 Steps: []resource.TestStep{ 250 { 251 Config: testAccAWSSecurityGroupRuleIngressClassicConfig(rInt), 252 Check: resource.ComposeTestCheckFunc( 253 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 254 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress_1", &group, nil, "ingress"), 255 resource.TestCheckResourceAttr( 256 "aws_security_group_rule.ingress_1", "from_port", "80"), 257 testRuleCount, 258 ), 259 }, 260 }, 261 }) 262 } 263 264 func TestAccAWSSecurityGroupRule_MultiIngress(t *testing.T) { 265 var group ec2.SecurityGroup 266 267 testMultiRuleCount := func(*terraform.State) error { 268 if len(group.IpPermissions) != 2 { 269 return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d", 270 2, len(group.IpPermissions)) 271 } 272 273 var rule *ec2.IpPermission 274 for _, r := range group.IpPermissions { 275 if *r.FromPort == int64(80) { 276 rule = r 277 } 278 } 279 280 if *rule.ToPort != int64(8000) { 281 return fmt.Errorf("Wrong Security Group port 2 setting, expected %d, got %d", 282 8000, int(*rule.ToPort)) 283 } 284 285 return nil 286 } 287 288 resource.Test(t, resource.TestCase{ 289 PreCheck: func() { testAccPreCheck(t) }, 290 Providers: testAccProviders, 291 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 292 Steps: []resource.TestStep{ 293 { 294 Config: testAccAWSSecurityGroupRuleConfigMultiIngress, 295 Check: resource.ComposeTestCheckFunc( 296 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 297 testMultiRuleCount, 298 ), 299 }, 300 }, 301 }) 302 } 303 304 func TestAccAWSSecurityGroupRule_Egress(t *testing.T) { 305 var group ec2.SecurityGroup 306 rInt := acctest.RandInt() 307 308 resource.Test(t, resource.TestCase{ 309 PreCheck: func() { testAccPreCheck(t) }, 310 Providers: testAccProviders, 311 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 312 Steps: []resource.TestStep{ 313 { 314 Config: testAccAWSSecurityGroupRuleEgressConfig(rInt), 315 Check: resource.ComposeTestCheckFunc( 316 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 317 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.egress_1", &group, nil, "egress"), 318 ), 319 }, 320 }, 321 }) 322 } 323 324 func TestAccAWSSecurityGroupRule_SelfReference(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: testAccCheckAWSSecurityGroupRuleDestroy, 331 Steps: []resource.TestStep{ 332 { 333 Config: testAccAWSSecurityGroupRuleConfigSelfReference, 334 Check: resource.ComposeTestCheckFunc( 335 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 336 ), 337 }, 338 }, 339 }) 340 } 341 342 func TestAccAWSSecurityGroupRule_ExpectInvalidTypeError(t *testing.T) { 343 rInt := acctest.RandInt() 344 resource.Test(t, resource.TestCase{ 345 PreCheck: func() { testAccPreCheck(t) }, 346 Providers: testAccProviders, 347 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 348 Steps: []resource.TestStep{ 349 { 350 Config: testAccAWSSecurityGroupRuleExpectInvalidType(rInt), 351 ExpectError: regexp.MustCompile(`\\"type\\" contains an invalid Security Group Rule type \\"foobar\\"`), 352 }, 353 }, 354 }) 355 } 356 357 // testing partial match implementation 358 func TestAccAWSSecurityGroupRule_PartialMatching_basic(t *testing.T) { 359 var group ec2.SecurityGroup 360 rInt := acctest.RandInt() 361 362 p := ec2.IpPermission{ 363 FromPort: aws.Int64(80), 364 ToPort: aws.Int64(80), 365 IpProtocol: aws.String("tcp"), 366 IpRanges: []*ec2.IpRange{ 367 {CidrIp: aws.String("10.0.2.0/24")}, 368 {CidrIp: aws.String("10.0.3.0/24")}, 369 {CidrIp: aws.String("10.0.4.0/24")}, 370 }, 371 } 372 373 o := ec2.IpPermission{ 374 FromPort: aws.Int64(80), 375 ToPort: aws.Int64(80), 376 IpProtocol: aws.String("tcp"), 377 IpRanges: []*ec2.IpRange{ 378 {CidrIp: aws.String("10.0.5.0/24")}, 379 }, 380 } 381 382 resource.Test(t, resource.TestCase{ 383 PreCheck: func() { testAccPreCheck(t) }, 384 Providers: testAccProviders, 385 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 386 Steps: []resource.TestStep{ 387 { 388 Config: testAccAWSSecurityGroupRulePartialMatching(rInt), 389 Check: resource.ComposeTestCheckFunc( 390 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 391 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.ingress", &group, &p, "ingress"), 392 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.other", &group, &o, "ingress"), 393 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.nat_ingress", &group, &o, "ingress"), 394 ), 395 }, 396 }, 397 }) 398 } 399 400 func TestAccAWSSecurityGroupRule_PartialMatching_Source(t *testing.T) { 401 var group ec2.SecurityGroup 402 var nat ec2.SecurityGroup 403 var p ec2.IpPermission 404 rInt := acctest.RandInt() 405 406 // This function creates the expected IPPermission with the group id from an 407 // external security group, needed because Security Group IDs are generated on 408 // AWS side and can't be known ahead of time. 409 setupSG := func(*terraform.State) error { 410 if nat.GroupId == nil { 411 return fmt.Errorf("Error: nat group has nil GroupID") 412 } 413 414 p = ec2.IpPermission{ 415 FromPort: aws.Int64(80), 416 ToPort: aws.Int64(80), 417 IpProtocol: aws.String("tcp"), 418 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 419 {GroupId: nat.GroupId}, 420 }, 421 } 422 423 return nil 424 } 425 426 resource.Test(t, resource.TestCase{ 427 PreCheck: func() { testAccPreCheck(t) }, 428 Providers: testAccProviders, 429 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 430 Steps: []resource.TestStep{ 431 { 432 Config: testAccAWSSecurityGroupRulePartialMatching_Source(rInt), 433 Check: resource.ComposeTestCheckFunc( 434 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 435 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.nat", &nat), 436 setupSG, 437 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.source_ingress", &group, &p, "ingress"), 438 ), 439 }, 440 }, 441 }) 442 } 443 444 func TestAccAWSSecurityGroupRule_Issue5310(t *testing.T) { 445 var group ec2.SecurityGroup 446 447 resource.Test(t, resource.TestCase{ 448 PreCheck: func() { testAccPreCheck(t) }, 449 Providers: testAccProviders, 450 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 451 Steps: []resource.TestStep{ 452 { 453 Config: testAccAWSSecurityGroupRuleIssue5310, 454 Check: resource.ComposeTestCheckFunc( 455 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.issue_5310", &group), 456 ), 457 }, 458 }, 459 }) 460 } 461 462 func TestAccAWSSecurityGroupRule_Race(t *testing.T) { 463 var group ec2.SecurityGroup 464 465 resource.Test(t, resource.TestCase{ 466 PreCheck: func() { testAccPreCheck(t) }, 467 Providers: testAccProviders, 468 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 469 Steps: []resource.TestStep{ 470 { 471 Config: testAccAWSSecurityGroupRuleRace, 472 Check: resource.ComposeTestCheckFunc( 473 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.race", &group), 474 ), 475 }, 476 }, 477 }) 478 } 479 480 func TestAccAWSSecurityGroupRule_SelfSource(t *testing.T) { 481 var group ec2.SecurityGroup 482 rInt := acctest.RandInt() 483 484 resource.Test(t, resource.TestCase{ 485 PreCheck: func() { testAccPreCheck(t) }, 486 Providers: testAccProviders, 487 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 488 Steps: []resource.TestStep{ 489 { 490 Config: testAccAWSSecurityGroupRuleSelfInSource(rInt), 491 Check: resource.ComposeTestCheckFunc( 492 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), 493 ), 494 }, 495 }, 496 }) 497 } 498 499 func TestAccAWSSecurityGroupRule_PrefixListEgress(t *testing.T) { 500 var group ec2.SecurityGroup 501 var endpoint ec2.VpcEndpoint 502 var p ec2.IpPermission 503 504 // This function creates the expected IPPermission with the prefix list ID from 505 // the VPC Endpoint created in the test 506 setupSG := func(*terraform.State) error { 507 conn := testAccProvider.Meta().(*AWSClient).ec2conn 508 prefixListInput := &ec2.DescribePrefixListsInput{ 509 Filters: []*ec2.Filter{ 510 {Name: aws.String("prefix-list-name"), Values: []*string{endpoint.ServiceName}}, 511 }, 512 } 513 514 log.Printf("[DEBUG] Reading VPC Endpoint prefix list: %s", prefixListInput) 515 prefixListsOutput, err := conn.DescribePrefixLists(prefixListInput) 516 517 if err != nil { 518 _, ok := err.(awserr.Error) 519 if !ok { 520 return fmt.Errorf("Error reading VPC Endpoint prefix list: %s", err.Error()) 521 } 522 } 523 524 if len(prefixListsOutput.PrefixLists) != 1 { 525 return fmt.Errorf("There are multiple prefix lists associated with the service name '%s'. Unexpected", prefixListsOutput) 526 } 527 528 p = ec2.IpPermission{ 529 IpProtocol: aws.String("-1"), 530 PrefixListIds: []*ec2.PrefixListId{ 531 {PrefixListId: prefixListsOutput.PrefixLists[0].PrefixListId}, 532 }, 533 } 534 535 return nil 536 } 537 538 resource.Test(t, resource.TestCase{ 539 PreCheck: func() { testAccPreCheck(t) }, 540 Providers: testAccProviders, 541 CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, 542 Steps: []resource.TestStep{ 543 { 544 Config: testAccAWSSecurityGroupRulePrefixListEgressConfig, 545 Check: resource.ComposeTestCheckFunc( 546 testAccCheckAWSSecurityGroupRuleExists("aws_security_group.egress", &group), 547 // lookup info on the VPC Endpoint created, to populate the expected 548 // IP Perm 549 testAccCheckVpcEndpointExists("aws_vpc_endpoint.s3-us-west-2", &endpoint), 550 setupSG, 551 testAccCheckAWSSecurityGroupRuleAttributes("aws_security_group_rule.egress_1", &group, &p, "egress"), 552 ), 553 }, 554 }, 555 }) 556 } 557 558 func testAccCheckAWSSecurityGroupRuleDestroy(s *terraform.State) error { 559 conn := testAccProvider.Meta().(*AWSClient).ec2conn 560 561 for _, rs := range s.RootModule().Resources { 562 if rs.Type != "aws_security_group" { 563 continue 564 } 565 566 // Retrieve our group 567 req := &ec2.DescribeSecurityGroupsInput{ 568 GroupIds: []*string{aws.String(rs.Primary.ID)}, 569 } 570 resp, err := conn.DescribeSecurityGroups(req) 571 if err == nil { 572 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID { 573 return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID) 574 } 575 576 return nil 577 } 578 579 ec2err, ok := err.(awserr.Error) 580 if !ok { 581 return err 582 } 583 // Confirm error code is what we want 584 if ec2err.Code() != "InvalidGroup.NotFound" { 585 return err 586 } 587 } 588 589 return nil 590 } 591 592 func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc { 593 return func(s *terraform.State) error { 594 rs, ok := s.RootModule().Resources[n] 595 if !ok { 596 return fmt.Errorf("Not found: %s", n) 597 } 598 599 if rs.Primary.ID == "" { 600 return fmt.Errorf("No Security Group is set") 601 } 602 603 conn := testAccProvider.Meta().(*AWSClient).ec2conn 604 req := &ec2.DescribeSecurityGroupsInput{ 605 GroupIds: []*string{aws.String(rs.Primary.ID)}, 606 } 607 resp, err := conn.DescribeSecurityGroups(req) 608 if err != nil { 609 return err 610 } 611 612 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupId == rs.Primary.ID { 613 *group = *resp.SecurityGroups[0] 614 return nil 615 } 616 617 return fmt.Errorf("Security Group not found") 618 } 619 } 620 621 func testAccCheckAWSSecurityGroupRuleAttributes(n string, group *ec2.SecurityGroup, p *ec2.IpPermission, ruleType string) resource.TestCheckFunc { 622 return func(s *terraform.State) error { 623 rs, ok := s.RootModule().Resources[n] 624 if !ok { 625 return fmt.Errorf("Security Group Rule Not found: %s", n) 626 } 627 628 if rs.Primary.ID == "" { 629 return fmt.Errorf("No Security Group Rule is set") 630 } 631 632 if p == nil { 633 p = &ec2.IpPermission{ 634 FromPort: aws.Int64(80), 635 ToPort: aws.Int64(8000), 636 IpProtocol: aws.String("tcp"), 637 IpRanges: []*ec2.IpRange{{CidrIp: aws.String("10.0.0.0/8")}}, 638 } 639 } 640 641 var matchingRule *ec2.IpPermission 642 var rules []*ec2.IpPermission 643 if ruleType == "ingress" { 644 rules = group.IpPermissions 645 } else { 646 rules = group.IpPermissionsEgress 647 } 648 649 if len(rules) == 0 { 650 return fmt.Errorf("No IPPerms") 651 } 652 653 for _, r := range rules { 654 if r.ToPort != nil && *p.ToPort != *r.ToPort { 655 continue 656 } 657 658 if r.FromPort != nil && *p.FromPort != *r.FromPort { 659 continue 660 } 661 662 if r.IpProtocol != nil && *p.IpProtocol != *r.IpProtocol { 663 continue 664 } 665 666 remaining := len(p.IpRanges) 667 for _, ip := range p.IpRanges { 668 for _, rip := range r.IpRanges { 669 if *ip.CidrIp == *rip.CidrIp { 670 remaining-- 671 } 672 } 673 } 674 675 if remaining > 0 { 676 continue 677 } 678 679 remaining = len(p.UserIdGroupPairs) 680 for _, ip := range p.UserIdGroupPairs { 681 for _, rip := range r.UserIdGroupPairs { 682 if *ip.GroupId == *rip.GroupId { 683 remaining-- 684 } 685 } 686 } 687 688 if remaining > 0 { 689 continue 690 } 691 692 remaining = len(p.PrefixListIds) 693 for _, pip := range p.PrefixListIds { 694 for _, rpip := range r.PrefixListIds { 695 if *pip.PrefixListId == *rpip.PrefixListId { 696 remaining-- 697 } 698 } 699 } 700 701 if remaining > 0 { 702 continue 703 } 704 705 matchingRule = r 706 } 707 708 if matchingRule != nil { 709 log.Printf("[DEBUG] Matching rule found : %s", matchingRule) 710 return nil 711 } 712 713 return fmt.Errorf("Error here\n\tlooking for %s, wasn't found in %s", p, rules) 714 } 715 } 716 717 func testAccAWSSecurityGroupRuleIngressConfig(rInt int) string { 718 return fmt.Sprintf(` 719 resource "aws_security_group" "web" { 720 name = "terraform_test_%d" 721 description = "Used in the terraform acceptance tests" 722 723 tags { 724 Name = "tf-acc-test" 725 } 726 } 727 728 resource "aws_security_group_rule" "ingress_1" { 729 type = "ingress" 730 protocol = "tcp" 731 from_port = 80 732 to_port = 8000 733 cidr_blocks = ["10.0.0.0/8"] 734 735 security_group_id = "${aws_security_group.web.id}" 736 }`, rInt) 737 } 738 739 const testAccAWSSecurityGroupRuleIngress_ipv6Config = ` 740 resource "aws_vpc" "tftest" { 741 cidr_block = "10.0.0.0/16" 742 743 tags { 744 Name = "tf-testing" 745 } 746 } 747 748 resource "aws_security_group" "web" { 749 vpc_id = "${aws_vpc.tftest.id}" 750 751 tags { 752 Name = "tf-acc-test" 753 } 754 } 755 756 resource "aws_security_group_rule" "ingress_1" { 757 type = "ingress" 758 protocol = "6" 759 from_port = 80 760 to_port = 8000 761 ipv6_cidr_blocks = ["::/0"] 762 763 security_group_id = "${aws_security_group.web.id}" 764 } 765 ` 766 767 const testAccAWSSecurityGroupRuleIngress_protocolConfig = ` 768 resource "aws_vpc" "tftest" { 769 cidr_block = "10.0.0.0/16" 770 771 tags { 772 Name = "tf-testing" 773 } 774 } 775 776 resource "aws_security_group" "web" { 777 vpc_id = "${aws_vpc.tftest.id}" 778 779 tags { 780 Name = "tf-acc-test" 781 } 782 } 783 784 resource "aws_security_group_rule" "ingress_1" { 785 type = "ingress" 786 protocol = "6" 787 from_port = 80 788 to_port = 8000 789 cidr_blocks = ["10.0.0.0/8"] 790 791 security_group_id = "${aws_security_group.web.id}" 792 } 793 794 ` 795 796 const testAccAWSSecurityGroupRuleIssue5310 = ` 797 provider "aws" { 798 region = "us-east-1" 799 } 800 801 resource "aws_security_group" "issue_5310" { 802 name = "terraform-test-issue_5310" 803 description = "SG for test of issue 5310" 804 } 805 806 resource "aws_security_group_rule" "issue_5310" { 807 type = "ingress" 808 from_port = 0 809 to_port = 65535 810 protocol = "tcp" 811 security_group_id = "${aws_security_group.issue_5310.id}" 812 self = true 813 } 814 ` 815 816 func testAccAWSSecurityGroupRuleIngressClassicConfig(rInt int) string { 817 return fmt.Sprintf(` 818 provider "aws" { 819 region = "us-east-1" 820 } 821 822 resource "aws_security_group" "web" { 823 name = "terraform_test_%d" 824 description = "Used in the terraform acceptance tests" 825 826 tags { 827 Name = "tf-acc-test" 828 } 829 } 830 831 resource "aws_security_group_rule" "ingress_1" { 832 type = "ingress" 833 protocol = "tcp" 834 from_port = 80 835 to_port = 8000 836 cidr_blocks = ["10.0.0.0/8"] 837 838 security_group_id = "${aws_security_group.web.id}" 839 }`, rInt) 840 } 841 842 func testAccAWSSecurityGroupRuleEgressConfig(rInt int) string { 843 return fmt.Sprintf(` 844 resource "aws_security_group" "web" { 845 name = "terraform_test_%d" 846 description = "Used in the terraform acceptance tests" 847 848 tags { 849 Name = "tf-acc-test" 850 } 851 } 852 853 resource "aws_security_group_rule" "egress_1" { 854 type = "egress" 855 protocol = "tcp" 856 from_port = 80 857 to_port = 8000 858 cidr_blocks = ["10.0.0.0/8"] 859 860 security_group_id = "${aws_security_group.web.id}" 861 }`, rInt) 862 } 863 864 const testAccAWSSecurityGroupRuleConfigMultiIngress = ` 865 resource "aws_security_group" "web" { 866 name = "terraform_acceptance_test_example_2" 867 description = "Used in the terraform acceptance tests" 868 } 869 870 resource "aws_security_group" "worker" { 871 name = "terraform_acceptance_test_example_worker" 872 description = "Used in the terraform acceptance tests" 873 } 874 875 876 resource "aws_security_group_rule" "ingress_1" { 877 type = "ingress" 878 protocol = "tcp" 879 from_port = 22 880 to_port = 22 881 cidr_blocks = ["10.0.0.0/8"] 882 883 security_group_id = "${aws_security_group.web.id}" 884 } 885 886 resource "aws_security_group_rule" "ingress_2" { 887 type = "ingress" 888 protocol = "tcp" 889 from_port = 80 890 to_port = 8000 891 self = true 892 893 security_group_id = "${aws_security_group.web.id}" 894 } 895 ` 896 897 // check for GH-1985 regression 898 const testAccAWSSecurityGroupRuleConfigSelfReference = ` 899 provider "aws" { 900 region = "us-west-2" 901 } 902 903 resource "aws_vpc" "main" { 904 cidr_block = "10.0.0.0/16" 905 tags { 906 Name = "sg-self-test" 907 } 908 } 909 910 resource "aws_security_group" "web" { 911 name = "main" 912 vpc_id = "${aws_vpc.main.id}" 913 tags { 914 Name = "sg-self-test" 915 } 916 } 917 918 resource "aws_security_group_rule" "self" { 919 type = "ingress" 920 protocol = "-1" 921 from_port = 0 922 to_port = 0 923 self = true 924 security_group_id = "${aws_security_group.web.id}" 925 } 926 ` 927 928 func testAccAWSSecurityGroupRulePartialMatching(rInt int) string { 929 return fmt.Sprintf(` 930 resource "aws_vpc" "default" { 931 cidr_block = "10.0.0.0/16" 932 tags { 933 Name = "tf-sg-rule-bug" 934 } 935 } 936 937 resource "aws_security_group" "web" { 938 name = "tf-other-%d" 939 vpc_id = "${aws_vpc.default.id}" 940 tags { 941 Name = "tf-other-sg" 942 } 943 } 944 945 resource "aws_security_group" "nat" { 946 name = "tf-nat-%d" 947 vpc_id = "${aws_vpc.default.id}" 948 tags { 949 Name = "tf-nat-sg" 950 } 951 } 952 953 resource "aws_security_group_rule" "ingress" { 954 type = "ingress" 955 from_port = 80 956 to_port = 80 957 protocol = "tcp" 958 cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] 959 960 security_group_id = "${aws_security_group.web.id}" 961 } 962 963 resource "aws_security_group_rule" "other" { 964 type = "ingress" 965 from_port = 80 966 to_port = 80 967 protocol = "tcp" 968 cidr_blocks = ["10.0.5.0/24"] 969 970 security_group_id = "${aws_security_group.web.id}" 971 } 972 973 // same a above, but different group, to guard against bad hashing 974 resource "aws_security_group_rule" "nat_ingress" { 975 type = "ingress" 976 from_port = 80 977 to_port = 80 978 protocol = "tcp" 979 cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] 980 981 security_group_id = "${aws_security_group.nat.id}" 982 }`, rInt, rInt) 983 } 984 985 func testAccAWSSecurityGroupRulePartialMatching_Source(rInt int) string { 986 return fmt.Sprintf(` 987 resource "aws_vpc" "default" { 988 cidr_block = "10.0.0.0/16" 989 tags { 990 Name = "tf-sg-rule-bug" 991 } 992 } 993 994 resource "aws_security_group" "web" { 995 name = "tf-other-%d" 996 vpc_id = "${aws_vpc.default.id}" 997 tags { 998 Name = "tf-other-sg" 999 } 1000 } 1001 1002 resource "aws_security_group" "nat" { 1003 name = "tf-nat-%d" 1004 vpc_id = "${aws_vpc.default.id}" 1005 tags { 1006 Name = "tf-nat-sg" 1007 } 1008 } 1009 1010 resource "aws_security_group_rule" "source_ingress" { 1011 type = "ingress" 1012 from_port = 80 1013 to_port = 80 1014 protocol = "tcp" 1015 1016 source_security_group_id = "${aws_security_group.nat.id}" 1017 security_group_id = "${aws_security_group.web.id}" 1018 } 1019 1020 resource "aws_security_group_rule" "other_ingress" { 1021 type = "ingress" 1022 from_port = 80 1023 to_port = 80 1024 protocol = "tcp" 1025 cidr_blocks = ["10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] 1026 1027 security_group_id = "${aws_security_group.web.id}" 1028 }`, rInt, rInt) 1029 } 1030 1031 var testAccAWSSecurityGroupRuleRace = func() string { 1032 var b bytes.Buffer 1033 iterations := 50 1034 b.WriteString(fmt.Sprintf(` 1035 resource "aws_vpc" "default" { 1036 cidr_block = "10.0.0.0/16" 1037 tags { Name = "tf-sg-rule-race" } 1038 } 1039 1040 resource "aws_security_group" "race" { 1041 name = "tf-sg-rule-race-group-%d" 1042 vpc_id = "${aws_vpc.default.id}" 1043 } 1044 `, acctest.RandInt())) 1045 for i := 1; i < iterations; i++ { 1046 b.WriteString(fmt.Sprintf(` 1047 resource "aws_security_group_rule" "ingress%d" { 1048 security_group_id = "${aws_security_group.race.id}" 1049 type = "ingress" 1050 from_port = %d 1051 to_port = %d 1052 protocol = "tcp" 1053 cidr_blocks = ["10.0.0.%d/32"] 1054 } 1055 1056 resource "aws_security_group_rule" "egress%d" { 1057 security_group_id = "${aws_security_group.race.id}" 1058 type = "egress" 1059 from_port = %d 1060 to_port = %d 1061 protocol = "tcp" 1062 cidr_blocks = ["10.0.0.%d/32"] 1063 } 1064 `, i, i, i, i, i, i, i, i)) 1065 } 1066 return b.String() 1067 }() 1068 1069 const testAccAWSSecurityGroupRulePrefixListEgressConfig = ` 1070 1071 resource "aws_vpc" "tf_sg_prefix_list_egress_test" { 1072 cidr_block = "10.0.0.0/16" 1073 tags { 1074 Name = "tf_sg_prefix_list_egress_test" 1075 } 1076 } 1077 1078 resource "aws_route_table" "default" { 1079 vpc_id = "${aws_vpc.tf_sg_prefix_list_egress_test.id}" 1080 } 1081 1082 resource "aws_vpc_endpoint" "s3-us-west-2" { 1083 vpc_id = "${aws_vpc.tf_sg_prefix_list_egress_test.id}" 1084 service_name = "com.amazonaws.us-west-2.s3" 1085 route_table_ids = ["${aws_route_table.default.id}"] 1086 policy = <<POLICY 1087 { 1088 "Version": "2012-10-17", 1089 "Statement": [ 1090 { 1091 "Sid":"AllowAll", 1092 "Effect":"Allow", 1093 "Principal":"*", 1094 "Action":"*", 1095 "Resource":"*" 1096 } 1097 ] 1098 } 1099 POLICY 1100 } 1101 1102 resource "aws_security_group" "egress" { 1103 name = "terraform_acceptance_test_prefix_list_egress" 1104 description = "Used in the terraform acceptance tests" 1105 vpc_id = "${aws_vpc.tf_sg_prefix_list_egress_test.id}" 1106 } 1107 1108 resource "aws_security_group_rule" "egress_1" { 1109 type = "egress" 1110 protocol = "-1" 1111 from_port = 0 1112 to_port = 0 1113 prefix_list_ids = ["${aws_vpc_endpoint.s3-us-west-2.prefix_list_id}"] 1114 security_group_id = "${aws_security_group.egress.id}" 1115 } 1116 ` 1117 1118 func testAccAWSSecurityGroupRuleSelfInSource(rInt int) string { 1119 return fmt.Sprintf(` 1120 resource "aws_vpc" "foo" { 1121 cidr_block = "10.1.0.0/16" 1122 1123 tags { 1124 Name = "tf_sg_rule_self_group" 1125 } 1126 } 1127 1128 resource "aws_security_group" "web" { 1129 name = "allow_all-%d" 1130 description = "Allow all inbound traffic" 1131 vpc_id = "${aws_vpc.foo.id}" 1132 } 1133 1134 resource "aws_security_group_rule" "allow_self" { 1135 type = "ingress" 1136 from_port = 0 1137 to_port = 0 1138 protocol = "-1" 1139 security_group_id = "${aws_security_group.web.id}" 1140 source_security_group_id = "${aws_security_group.web.id}" 1141 }`, rInt) 1142 } 1143 1144 func testAccAWSSecurityGroupRuleExpectInvalidType(rInt int) string { 1145 return fmt.Sprintf(` 1146 resource "aws_vpc" "foo" { 1147 cidr_block = "10.1.0.0/16" 1148 1149 tags { 1150 Name = "tf_sg_rule_self_group" 1151 } 1152 } 1153 1154 resource "aws_security_group" "web" { 1155 name = "allow_all-%d" 1156 description = "Allow all inbound traffic" 1157 vpc_id = "${aws_vpc.foo.id}" 1158 } 1159 1160 resource "aws_security_group_rule" "allow_self" { 1161 type = "foobar" 1162 from_port = 0 1163 to_port = 0 1164 protocol = "-1" 1165 security_group_id = "${aws_security_group.web.id}" 1166 source_security_group_id = "${aws_security_group.web.id}" 1167 }`, rInt) 1168 }