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