github.com/i0n/terraform@v0.4.3-0.20150506151324-010a39a58ec1/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/awslabs/aws-sdk-go/aws" 10 "github.com/awslabs/aws-sdk-go/service/ec2" 11 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/terraform" 13 ) 14 15 func TestAccAWSSecurityGroup_normal(t *testing.T) { 16 var group ec2.SecurityGroup 17 18 resource.Test(t, resource.TestCase{ 19 PreCheck: func() { testAccPreCheck(t) }, 20 Providers: testAccProviders, 21 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 22 Steps: []resource.TestStep{ 23 resource.TestStep{ 24 Config: testAccAWSSecurityGroupConfig, 25 Check: resource.ComposeTestCheckFunc( 26 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 27 testAccCheckAWSSecurityGroupAttributes(&group), 28 resource.TestCheckResourceAttr( 29 "aws_security_group.web", "name", "terraform_acceptance_test_example"), 30 resource.TestCheckResourceAttr( 31 "aws_security_group.web", "description", "Used in the terraform acceptance tests"), 32 resource.TestCheckResourceAttr( 33 "aws_security_group.web", "ingress.3629188364.protocol", "tcp"), 34 resource.TestCheckResourceAttr( 35 "aws_security_group.web", "ingress.3629188364.from_port", "80"), 36 resource.TestCheckResourceAttr( 37 "aws_security_group.web", "ingress.3629188364.to_port", "8000"), 38 resource.TestCheckResourceAttr( 39 "aws_security_group.web", "ingress.3629188364.cidr_blocks.#", "1"), 40 resource.TestCheckResourceAttr( 41 "aws_security_group.web", "ingress.3629188364.cidr_blocks.0", "10.0.0.0/8"), 42 ), 43 }, 44 }, 45 }) 46 } 47 48 func TestAccAWSSecurityGroup_self(t *testing.T) { 49 var group ec2.SecurityGroup 50 51 checkSelf := func(s *terraform.State) (err error) { 52 defer func() { 53 if e := recover(); e != nil { 54 err = fmt.Errorf("bad: %#v", group) 55 } 56 }() 57 58 if *group.IPPermissions[0].UserIDGroupPairs[0].GroupID != *group.GroupID { 59 return fmt.Errorf("bad: %#v", group) 60 } 61 62 return nil 63 } 64 65 resource.Test(t, resource.TestCase{ 66 PreCheck: func() { testAccPreCheck(t) }, 67 Providers: testAccProviders, 68 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 69 Steps: []resource.TestStep{ 70 resource.TestStep{ 71 Config: testAccAWSSecurityGroupConfigSelf, 72 Check: resource.ComposeTestCheckFunc( 73 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 74 resource.TestCheckResourceAttr( 75 "aws_security_group.web", "name", "terraform_acceptance_test_example"), 76 resource.TestCheckResourceAttr( 77 "aws_security_group.web", "description", "Used in the terraform acceptance tests"), 78 resource.TestCheckResourceAttr( 79 "aws_security_group.web", "ingress.3971148406.protocol", "tcp"), 80 resource.TestCheckResourceAttr( 81 "aws_security_group.web", "ingress.3971148406.from_port", "80"), 82 resource.TestCheckResourceAttr( 83 "aws_security_group.web", "ingress.3971148406.to_port", "8000"), 84 resource.TestCheckResourceAttr( 85 "aws_security_group.web", "ingress.3971148406.self", "true"), 86 checkSelf, 87 ), 88 }, 89 }, 90 }) 91 } 92 93 func TestAccAWSSecurityGroup_vpc(t *testing.T) { 94 var group ec2.SecurityGroup 95 96 testCheck := func(*terraform.State) error { 97 if *group.VPCID == "" { 98 return fmt.Errorf("should have vpc ID") 99 } 100 101 return nil 102 } 103 104 resource.Test(t, resource.TestCase{ 105 PreCheck: func() { testAccPreCheck(t) }, 106 Providers: testAccProviders, 107 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 108 Steps: []resource.TestStep{ 109 resource.TestStep{ 110 Config: testAccAWSSecurityGroupConfigVpc, 111 Check: resource.ComposeTestCheckFunc( 112 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 113 testAccCheckAWSSecurityGroupAttributes(&group), 114 resource.TestCheckResourceAttr( 115 "aws_security_group.web", "name", "terraform_acceptance_test_example"), 116 resource.TestCheckResourceAttr( 117 "aws_security_group.web", "description", "Used in the terraform acceptance tests"), 118 resource.TestCheckResourceAttr( 119 "aws_security_group.web", "ingress.3629188364.protocol", "tcp"), 120 resource.TestCheckResourceAttr( 121 "aws_security_group.web", "ingress.3629188364.from_port", "80"), 122 resource.TestCheckResourceAttr( 123 "aws_security_group.web", "ingress.3629188364.to_port", "8000"), 124 resource.TestCheckResourceAttr( 125 "aws_security_group.web", "ingress.3629188364.cidr_blocks.#", "1"), 126 resource.TestCheckResourceAttr( 127 "aws_security_group.web", "ingress.3629188364.cidr_blocks.0", "10.0.0.0/8"), 128 resource.TestCheckResourceAttr( 129 "aws_security_group.web", "egress.3629188364.protocol", "tcp"), 130 resource.TestCheckResourceAttr( 131 "aws_security_group.web", "egress.3629188364.from_port", "80"), 132 resource.TestCheckResourceAttr( 133 "aws_security_group.web", "egress.3629188364.to_port", "8000"), 134 resource.TestCheckResourceAttr( 135 "aws_security_group.web", "egress.3629188364.cidr_blocks.#", "1"), 136 resource.TestCheckResourceAttr( 137 "aws_security_group.web", "egress.3629188364.cidr_blocks.0", "10.0.0.0/8"), 138 testCheck, 139 ), 140 }, 141 }, 142 }) 143 } 144 145 func TestAccAWSSecurityGroup_MultiIngress(t *testing.T) { 146 var group ec2.SecurityGroup 147 148 resource.Test(t, resource.TestCase{ 149 PreCheck: func() { testAccPreCheck(t) }, 150 Providers: testAccProviders, 151 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 152 Steps: []resource.TestStep{ 153 resource.TestStep{ 154 Config: testAccAWSSecurityGroupConfigMultiIngress, 155 Check: resource.ComposeTestCheckFunc( 156 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 157 ), 158 }, 159 }, 160 }) 161 } 162 163 func TestAccAWSSecurityGroup_Change(t *testing.T) { 164 var group ec2.SecurityGroup 165 166 resource.Test(t, resource.TestCase{ 167 PreCheck: func() { testAccPreCheck(t) }, 168 Providers: testAccProviders, 169 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 170 Steps: []resource.TestStep{ 171 resource.TestStep{ 172 Config: testAccAWSSecurityGroupConfig, 173 Check: resource.ComposeTestCheckFunc( 174 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 175 ), 176 }, 177 resource.TestStep{ 178 Config: testAccAWSSecurityGroupConfigChange, 179 Check: resource.ComposeTestCheckFunc( 180 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 181 testAccCheckAWSSecurityGroupAttributesChanged(&group), 182 ), 183 }, 184 }, 185 }) 186 } 187 188 func TestAccAWSSecurityGroup_generatedName(t *testing.T) { 189 var group ec2.SecurityGroup 190 191 resource.Test(t, resource.TestCase{ 192 PreCheck: func() { testAccPreCheck(t) }, 193 Providers: testAccProviders, 194 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 195 Steps: []resource.TestStep{ 196 resource.TestStep{ 197 Config: testAccAWSSecurityGroupConfig_generatedName, 198 Check: resource.ComposeTestCheckFunc( 199 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 200 resource.TestCheckResourceAttr( 201 "aws_security_group.web", "description", "Managed by Terraform"), 202 func(s *terraform.State) error { 203 if group.GroupName == nil { 204 return fmt.Errorf("bad: No SG name") 205 } 206 if !strings.HasPrefix(*group.GroupName, "terraform-") { 207 return fmt.Errorf("No terraform- prefix: %s", *group.GroupName) 208 } 209 return nil 210 }, 211 ), 212 }, 213 }, 214 }) 215 } 216 217 func TestAccAWSSecurityGroup_DefaultEgress(t *testing.T) { 218 219 // VPC 220 resource.Test(t, resource.TestCase{ 221 PreCheck: func() { testAccPreCheck(t) }, 222 Providers: testAccProviders, 223 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 224 Steps: []resource.TestStep{ 225 resource.TestStep{ 226 Config: testAccAWSSecurityGroupConfigDefaultEgress, 227 Check: resource.ComposeTestCheckFunc( 228 testAccCheckAWSSecurityGroupExistsWithoutDefault("aws_security_group.worker"), 229 ), 230 }, 231 }, 232 }) 233 234 // Classic 235 var group ec2.SecurityGroup 236 resource.Test(t, resource.TestCase{ 237 PreCheck: func() { testAccPreCheck(t) }, 238 Providers: testAccProviders, 239 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 240 Steps: []resource.TestStep{ 241 resource.TestStep{ 242 Config: testAccAWSSecurityGroupConfigClassic, 243 Check: resource.ComposeTestCheckFunc( 244 testAccCheckAWSSecurityGroupExists("aws_security_group.web", &group), 245 ), 246 }, 247 }, 248 }) 249 } 250 251 func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error { 252 conn := testAccProvider.Meta().(*AWSClient).ec2conn 253 254 for _, rs := range s.RootModule().Resources { 255 if rs.Type != "aws_security_group" { 256 continue 257 } 258 259 // Retrieve our group 260 req := &ec2.DescribeSecurityGroupsInput{ 261 GroupIDs: []*string{aws.String(rs.Primary.ID)}, 262 } 263 resp, err := conn.DescribeSecurityGroups(req) 264 if err == nil { 265 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID { 266 return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID) 267 } 268 269 return nil 270 } 271 272 ec2err, ok := err.(aws.APIError) 273 if !ok { 274 return err 275 } 276 // Confirm error code is what we want 277 if ec2err.Code != "InvalidGroup.NotFound" { 278 return err 279 } 280 } 281 282 return nil 283 } 284 285 func testAccCheckAWSSecurityGroupExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc { 286 return func(s *terraform.State) error { 287 rs, ok := s.RootModule().Resources[n] 288 if !ok { 289 return fmt.Errorf("Not found: %s", n) 290 } 291 292 if rs.Primary.ID == "" { 293 return fmt.Errorf("No Security Group is set") 294 } 295 296 conn := testAccProvider.Meta().(*AWSClient).ec2conn 297 req := &ec2.DescribeSecurityGroupsInput{ 298 GroupIDs: []*string{aws.String(rs.Primary.ID)}, 299 } 300 resp, err := conn.DescribeSecurityGroups(req) 301 if err != nil { 302 return err 303 } 304 305 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID { 306 *group = *resp.SecurityGroups[0] 307 return nil 308 } 309 310 return fmt.Errorf("Security Group not found") 311 } 312 } 313 314 func testAccCheckAWSSecurityGroupAttributes(group *ec2.SecurityGroup) resource.TestCheckFunc { 315 return func(s *terraform.State) error { 316 p := &ec2.IPPermission{ 317 FromPort: aws.Long(80), 318 ToPort: aws.Long(8000), 319 IPProtocol: aws.String("tcp"), 320 IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}}, 321 } 322 323 if *group.GroupName != "terraform_acceptance_test_example" { 324 return fmt.Errorf("Bad name: %s", *group.GroupName) 325 } 326 327 if *group.Description != "Used in the terraform acceptance tests" { 328 return fmt.Errorf("Bad description: %s", *group.Description) 329 } 330 331 if len(group.IPPermissions) == 0 { 332 return fmt.Errorf("No IPPerms") 333 } 334 335 // Compare our ingress 336 if !reflect.DeepEqual(group.IPPermissions[0], p) { 337 return fmt.Errorf( 338 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 339 group.IPPermissions[0], 340 p) 341 } 342 343 return nil 344 } 345 } 346 347 func TestAccAWSSecurityGroup_tags(t *testing.T) { 348 var group ec2.SecurityGroup 349 350 resource.Test(t, resource.TestCase{ 351 PreCheck: func() { testAccPreCheck(t) }, 352 Providers: testAccProviders, 353 CheckDestroy: testAccCheckAWSSecurityGroupDestroy, 354 Steps: []resource.TestStep{ 355 resource.TestStep{ 356 Config: testAccAWSSecurityGroupConfigTags, 357 Check: resource.ComposeTestCheckFunc( 358 testAccCheckAWSSecurityGroupExists("aws_security_group.foo", &group), 359 testAccCheckTagsSDK(&group.Tags, "foo", "bar"), 360 ), 361 }, 362 363 resource.TestStep{ 364 Config: testAccAWSSecurityGroupConfigTagsUpdate, 365 Check: resource.ComposeTestCheckFunc( 366 testAccCheckAWSSecurityGroupExists("aws_security_group.foo", &group), 367 testAccCheckTagsSDK(&group.Tags, "foo", ""), 368 testAccCheckTagsSDK(&group.Tags, "bar", "baz"), 369 ), 370 }, 371 }, 372 }) 373 } 374 375 func testAccCheckAWSSecurityGroupAttributesChanged(group *ec2.SecurityGroup) resource.TestCheckFunc { 376 return func(s *terraform.State) error { 377 p := []*ec2.IPPermission{ 378 &ec2.IPPermission{ 379 FromPort: aws.Long(80), 380 ToPort: aws.Long(9000), 381 IPProtocol: aws.String("tcp"), 382 IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}}, 383 }, 384 &ec2.IPPermission{ 385 FromPort: aws.Long(80), 386 ToPort: aws.Long(8000), 387 IPProtocol: aws.String("tcp"), 388 IPRanges: []*ec2.IPRange{ 389 &ec2.IPRange{ 390 CIDRIP: aws.String("0.0.0.0/0"), 391 }, 392 &ec2.IPRange{ 393 CIDRIP: aws.String("10.0.0.0/8"), 394 }, 395 }, 396 }, 397 } 398 399 if *group.GroupName != "terraform_acceptance_test_example" { 400 return fmt.Errorf("Bad name: %s", *group.GroupName) 401 } 402 403 if *group.Description != "Used in the terraform acceptance tests" { 404 return fmt.Errorf("Bad description: %s", *group.Description) 405 } 406 407 // Compare our ingress 408 if len(group.IPPermissions) != 2 { 409 return fmt.Errorf( 410 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 411 group.IPPermissions, 412 p) 413 } 414 415 if *group.IPPermissions[0].ToPort == 8000 { 416 group.IPPermissions[1], group.IPPermissions[0] = 417 group.IPPermissions[0], group.IPPermissions[1] 418 } 419 420 if !reflect.DeepEqual(group.IPPermissions, p) { 421 return fmt.Errorf( 422 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 423 group.IPPermissions, 424 p) 425 } 426 427 return nil 428 } 429 } 430 431 func testAccCheckAWSSecurityGroupExistsWithoutDefault(n string) resource.TestCheckFunc { 432 return func(s *terraform.State) error { 433 rs, ok := s.RootModule().Resources[n] 434 if !ok { 435 return fmt.Errorf("Not found: %s", n) 436 } 437 438 if rs.Primary.ID == "" { 439 return fmt.Errorf("No Security Group is set") 440 } 441 442 conn := testAccProvider.Meta().(*AWSClient).ec2conn 443 req := &ec2.DescribeSecurityGroupsInput{ 444 GroupIDs: []*string{aws.String(rs.Primary.ID)}, 445 } 446 resp, err := conn.DescribeSecurityGroups(req) 447 if err != nil { 448 return err 449 } 450 451 if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID { 452 group := *resp.SecurityGroups[0] 453 454 if len(group.IPPermissionsEgress) != 1 { 455 return fmt.Errorf("Security Group should have only 1 egress rule, got %d", len(group.IPPermissionsEgress)) 456 } 457 } 458 459 return nil 460 } 461 } 462 463 const testAccAWSSecurityGroupConfig = ` 464 resource "aws_security_group" "web" { 465 name = "terraform_acceptance_test_example" 466 description = "Used in the terraform acceptance tests" 467 468 ingress { 469 protocol = "tcp" 470 from_port = 80 471 to_port = 8000 472 cidr_blocks = ["10.0.0.0/8"] 473 } 474 475 egress { 476 protocol = "tcp" 477 from_port = 80 478 to_port = 8000 479 cidr_blocks = ["10.0.0.0/8"] 480 } 481 482 tags { 483 Name = "tf-acc-test" 484 } 485 } 486 ` 487 488 const testAccAWSSecurityGroupConfigChange = ` 489 resource "aws_security_group" "web" { 490 name = "terraform_acceptance_test_example" 491 description = "Used in the terraform acceptance tests" 492 493 ingress { 494 protocol = "tcp" 495 from_port = 80 496 to_port = 9000 497 cidr_blocks = ["10.0.0.0/8"] 498 } 499 500 ingress { 501 protocol = "tcp" 502 from_port = 80 503 to_port = 8000 504 cidr_blocks = ["0.0.0.0/0", "10.0.0.0/8"] 505 } 506 507 egress { 508 protocol = "tcp" 509 from_port = 80 510 to_port = 8000 511 cidr_blocks = ["10.0.0.0/8"] 512 } 513 } 514 ` 515 516 const testAccAWSSecurityGroupConfigSelf = ` 517 resource "aws_security_group" "web" { 518 name = "terraform_acceptance_test_example" 519 description = "Used in the terraform acceptance tests" 520 521 ingress { 522 protocol = "tcp" 523 from_port = 80 524 to_port = 8000 525 self = true 526 } 527 528 egress { 529 protocol = "tcp" 530 from_port = 80 531 to_port = 8000 532 cidr_blocks = ["10.0.0.0/8"] 533 } 534 } 535 ` 536 537 const testAccAWSSecurityGroupConfigVpc = ` 538 resource "aws_vpc" "foo" { 539 cidr_block = "10.1.0.0/16" 540 } 541 542 resource "aws_security_group" "web" { 543 name = "terraform_acceptance_test_example" 544 description = "Used in the terraform acceptance tests" 545 vpc_id = "${aws_vpc.foo.id}" 546 547 ingress { 548 protocol = "tcp" 549 from_port = 80 550 to_port = 8000 551 cidr_blocks = ["10.0.0.0/8"] 552 } 553 554 egress { 555 protocol = "tcp" 556 from_port = 80 557 to_port = 8000 558 cidr_blocks = ["10.0.0.0/8"] 559 } 560 } 561 ` 562 563 const testAccAWSSecurityGroupConfigMultiIngress = ` 564 resource "aws_security_group" "worker" { 565 name = "terraform_acceptance_test_example_1" 566 description = "Used in the terraform acceptance tests" 567 568 ingress { 569 protocol = "tcp" 570 from_port = 80 571 to_port = 8000 572 cidr_blocks = ["10.0.0.0/8"] 573 } 574 575 egress { 576 protocol = "tcp" 577 from_port = 80 578 to_port = 8000 579 cidr_blocks = ["10.0.0.0/8"] 580 } 581 } 582 583 resource "aws_security_group" "web" { 584 name = "terraform_acceptance_test_example_2" 585 description = "Used in the terraform acceptance tests" 586 587 ingress { 588 protocol = "tcp" 589 from_port = 22 590 to_port = 22 591 cidr_blocks = ["10.0.0.0/8"] 592 } 593 594 ingress { 595 protocol = "tcp" 596 from_port = 800 597 to_port = 800 598 cidr_blocks = ["10.0.0.0/8"] 599 } 600 601 ingress { 602 protocol = "tcp" 603 from_port = 80 604 to_port = 8000 605 security_groups = ["${aws_security_group.worker.id}"] 606 } 607 608 egress { 609 protocol = "tcp" 610 from_port = 80 611 to_port = 8000 612 cidr_blocks = ["10.0.0.0/8"] 613 } 614 } 615 ` 616 617 const testAccAWSSecurityGroupConfigTags = ` 618 resource "aws_security_group" "foo" { 619 name = "terraform_acceptance_test_example" 620 description = "Used in the terraform acceptance tests" 621 622 ingress { 623 protocol = "tcp" 624 from_port = 80 625 to_port = 8000 626 cidr_blocks = ["10.0.0.0/8"] 627 } 628 629 egress { 630 protocol = "tcp" 631 from_port = 80 632 to_port = 8000 633 cidr_blocks = ["10.0.0.0/8"] 634 } 635 636 tags { 637 foo = "bar" 638 } 639 } 640 ` 641 642 const testAccAWSSecurityGroupConfigTagsUpdate = ` 643 resource "aws_security_group" "foo" { 644 name = "terraform_acceptance_test_example" 645 description = "Used in the terraform acceptance tests" 646 647 ingress { 648 protocol = "tcp" 649 from_port = 80 650 to_port = 8000 651 cidr_blocks = ["10.0.0.0/8"] 652 } 653 654 egress { 655 protocol = "tcp" 656 from_port = 80 657 to_port = 8000 658 cidr_blocks = ["10.0.0.0/8"] 659 } 660 661 tags { 662 bar = "baz" 663 } 664 } 665 ` 666 667 const testAccAWSSecurityGroupConfig_generatedName = ` 668 resource "aws_security_group" "web" { 669 ingress { 670 protocol = "tcp" 671 from_port = 80 672 to_port = 8000 673 cidr_blocks = ["10.0.0.0/8"] 674 } 675 676 egress { 677 protocol = "tcp" 678 from_port = 80 679 to_port = 8000 680 cidr_blocks = ["10.0.0.0/8"] 681 } 682 683 tags { 684 Name = "tf-acc-test" 685 } 686 } 687 ` 688 689 const testAccAWSSecurityGroupConfigDefaultEgress = ` 690 resource "aws_vpc" "tf_sg_egress_test" { 691 cidr_block = "10.0.0.0/16" 692 tags { 693 Name = "tf_sg_egress_test" 694 } 695 } 696 697 resource "aws_security_group" "worker" { 698 name = "terraform_acceptance_test_example_1" 699 description = "Used in the terraform acceptance tests" 700 vpc_id = "${aws_vpc.tf_sg_egress_test.id}" 701 702 egress { 703 protocol = "tcp" 704 from_port = 80 705 to_port = 8000 706 cidr_blocks = ["10.0.0.0/8"] 707 } 708 } 709 ` 710 711 const testAccAWSSecurityGroupConfigClassic = ` 712 provider "aws" { 713 region = "us-east-1" 714 } 715 716 resource "aws_security_group" "web" { 717 name = "terraform_acceptance_test_example_1" 718 description = "Used in the terraform acceptance tests" 719 } 720 `