github.com/sathiyas/terraform@v0.6.9-0.20151210233947-3330da00b997/builtin/providers/aws/resource_aws_route53_record_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/terraform/helper/resource" 9 "github.com/hashicorp/terraform/terraform" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/service/route53" 13 ) 14 15 func TestCleanRecordName(t *testing.T) { 16 cases := []struct { 17 Input, Output string 18 }{ 19 {"www.nonexample.com", "www.nonexample.com"}, 20 {"\\052.nonexample.com", "*.nonexample.com"}, 21 {"nonexample.com", "nonexample.com"}, 22 } 23 24 for _, tc := range cases { 25 actual := cleanRecordName(tc.Input) 26 if actual != tc.Output { 27 t.Fatalf("input: %s\noutput: %s", tc.Input, actual) 28 } 29 } 30 } 31 32 func TestExpandRecordName(t *testing.T) { 33 cases := []struct { 34 Input, Output string 35 }{ 36 {"www", "www.nonexample.com"}, 37 {"dev.www", "dev.www.nonexample.com"}, 38 {"*", "*.nonexample.com"}, 39 {"nonexample.com", "nonexample.com"}, 40 {"test.nonexample.com", "test.nonexample.com"}, 41 {"test.nonexample.com.", "test.nonexample.com"}, 42 } 43 44 zone_name := "nonexample.com" 45 for _, tc := range cases { 46 actual := expandRecordName(tc.Input, zone_name) 47 if actual != tc.Output { 48 t.Fatalf("input: %s\noutput: %s", tc.Input, actual) 49 } 50 } 51 } 52 53 func TestAccAWSRoute53Record_basic(t *testing.T) { 54 resource.Test(t, resource.TestCase{ 55 PreCheck: func() { testAccPreCheck(t) }, 56 Providers: testAccProviders, 57 CheckDestroy: testAccCheckRoute53RecordDestroy, 58 Steps: []resource.TestStep{ 59 resource.TestStep{ 60 Config: testAccRoute53RecordConfig, 61 Check: resource.ComposeTestCheckFunc( 62 testAccCheckRoute53RecordExists("aws_route53_record.default"), 63 ), 64 }, 65 }, 66 }) 67 } 68 69 func TestAccAWSRoute53Record_txtSupport(t *testing.T) { 70 resource.Test(t, resource.TestCase{ 71 PreCheck: func() { testAccPreCheck(t) }, 72 Providers: testAccProviders, 73 CheckDestroy: testAccCheckRoute53RecordDestroy, 74 Steps: []resource.TestStep{ 75 resource.TestStep{ 76 Config: testAccRoute53RecordConfigTXT, 77 Check: resource.ComposeTestCheckFunc( 78 testAccCheckRoute53RecordExists("aws_route53_record.default"), 79 ), 80 }, 81 }, 82 }) 83 } 84 85 func TestAccAWSRoute53Record_spfSupport(t *testing.T) { 86 resource.Test(t, resource.TestCase{ 87 PreCheck: func() { testAccPreCheck(t) }, 88 Providers: testAccProviders, 89 CheckDestroy: testAccCheckRoute53RecordDestroy, 90 Steps: []resource.TestStep{ 91 resource.TestStep{ 92 Config: testAccRoute53RecordConfigSPF, 93 Check: resource.ComposeTestCheckFunc( 94 testAccCheckRoute53RecordExists("aws_route53_record.default"), 95 resource.TestCheckResourceAttr( 96 "aws_route53_record.default", "records.2930149397", "include:notexample.com"), 97 ), 98 }, 99 }, 100 }) 101 } 102 func TestAccAWSRoute53Record_generatesSuffix(t *testing.T) { 103 resource.Test(t, resource.TestCase{ 104 PreCheck: func() { testAccPreCheck(t) }, 105 Providers: testAccProviders, 106 CheckDestroy: testAccCheckRoute53RecordDestroy, 107 Steps: []resource.TestStep{ 108 resource.TestStep{ 109 Config: testAccRoute53RecordConfigSuffix, 110 Check: resource.ComposeTestCheckFunc( 111 testAccCheckRoute53RecordExists("aws_route53_record.default"), 112 ), 113 }, 114 }, 115 }) 116 } 117 118 func TestAccAWSRoute53Record_wildcard(t *testing.T) { 119 resource.Test(t, resource.TestCase{ 120 PreCheck: func() { testAccPreCheck(t) }, 121 Providers: testAccProviders, 122 CheckDestroy: testAccCheckRoute53RecordDestroy, 123 Steps: []resource.TestStep{ 124 resource.TestStep{ 125 Config: testAccRoute53WildCardRecordConfig, 126 Check: resource.ComposeTestCheckFunc( 127 testAccCheckRoute53RecordExists("aws_route53_record.wildcard"), 128 ), 129 }, 130 131 // Cause a change, which will trigger a refresh 132 resource.TestStep{ 133 Config: testAccRoute53WildCardRecordConfigUpdate, 134 Check: resource.ComposeTestCheckFunc( 135 testAccCheckRoute53RecordExists("aws_route53_record.wildcard"), 136 ), 137 }, 138 }, 139 }) 140 } 141 142 func TestAccAWSRoute53Record_failover(t *testing.T) { 143 resource.Test(t, resource.TestCase{ 144 PreCheck: func() { testAccPreCheck(t) }, 145 Providers: testAccProviders, 146 CheckDestroy: testAccCheckRoute53RecordDestroy, 147 Steps: []resource.TestStep{ 148 resource.TestStep{ 149 Config: testAccRoute53FailoverCNAMERecord, 150 Check: resource.ComposeTestCheckFunc( 151 testAccCheckRoute53RecordExists("aws_route53_record.www-primary"), 152 testAccCheckRoute53RecordExists("aws_route53_record.www-secondary"), 153 ), 154 }, 155 }, 156 }) 157 } 158 159 func TestAccAWSRoute53Record_weighted_basic(t *testing.T) { 160 resource.Test(t, resource.TestCase{ 161 PreCheck: func() { testAccPreCheck(t) }, 162 Providers: testAccProviders, 163 CheckDestroy: testAccCheckRoute53RecordDestroy, 164 Steps: []resource.TestStep{ 165 resource.TestStep{ 166 Config: testAccRoute53WeightedCNAMERecord, 167 Check: resource.ComposeTestCheckFunc( 168 testAccCheckRoute53RecordExists("aws_route53_record.www-dev"), 169 testAccCheckRoute53RecordExists("aws_route53_record.www-live"), 170 testAccCheckRoute53RecordExists("aws_route53_record.www-off"), 171 ), 172 }, 173 }, 174 }) 175 } 176 177 func TestAccAWSRoute53Record_alias(t *testing.T) { 178 resource.Test(t, resource.TestCase{ 179 PreCheck: func() { testAccPreCheck(t) }, 180 Providers: testAccProviders, 181 CheckDestroy: testAccCheckRoute53RecordDestroy, 182 Steps: []resource.TestStep{ 183 resource.TestStep{ 184 Config: testAccRoute53ElbAliasRecord, 185 Check: resource.ComposeTestCheckFunc( 186 testAccCheckRoute53RecordExists("aws_route53_record.alias"), 187 ), 188 }, 189 }, 190 }) 191 } 192 193 func TestAccAWSRoute53Record_s3_alias(t *testing.T) { 194 resource.Test(t, resource.TestCase{ 195 PreCheck: func() { testAccPreCheck(t) }, 196 Providers: testAccProviders, 197 CheckDestroy: testAccCheckRoute53RecordDestroy, 198 Steps: []resource.TestStep{ 199 resource.TestStep{ 200 Config: testAccRoute53S3AliasRecord, 201 Check: resource.ComposeTestCheckFunc( 202 testAccCheckRoute53RecordExists("aws_route53_record.alias"), 203 ), 204 }, 205 }, 206 }) 207 } 208 209 func TestAccAWSRoute53Record_weighted_alias(t *testing.T) { 210 resource.Test(t, resource.TestCase{ 211 PreCheck: func() { testAccPreCheck(t) }, 212 Providers: testAccProviders, 213 CheckDestroy: testAccCheckRoute53RecordDestroy, 214 Steps: []resource.TestStep{ 215 resource.TestStep{ 216 Config: testAccRoute53WeightedElbAliasRecord, 217 Check: resource.ComposeTestCheckFunc( 218 testAccCheckRoute53RecordExists("aws_route53_record.elb_weighted_alias_live"), 219 testAccCheckRoute53RecordExists("aws_route53_record.elb_weighted_alias_dev"), 220 ), 221 }, 222 223 resource.TestStep{ 224 Config: testAccRoute53WeightedR53AliasRecord, 225 Check: resource.ComposeTestCheckFunc( 226 testAccCheckRoute53RecordExists("aws_route53_record.green_origin"), 227 testAccCheckRoute53RecordExists("aws_route53_record.r53_weighted_alias_live"), 228 testAccCheckRoute53RecordExists("aws_route53_record.blue_origin"), 229 testAccCheckRoute53RecordExists("aws_route53_record.r53_weighted_alias_dev"), 230 ), 231 }, 232 }, 233 }) 234 } 235 236 func TestAccAWSRoute53Record_TypeChange(t *testing.T) { 237 resource.Test(t, resource.TestCase{ 238 PreCheck: func() { testAccPreCheck(t) }, 239 Providers: testAccProviders, 240 CheckDestroy: testAccCheckRoute53RecordDestroy, 241 Steps: []resource.TestStep{ 242 resource.TestStep{ 243 Config: testAccRoute53RecordTypeChangePre, 244 Check: resource.ComposeTestCheckFunc( 245 testAccCheckRoute53RecordExists("aws_route53_record.sample"), 246 ), 247 }, 248 249 // Cause a change, which will trigger a refresh 250 resource.TestStep{ 251 Config: testAccRoute53RecordTypeChangePost, 252 Check: resource.ComposeTestCheckFunc( 253 testAccCheckRoute53RecordExists("aws_route53_record.sample"), 254 ), 255 }, 256 }, 257 }) 258 } 259 260 func testAccCheckRoute53RecordDestroy(s *terraform.State) error { 261 conn := testAccProvider.Meta().(*AWSClient).r53conn 262 for _, rs := range s.RootModule().Resources { 263 if rs.Type != "aws_route53_record" { 264 continue 265 } 266 267 parts := strings.Split(rs.Primary.ID, "_") 268 zone := parts[0] 269 name := parts[1] 270 rType := parts[2] 271 272 lopts := &route53.ListResourceRecordSetsInput{ 273 HostedZoneId: aws.String(cleanZoneID(zone)), 274 StartRecordName: aws.String(name), 275 StartRecordType: aws.String(rType), 276 } 277 278 resp, err := conn.ListResourceRecordSets(lopts) 279 if err != nil { 280 return err 281 } 282 if len(resp.ResourceRecordSets) == 0 { 283 return nil 284 } 285 rec := resp.ResourceRecordSets[0] 286 if FQDN(*rec.Name) == FQDN(name) && *rec.Type == rType { 287 return fmt.Errorf("Record still exists: %#v", rec) 288 } 289 } 290 return nil 291 } 292 293 func testAccCheckRoute53RecordExists(n string) resource.TestCheckFunc { 294 return func(s *terraform.State) error { 295 conn := testAccProvider.Meta().(*AWSClient).r53conn 296 rs, ok := s.RootModule().Resources[n] 297 if !ok { 298 return fmt.Errorf("Not found: %s", n) 299 } 300 301 if rs.Primary.ID == "" { 302 return fmt.Errorf("No hosted zone ID is set") 303 } 304 305 parts := strings.Split(rs.Primary.ID, "_") 306 zone := parts[0] 307 name := parts[1] 308 rType := parts[2] 309 310 en := expandRecordName(name, "notexample.com") 311 312 lopts := &route53.ListResourceRecordSetsInput{ 313 HostedZoneId: aws.String(cleanZoneID(zone)), 314 StartRecordName: aws.String(en), 315 StartRecordType: aws.String(rType), 316 } 317 318 resp, err := conn.ListResourceRecordSets(lopts) 319 if err != nil { 320 return err 321 } 322 if len(resp.ResourceRecordSets) == 0 { 323 return fmt.Errorf("Record does not exist") 324 } 325 // rec := resp.ResourceRecordSets[0] 326 for _, rec := range resp.ResourceRecordSets { 327 recName := cleanRecordName(*rec.Name) 328 if FQDN(strings.ToLower(recName)) == FQDN(strings.ToLower(en)) && *rec.Type == rType { 329 return nil 330 } 331 } 332 return fmt.Errorf("Record does not exist: %#v", rs.Primary.ID) 333 } 334 } 335 336 const testAccRoute53RecordConfig = ` 337 resource "aws_route53_zone" "main" { 338 name = "notexample.com" 339 } 340 341 resource "aws_route53_record" "default" { 342 zone_id = "${aws_route53_zone.main.zone_id}" 343 name = "www.NOTexamplE.com" 344 type = "A" 345 ttl = "30" 346 records = ["127.0.0.1", "127.0.0.27"] 347 } 348 ` 349 350 const testAccRoute53RecordConfigSuffix = ` 351 resource "aws_route53_zone" "main" { 352 name = "notexample.com" 353 } 354 355 resource "aws_route53_record" "default" { 356 zone_id = "${aws_route53_zone.main.zone_id}" 357 name = "subdomain" 358 type = "A" 359 ttl = "30" 360 records = ["127.0.0.1", "127.0.0.27"] 361 } 362 ` 363 364 const testAccRoute53WildCardRecordConfig = ` 365 resource "aws_route53_zone" "main" { 366 name = "notexample.com" 367 } 368 369 resource "aws_route53_record" "default" { 370 zone_id = "${aws_route53_zone.main.zone_id}" 371 name = "subdomain" 372 type = "A" 373 ttl = "30" 374 records = ["127.0.0.1", "127.0.0.27"] 375 } 376 377 resource "aws_route53_record" "wildcard" { 378 zone_id = "${aws_route53_zone.main.zone_id}" 379 name = "*.notexample.com" 380 type = "A" 381 ttl = "30" 382 records = ["127.0.0.1"] 383 } 384 ` 385 386 const testAccRoute53WildCardRecordConfigUpdate = ` 387 resource "aws_route53_zone" "main" { 388 name = "notexample.com" 389 } 390 391 resource "aws_route53_record" "default" { 392 zone_id = "${aws_route53_zone.main.zone_id}" 393 name = "subdomain" 394 type = "A" 395 ttl = "30" 396 records = ["127.0.0.1", "127.0.0.27"] 397 } 398 399 resource "aws_route53_record" "wildcard" { 400 zone_id = "${aws_route53_zone.main.zone_id}" 401 name = "*.notexample.com" 402 type = "A" 403 ttl = "60" 404 records = ["127.0.0.1"] 405 } 406 ` 407 const testAccRoute53RecordConfigTXT = ` 408 resource "aws_route53_zone" "main" { 409 name = "notexample.com" 410 } 411 412 resource "aws_route53_record" "default" { 413 zone_id = "/hostedzone/${aws_route53_zone.main.zone_id}" 414 name = "subdomain" 415 type = "TXT" 416 ttl = "30" 417 records = ["lalalala"] 418 } 419 ` 420 const testAccRoute53RecordConfigSPF = ` 421 resource "aws_route53_zone" "main" { 422 name = "notexample.com" 423 } 424 425 resource "aws_route53_record" "default" { 426 zone_id = "${aws_route53_zone.main.zone_id}" 427 name = "test" 428 type = "SPF" 429 ttl = "30" 430 records = ["include:notexample.com"] 431 } 432 ` 433 434 const testAccRoute53FailoverCNAMERecord = ` 435 resource "aws_route53_zone" "main" { 436 name = "notexample.com" 437 } 438 439 resource "aws_route53_health_check" "foo" { 440 fqdn = "dev.notexample.com" 441 port = 80 442 type = "HTTP" 443 resource_path = "/" 444 failure_threshold = "2" 445 request_interval = "30" 446 447 tags = { 448 Name = "tf-test-health-check" 449 } 450 } 451 452 resource "aws_route53_record" "www-primary" { 453 zone_id = "${aws_route53_zone.main.zone_id}" 454 name = "www" 455 type = "CNAME" 456 ttl = "5" 457 failover = "PRIMARY" 458 health_check_id = "${aws_route53_health_check.foo.id}" 459 set_identifier = "www-primary" 460 records = ["primary.notexample.com"] 461 } 462 463 resource "aws_route53_record" "www-secondary" { 464 zone_id = "${aws_route53_zone.main.zone_id}" 465 name = "www" 466 type = "CNAME" 467 ttl = "5" 468 failover = "SECONDARY" 469 set_identifier = "www-secondary" 470 records = ["secondary.notexample.com"] 471 } 472 ` 473 474 const testAccRoute53WeightedCNAMERecord = ` 475 resource "aws_route53_zone" "main" { 476 name = "notexample.com" 477 } 478 479 resource "aws_route53_record" "www-dev" { 480 zone_id = "${aws_route53_zone.main.zone_id}" 481 name = "www" 482 type = "CNAME" 483 ttl = "5" 484 weight = 10 485 set_identifier = "dev" 486 records = ["dev.notexample.com"] 487 } 488 489 resource "aws_route53_record" "www-live" { 490 zone_id = "${aws_route53_zone.main.zone_id}" 491 name = "www" 492 type = "CNAME" 493 ttl = "5" 494 weight = 90 495 set_identifier = "live" 496 records = ["dev.notexample.com"] 497 } 498 499 resource "aws_route53_record" "www-off" { 500 zone_id = "${aws_route53_zone.main.zone_id}" 501 name = "www" 502 type = "CNAME" 503 ttl = "5" 504 weight = 0 505 set_identifier = "off" 506 records = ["dev.notexample.com"] 507 } 508 ` 509 510 const testAccRoute53ElbAliasRecord = ` 511 resource "aws_route53_zone" "main" { 512 name = "notexample.com" 513 } 514 515 resource "aws_route53_record" "alias" { 516 zone_id = "${aws_route53_zone.main.zone_id}" 517 name = "www" 518 type = "A" 519 520 alias { 521 zone_id = "${aws_elb.main.zone_id}" 522 name = "${aws_elb.main.dns_name}" 523 evaluate_target_health = true 524 } 525 } 526 527 resource "aws_elb" "main" { 528 name = "foobar-terraform-elb" 529 availability_zones = ["us-west-2a"] 530 531 listener { 532 instance_port = 80 533 instance_protocol = "http" 534 lb_port = 80 535 lb_protocol = "http" 536 } 537 } 538 ` 539 540 const testAccRoute53AliasRecord = ` 541 resource "aws_route53_zone" "main" { 542 name = "notexample.com" 543 } 544 545 resource "aws_route53_record" "origin" { 546 zone_id = "${aws_route53_zone.main.zone_id}" 547 name = "origin" 548 type = "A" 549 ttl = 5 550 records = ["127.0.0.1"] 551 } 552 553 resource "aws_route53_record" "alias" { 554 zone_id = "${aws_route53_zone.main.zone_id}" 555 name = "www" 556 type = "A" 557 558 alias { 559 zone_id = "${aws_route53_zone.main.zone_id}" 560 name = "${aws_route53_record.origin.name}.${aws_route53_zone.main.name}" 561 evaluate_target_health = true 562 } 563 } 564 ` 565 566 const testAccRoute53S3AliasRecord = ` 567 resource "aws_route53_zone" "main" { 568 name = "notexample.com" 569 } 570 571 resource "aws_s3_bucket" "website" { 572 bucket = "website.notexample.com" 573 acl = "public-read" 574 website { 575 index_document = "index.html" 576 } 577 } 578 579 resource "aws_route53_record" "alias" { 580 zone_id = "${aws_route53_zone.main.zone_id}" 581 name = "www" 582 type = "A" 583 584 alias { 585 zone_id = "${aws_s3_bucket.website.hosted_zone_id}" 586 name = "${aws_s3_bucket.website.website_domain}" 587 evaluate_target_health = true 588 } 589 } 590 ` 591 592 const testAccRoute53WeightedElbAliasRecord = ` 593 resource "aws_route53_zone" "main" { 594 name = "notexample.com" 595 } 596 597 resource "aws_elb" "live" { 598 name = "foobar-terraform-elb-live" 599 availability_zones = ["us-west-2a"] 600 601 listener { 602 instance_port = 80 603 instance_protocol = "http" 604 lb_port = 80 605 lb_protocol = "http" 606 } 607 } 608 609 resource "aws_route53_record" "elb_weighted_alias_live" { 610 zone_id = "${aws_route53_zone.main.zone_id}" 611 name = "www" 612 type = "A" 613 614 weight = 90 615 set_identifier = "live" 616 617 alias { 618 zone_id = "${aws_elb.live.zone_id}" 619 name = "${aws_elb.live.dns_name}" 620 evaluate_target_health = true 621 } 622 } 623 624 resource "aws_elb" "dev" { 625 name = "foobar-terraform-elb-dev" 626 availability_zones = ["us-west-2a"] 627 628 listener { 629 instance_port = 80 630 instance_protocol = "http" 631 lb_port = 80 632 lb_protocol = "http" 633 } 634 } 635 636 resource "aws_route53_record" "elb_weighted_alias_dev" { 637 zone_id = "${aws_route53_zone.main.zone_id}" 638 name = "www" 639 type = "A" 640 641 weight = 10 642 set_identifier = "dev" 643 644 alias { 645 zone_id = "${aws_elb.dev.zone_id}" 646 name = "${aws_elb.dev.dns_name}" 647 evaluate_target_health = true 648 } 649 } 650 ` 651 652 const testAccRoute53WeightedR53AliasRecord = ` 653 resource "aws_route53_zone" "main" { 654 name = "notexample.com" 655 } 656 657 resource "aws_route53_record" "blue_origin" { 658 zone_id = "${aws_route53_zone.main.zone_id}" 659 name = "blue-origin" 660 type = "CNAME" 661 ttl = 5 662 records = ["v1.terraform.io"] 663 } 664 665 resource "aws_route53_record" "r53_weighted_alias_live" { 666 zone_id = "${aws_route53_zone.main.zone_id}" 667 name = "www" 668 type = "CNAME" 669 670 weight = 90 671 set_identifier = "blue" 672 673 alias { 674 zone_id = "${aws_route53_zone.main.zone_id}" 675 name = "${aws_route53_record.blue_origin.name}.${aws_route53_zone.main.name}" 676 evaluate_target_health = false 677 } 678 } 679 680 resource "aws_route53_record" "green_origin" { 681 zone_id = "${aws_route53_zone.main.zone_id}" 682 name = "green-origin" 683 type = "CNAME" 684 ttl = 5 685 records = ["v2.terraform.io"] 686 } 687 688 resource "aws_route53_record" "r53_weighted_alias_dev" { 689 zone_id = "${aws_route53_zone.main.zone_id}" 690 name = "www" 691 type = "CNAME" 692 693 weight = 10 694 set_identifier = "green" 695 696 alias { 697 zone_id = "${aws_route53_zone.main.zone_id}" 698 name = "${aws_route53_record.green_origin.name}.${aws_route53_zone.main.name}" 699 evaluate_target_health = false 700 } 701 } 702 ` 703 704 const testAccRoute53RecordTypeChangePre = ` 705 resource "aws_route53_zone" "main" { 706 name = "notexample.com" 707 } 708 709 resource "aws_route53_record" "sample" { 710 zone_id = "${aws_route53_zone.main.zone_id}" 711 name = "sample" 712 type = "CNAME" 713 ttl = "30" 714 records = ["www.terraform.io"] 715 } 716 ` 717 718 const testAccRoute53RecordTypeChangePost = ` 719 resource "aws_route53_zone" "main" { 720 name = "notexample.com" 721 } 722 723 resource "aws_route53_record" "sample" { 724 zone_id = "${aws_route53_zone.main.zone_id}" 725 name = "sample" 726 type = "A" 727 ttl = "30" 728 records = ["127.0.0.1", "8.8.8.8"] 729 } 730 `