github.com/mikesimons/terraform@v0.6.13-0.20160304043642-f11448c69214/config/loader_test.go (about) 1 package config 2 3 import ( 4 "io/ioutil" 5 "path/filepath" 6 "reflect" 7 "strings" 8 "testing" 9 ) 10 11 func TestIsEmptyDir(t *testing.T) { 12 val, err := IsEmptyDir(fixtureDir) 13 if err != nil { 14 t.Fatalf("err: %s", err) 15 } 16 if val { 17 t.Fatal("should not be empty") 18 } 19 } 20 21 func TestIsEmptyDir_noExist(t *testing.T) { 22 val, err := IsEmptyDir(filepath.Join(fixtureDir, "nopenopenope")) 23 if err != nil { 24 t.Fatalf("err: %s", err) 25 } 26 if !val { 27 t.Fatal("should be empty") 28 } 29 } 30 31 func TestIsEmptyDir_noConfigs(t *testing.T) { 32 val, err := IsEmptyDir(filepath.Join(fixtureDir, "dir-empty")) 33 if err != nil { 34 t.Fatalf("err: %s", err) 35 } 36 if !val { 37 t.Fatal("should be empty") 38 } 39 } 40 41 func TestLoadFile_badType(t *testing.T) { 42 _, err := LoadFile(filepath.Join(fixtureDir, "bad_type.tf.nope")) 43 if err == nil { 44 t.Fatal("should have error") 45 } 46 } 47 48 func TestLoadFile_lifecycleKeyCheck(t *testing.T) { 49 _, err := LoadFile(filepath.Join(fixtureDir, "lifecycle_cbd_typo.tf")) 50 if err == nil { 51 t.Fatal("should have error") 52 } 53 54 t.Logf("err: %s", err) 55 } 56 57 func TestLoadFile_resourceArityMistake(t *testing.T) { 58 _, err := LoadFile(filepath.Join(fixtureDir, "resource-arity-mistake.tf")) 59 if err == nil { 60 t.Fatal("should have error") 61 } 62 expected := "Error loading test-fixtures/resource-arity-mistake.tf: position 2:10: resource must be followed by exactly two strings, a type and a name" 63 if err.Error() != expected { 64 t.Fatalf("expected:\n%s\ngot:\n%s", expected, err) 65 } 66 } 67 68 func TestLoadFileWindowsLineEndings(t *testing.T) { 69 testFile := filepath.Join(fixtureDir, "windows-line-endings.tf") 70 71 contents, err := ioutil.ReadFile(testFile) 72 if err != nil { 73 t.Fatalf("err: %s", err) 74 } 75 if !strings.Contains(string(contents), "\r\n") { 76 t.Fatalf("Windows line endings test file %s contains no windows line endings - this may be an autocrlf related issue.", testFile) 77 } 78 79 c, err := LoadFile(testFile) 80 if err != nil { 81 t.Fatalf("err: %s", err) 82 } 83 84 if c == nil { 85 t.Fatal("config should not be nil") 86 } 87 88 if c.Dir != "" { 89 t.Fatalf("bad: %#v", c.Dir) 90 } 91 92 actual := resourcesStr(c.Resources) 93 if actual != strings.TrimSpace(windowsHeredocResourcesStr) { 94 t.Fatalf("bad:\n%s", actual) 95 } 96 } 97 98 func TestLoadFileHeredoc(t *testing.T) { 99 c, err := LoadFile(filepath.Join(fixtureDir, "heredoc.tf")) 100 if err != nil { 101 t.Fatalf("err: %s", err) 102 } 103 104 if c == nil { 105 t.Fatal("config should not be nil") 106 } 107 108 if c.Dir != "" { 109 t.Fatalf("bad: %#v", c.Dir) 110 } 111 112 actual := providerConfigsStr(c.ProviderConfigs) 113 if actual != strings.TrimSpace(heredocProvidersStr) { 114 t.Fatalf("bad:\n%s", actual) 115 } 116 117 actual = resourcesStr(c.Resources) 118 if actual != strings.TrimSpace(heredocResourcesStr) { 119 t.Fatalf("bad:\n%s", actual) 120 } 121 } 122 123 func TestLoadFileEscapedQuotes(t *testing.T) { 124 c, err := LoadFile(filepath.Join(fixtureDir, "escapedquotes.tf")) 125 if err != nil { 126 t.Fatalf("err: %s", err) 127 } 128 129 if c == nil { 130 t.Fatal("config should not be nil") 131 } 132 133 if c.Dir != "" { 134 t.Fatalf("bad: %#v", c.Dir) 135 } 136 137 actual := resourcesStr(c.Resources) 138 if actual != strings.TrimSpace(escapedquotesResourcesStr) { 139 t.Fatalf("bad:\n%s", actual) 140 } 141 } 142 143 func TestLoadFileBasic(t *testing.T) { 144 c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf")) 145 if err != nil { 146 t.Fatalf("err: %s", err) 147 } 148 149 if c == nil { 150 t.Fatal("config should not be nil") 151 } 152 153 if c.Dir != "" { 154 t.Fatalf("bad: %#v", c.Dir) 155 } 156 157 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 158 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 159 t.Fatalf("bad: %#v", c.Atlas) 160 } 161 162 actual := variablesStr(c.Variables) 163 if actual != strings.TrimSpace(basicVariablesStr) { 164 t.Fatalf("bad:\n%s", actual) 165 } 166 167 actual = providerConfigsStr(c.ProviderConfigs) 168 if actual != strings.TrimSpace(basicProvidersStr) { 169 t.Fatalf("bad:\n%s", actual) 170 } 171 172 actual = resourcesStr(c.Resources) 173 if actual != strings.TrimSpace(basicResourcesStr) { 174 t.Fatalf("bad:\n%s", actual) 175 } 176 177 actual = outputsStr(c.Outputs) 178 if actual != strings.TrimSpace(basicOutputsStr) { 179 t.Fatalf("bad:\n%s", actual) 180 } 181 } 182 183 func TestLoadFileBasic_empty(t *testing.T) { 184 c, err := LoadFile(filepath.Join(fixtureDir, "empty.tf")) 185 if err != nil { 186 t.Fatalf("err: %s", err) 187 } 188 189 if c == nil { 190 t.Fatal("config should not be nil") 191 } 192 } 193 194 func TestLoadFileBasic_import(t *testing.T) { 195 // Skip because we disabled importing 196 t.Skip() 197 198 c, err := LoadFile(filepath.Join(fixtureDir, "import.tf")) 199 if err != nil { 200 t.Fatalf("err: %s", err) 201 } 202 203 if c == nil { 204 t.Fatal("config should not be nil") 205 } 206 207 actual := variablesStr(c.Variables) 208 if actual != strings.TrimSpace(importVariablesStr) { 209 t.Fatalf("bad:\n%s", actual) 210 } 211 212 actual = providerConfigsStr(c.ProviderConfigs) 213 if actual != strings.TrimSpace(importProvidersStr) { 214 t.Fatalf("bad:\n%s", actual) 215 } 216 217 actual = resourcesStr(c.Resources) 218 if actual != strings.TrimSpace(importResourcesStr) { 219 t.Fatalf("bad:\n%s", actual) 220 } 221 } 222 223 func TestLoadFileBasic_json(t *testing.T) { 224 c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf.json")) 225 if err != nil { 226 t.Fatalf("err: %s", err) 227 } 228 229 if c == nil { 230 t.Fatal("config should not be nil") 231 } 232 233 if c.Dir != "" { 234 t.Fatalf("bad: %#v", c.Dir) 235 } 236 237 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 238 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 239 t.Fatalf("bad: %#v", c.Atlas) 240 } 241 242 actual := variablesStr(c.Variables) 243 if actual != strings.TrimSpace(basicVariablesStr) { 244 t.Fatalf("bad:\n%s", actual) 245 } 246 247 actual = providerConfigsStr(c.ProviderConfigs) 248 if actual != strings.TrimSpace(basicProvidersStr) { 249 t.Fatalf("bad:\n%s", actual) 250 } 251 252 actual = resourcesStr(c.Resources) 253 if actual != strings.TrimSpace(basicResourcesStr) { 254 t.Fatalf("bad:\n%s", actual) 255 } 256 257 actual = outputsStr(c.Outputs) 258 if actual != strings.TrimSpace(basicOutputsStr) { 259 t.Fatalf("bad:\n%s", actual) 260 } 261 } 262 263 func TestLoadFileBasic_modules(t *testing.T) { 264 c, err := LoadFile(filepath.Join(fixtureDir, "modules.tf")) 265 if err != nil { 266 t.Fatalf("err: %s", err) 267 } 268 269 if c == nil { 270 t.Fatal("config should not be nil") 271 } 272 273 if c.Dir != "" { 274 t.Fatalf("bad: %#v", c.Dir) 275 } 276 277 actual := modulesStr(c.Modules) 278 if actual != strings.TrimSpace(modulesModulesStr) { 279 t.Fatalf("bad:\n%s", actual) 280 } 281 } 282 283 func TestLoadJSONBasic(t *testing.T) { 284 raw, err := ioutil.ReadFile(filepath.Join(fixtureDir, "basic.tf.json")) 285 if err != nil { 286 t.Fatalf("err: %s", err) 287 } 288 289 c, err := LoadJSON(raw) 290 if err != nil { 291 t.Fatalf("err: %s", err) 292 } 293 294 if c == nil { 295 t.Fatal("config should not be nil") 296 } 297 298 if c.Dir != "" { 299 t.Fatalf("bad: %#v", c.Dir) 300 } 301 302 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 303 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 304 t.Fatalf("bad: %#v", c.Atlas) 305 } 306 307 actual := variablesStr(c.Variables) 308 if actual != strings.TrimSpace(basicVariablesStr) { 309 t.Fatalf("bad:\n%s", actual) 310 } 311 312 actual = providerConfigsStr(c.ProviderConfigs) 313 if actual != strings.TrimSpace(basicProvidersStr) { 314 t.Fatalf("bad:\n%s", actual) 315 } 316 317 actual = resourcesStr(c.Resources) 318 if actual != strings.TrimSpace(basicResourcesStr) { 319 t.Fatalf("bad:\n%s", actual) 320 } 321 322 actual = outputsStr(c.Outputs) 323 if actual != strings.TrimSpace(basicOutputsStr) { 324 t.Fatalf("bad:\n%s", actual) 325 } 326 } 327 328 func TestLoadFile_variables(t *testing.T) { 329 c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf")) 330 if err != nil { 331 t.Fatalf("err: %s", err) 332 } 333 if c == nil { 334 t.Fatal("config should not be nil") 335 } 336 337 if c.Dir != "" { 338 t.Fatalf("bad: %#v", c.Dir) 339 } 340 341 actual := variablesStr(c.Variables) 342 if actual != strings.TrimSpace(variablesVariablesStr) { 343 t.Fatalf("bad:\n%s", actual) 344 } 345 } 346 347 func TestLoadDir_basic(t *testing.T) { 348 dir := filepath.Join(fixtureDir, "dir-basic") 349 c, err := LoadDir(dir) 350 if err != nil { 351 t.Fatalf("err: %s", err) 352 } 353 354 if c == nil { 355 t.Fatal("config should not be nil") 356 } 357 358 dirAbs, err := filepath.Abs(dir) 359 if err != nil { 360 t.Fatalf("err: %s", err) 361 } 362 if c.Dir != dirAbs { 363 t.Fatalf("bad: %#v", c.Dir) 364 } 365 366 actual := variablesStr(c.Variables) 367 if actual != strings.TrimSpace(dirBasicVariablesStr) { 368 t.Fatalf("bad:\n%s", actual) 369 } 370 371 actual = providerConfigsStr(c.ProviderConfigs) 372 if actual != strings.TrimSpace(dirBasicProvidersStr) { 373 t.Fatalf("bad:\n%s", actual) 374 } 375 376 actual = resourcesStr(c.Resources) 377 if actual != strings.TrimSpace(dirBasicResourcesStr) { 378 t.Fatalf("bad:\n%s", actual) 379 } 380 381 actual = outputsStr(c.Outputs) 382 if actual != strings.TrimSpace(dirBasicOutputsStr) { 383 t.Fatalf("bad:\n%s", actual) 384 } 385 } 386 387 func TestLoadDir_file(t *testing.T) { 388 _, err := LoadDir(filepath.Join(fixtureDir, "variables.tf")) 389 if err == nil { 390 t.Fatal("should error") 391 } 392 } 393 394 func TestLoadDir_noConfigs(t *testing.T) { 395 _, err := LoadDir(filepath.Join(fixtureDir, "dir-empty")) 396 if err == nil { 397 t.Fatal("should error") 398 } 399 } 400 401 func TestLoadDir_noMerge(t *testing.T) { 402 c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge")) 403 if err != nil { 404 t.Fatalf("err: %s", err) 405 } 406 407 if c == nil { 408 t.Fatal("config should not be nil") 409 } 410 411 if err := c.Validate(); err == nil { 412 t.Fatal("should not be valid") 413 } 414 } 415 416 func TestLoadDir_override(t *testing.T) { 417 c, err := LoadDir(filepath.Join(fixtureDir, "dir-override")) 418 if err != nil { 419 t.Fatalf("err: %s", err) 420 } 421 422 if c == nil { 423 t.Fatal("config should not be nil") 424 } 425 426 actual := variablesStr(c.Variables) 427 if actual != strings.TrimSpace(dirOverrideVariablesStr) { 428 t.Fatalf("bad:\n%s", actual) 429 } 430 431 actual = providerConfigsStr(c.ProviderConfigs) 432 if actual != strings.TrimSpace(dirOverrideProvidersStr) { 433 t.Fatalf("bad:\n%s", actual) 434 } 435 436 actual = resourcesStr(c.Resources) 437 if actual != strings.TrimSpace(dirOverrideResourcesStr) { 438 t.Fatalf("bad:\n%s", actual) 439 } 440 441 actual = outputsStr(c.Outputs) 442 if actual != strings.TrimSpace(dirOverrideOutputsStr) { 443 t.Fatalf("bad:\n%s", actual) 444 } 445 } 446 447 func TestLoadFile_mismatchedVariableTypes(t *testing.T) { 448 _, err := LoadFile(filepath.Join(fixtureDir, "variable-mismatched-type.tf")) 449 if err == nil { 450 t.Fatalf("bad: expected error") 451 } 452 453 errorStr := err.Error() 454 if !strings.Contains(errorStr, "'not_a_map' has a default value which is not of type 'string'") { 455 t.Fatalf("bad: expected error has wrong text: %s", errorStr) 456 } 457 } 458 459 func TestLoadFile_badVariableTypes(t *testing.T) { 460 _, err := LoadFile(filepath.Join(fixtureDir, "bad-variable-type.tf")) 461 if err == nil { 462 t.Fatalf("bad: expected error") 463 } 464 465 errorStr := err.Error() 466 if !strings.Contains(errorStr, "'bad_type' must be of type string") { 467 t.Fatalf("bad: expected error has wrong text: %s", errorStr) 468 } 469 } 470 471 func TestLoadFile_provisioners(t *testing.T) { 472 c, err := LoadFile(filepath.Join(fixtureDir, "provisioners.tf")) 473 if err != nil { 474 t.Fatalf("err: %s", err) 475 } 476 477 if c == nil { 478 t.Fatal("config should not be nil") 479 } 480 481 actual := resourcesStr(c.Resources) 482 if actual != strings.TrimSpace(provisionerResourcesStr) { 483 t.Fatalf("bad:\n%s", actual) 484 } 485 } 486 487 func TestLoadFile_connections(t *testing.T) { 488 c, err := LoadFile(filepath.Join(fixtureDir, "connection.tf")) 489 if err != nil { 490 t.Fatalf("err: %s", err) 491 } 492 493 if c == nil { 494 t.Fatal("config should not be nil") 495 } 496 497 actual := resourcesStr(c.Resources) 498 if actual != strings.TrimSpace(connectionResourcesStr) { 499 t.Fatalf("bad:\n%s", actual) 500 } 501 502 // Check for the connection info 503 r := c.Resources[0] 504 if r.Name != "web" && r.Type != "aws_instance" { 505 t.Fatalf("Bad: %#v", r) 506 } 507 508 p1 := r.Provisioners[0] 509 if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 { 510 t.Fatalf("Bad: %#v", p1.ConnInfo) 511 } 512 if p1.ConnInfo.Raw["user"] != "nobody" { 513 t.Fatalf("Bad: %#v", p1.ConnInfo) 514 } 515 516 p2 := r.Provisioners[1] 517 if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 { 518 t.Fatalf("Bad: %#v", p2.ConnInfo) 519 } 520 if p2.ConnInfo.Raw["user"] != "root" { 521 t.Fatalf("Bad: %#v", p2.ConnInfo) 522 } 523 } 524 525 func TestLoadFile_createBeforeDestroy(t *testing.T) { 526 c, err := LoadFile(filepath.Join(fixtureDir, "create-before-destroy.tf")) 527 if err != nil { 528 t.Fatalf("err: %s", err) 529 } 530 531 if c == nil { 532 t.Fatal("config should not be nil") 533 } 534 535 actual := resourcesStr(c.Resources) 536 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 537 t.Fatalf("bad:\n%s", actual) 538 } 539 540 // Check for the flag value 541 r := c.Resources[0] 542 if r.Name != "web" && r.Type != "aws_instance" { 543 t.Fatalf("Bad: %#v", r) 544 } 545 546 // Should enable create before destroy 547 if !r.Lifecycle.CreateBeforeDestroy { 548 t.Fatalf("Bad: %#v", r) 549 } 550 551 r = c.Resources[1] 552 if r.Name != "bar" && r.Type != "aws_instance" { 553 t.Fatalf("Bad: %#v", r) 554 } 555 556 // Should not enable create before destroy 557 if r.Lifecycle.CreateBeforeDestroy { 558 t.Fatalf("Bad: %#v", r) 559 } 560 } 561 562 func TestLoadFile_ignoreChanges(t *testing.T) { 563 c, err := LoadFile(filepath.Join(fixtureDir, "ignore-changes.tf")) 564 if err != nil { 565 t.Fatalf("err: %s", err) 566 } 567 568 if c == nil { 569 t.Fatal("config should not be nil") 570 } 571 572 actual := resourcesStr(c.Resources) 573 print(actual) 574 if actual != strings.TrimSpace(ignoreChangesResourcesStr) { 575 t.Fatalf("bad:\n%s", actual) 576 } 577 578 // Check for the flag value 579 r := c.Resources[0] 580 if r.Name != "web" && r.Type != "aws_instance" { 581 t.Fatalf("Bad: %#v", r) 582 } 583 584 // Should populate ignore changes 585 if len(r.Lifecycle.IgnoreChanges) == 0 { 586 t.Fatalf("Bad: %#v", r) 587 } 588 589 r = c.Resources[1] 590 if r.Name != "bar" && r.Type != "aws_instance" { 591 t.Fatalf("Bad: %#v", r) 592 } 593 594 // Should not populate ignore changes 595 if len(r.Lifecycle.IgnoreChanges) > 0 { 596 t.Fatalf("Bad: %#v", r) 597 } 598 599 r = c.Resources[2] 600 if r.Name != "baz" && r.Type != "aws_instance" { 601 t.Fatalf("Bad: %#v", r) 602 } 603 604 // Should not populate ignore changes 605 if len(r.Lifecycle.IgnoreChanges) > 0 { 606 t.Fatalf("Bad: %#v", r) 607 } 608 } 609 610 func TestLoad_preventDestroyString(t *testing.T) { 611 c, err := LoadFile(filepath.Join(fixtureDir, "prevent-destroy-string.tf")) 612 if err != nil { 613 t.Fatalf("err: %s", err) 614 } 615 616 if c == nil { 617 t.Fatal("config should not be nil") 618 } 619 620 actual := resourcesStr(c.Resources) 621 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 622 t.Fatalf("bad:\n%s", actual) 623 } 624 625 // Check for the flag value 626 r := c.Resources[0] 627 if r.Name != "web" && r.Type != "aws_instance" { 628 t.Fatalf("Bad: %#v", r) 629 } 630 631 // Should enable create before destroy 632 if !r.Lifecycle.PreventDestroy { 633 t.Fatalf("Bad: %#v", r) 634 } 635 636 r = c.Resources[1] 637 if r.Name != "bar" && r.Type != "aws_instance" { 638 t.Fatalf("Bad: %#v", r) 639 } 640 641 // Should not enable create before destroy 642 if r.Lifecycle.PreventDestroy { 643 t.Fatalf("Bad: %#v", r) 644 } 645 } 646 647 func TestLoad_temporary_files(t *testing.T) { 648 _, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files")) 649 if err == nil { 650 t.Fatalf("Expected to see an error stating no config files found") 651 } 652 } 653 654 func TestLoad_hclAttributes(t *testing.T) { 655 c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf")) 656 if err != nil { 657 t.Fatalf("Bad: %s", err) 658 } 659 660 if c == nil { 661 t.Fatal("config should not be nil") 662 } 663 664 actual := resourcesStr(c.Resources) 665 print(actual) 666 if actual != strings.TrimSpace(jsonAttributeStr) { 667 t.Fatalf("bad:\n%s", actual) 668 } 669 670 r := c.Resources[0] 671 if r.Name != "test" && r.Type != "cloudstack_firewall" { 672 t.Fatalf("Bad: %#v", r) 673 } 674 675 raw := r.RawConfig 676 if raw.Raw["ipaddress"] != "192.168.0.1" { 677 t.Fatalf("Bad: %s", raw.Raw["ipAddress"]) 678 } 679 680 rule := raw.Raw["rule"].([]map[string]interface{})[0] 681 if rule["protocol"] != "tcp" { 682 t.Fatalf("Bad: %s", rule["protocol"]) 683 } 684 685 if rule["source_cidr"] != "10.0.0.0/8" { 686 t.Fatalf("Bad: %s", rule["source_cidr"]) 687 } 688 689 ports := rule["ports"].([]interface{}) 690 691 if ports[0] != "80" { 692 t.Fatalf("Bad ports: %s", ports[0]) 693 } 694 if ports[1] != "1000-2000" { 695 t.Fatalf("Bad ports: %s", ports[1]) 696 } 697 } 698 699 func TestLoad_jsonAttributes(t *testing.T) { 700 c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf.json")) 701 if err != nil { 702 t.Fatalf("Bad: %s", err) 703 } 704 705 if c == nil { 706 t.Fatal("config should not be nil") 707 } 708 709 actual := resourcesStr(c.Resources) 710 print(actual) 711 if actual != strings.TrimSpace(jsonAttributeStr) { 712 t.Fatalf("bad:\n%s", actual) 713 } 714 715 r := c.Resources[0] 716 if r.Name != "test" && r.Type != "cloudstack_firewall" { 717 t.Fatalf("Bad: %#v", r) 718 } 719 720 raw := r.RawConfig 721 if raw.Raw["ipaddress"] != "192.168.0.1" { 722 t.Fatalf("Bad: %s", raw.Raw["ipAddress"]) 723 } 724 725 rule := raw.Raw["rule"].([]map[string]interface{})[0] 726 if rule["protocol"] != "tcp" { 727 t.Fatalf("Bad: %s", rule["protocol"]) 728 } 729 730 if rule["source_cidr"] != "10.0.0.0/8" { 731 t.Fatalf("Bad: %s", rule["source_cidr"]) 732 } 733 734 ports := rule["ports"].([]interface{}) 735 736 if ports[0] != "80" { 737 t.Fatalf("Bad ports: %s", ports[0]) 738 } 739 if ports[1] != "1000-2000" { 740 t.Fatalf("Bad ports: %s", ports[1]) 741 } 742 } 743 744 const jsonAttributeStr = ` 745 cloudstack_firewall[test] (x1) 746 ipaddress 747 rule 748 ` 749 750 const windowsHeredocResourcesStr = ` 751 aws_instance[test] (x1) 752 user_data 753 ` 754 755 const heredocProvidersStr = ` 756 aws 757 access_key 758 secret_key 759 ` 760 761 const heredocResourcesStr = ` 762 aws_iam_policy[policy] (x1) 763 description 764 name 765 path 766 policy 767 aws_instance[heredocwithnumbers] (x1) 768 ami 769 provisioners 770 local-exec 771 command 772 aws_instance[test] (x1) 773 ami 774 provisioners 775 remote-exec 776 inline 777 ` 778 779 const escapedquotesResourcesStr = ` 780 aws_instance[quotes] (x1) 781 ami 782 vars 783 user: var.ami 784 ` 785 786 const basicOutputsStr = ` 787 web_ip 788 vars 789 resource: aws_instance.web.private_ip 790 ` 791 792 const basicProvidersStr = ` 793 aws 794 access_key 795 secret_key 796 do 797 api_key 798 vars 799 user: var.foo 800 ` 801 802 const basicResourcesStr = ` 803 aws_instance[db] (x1) 804 VPC 805 security_groups 806 provisioners 807 file 808 destination 809 source 810 dependsOn 811 aws_instance.web 812 vars 813 resource: aws_security_group.firewall.*.id 814 aws_instance[web] (x1) 815 ami 816 network_interface 817 security_groups 818 provisioners 819 file 820 destination 821 source 822 vars 823 resource: aws_security_group.firewall.foo 824 user: var.foo 825 aws_security_group[firewall] (x5) 826 ` 827 828 const basicVariablesStr = ` 829 bar (required) (string) 830 <> 831 <> 832 baz (map) 833 map[key:value] 834 <> 835 foo 836 bar 837 bar 838 ` 839 840 const dirBasicOutputsStr = ` 841 web_ip 842 vars 843 resource: aws_instance.web.private_ip 844 ` 845 846 const dirBasicProvidersStr = ` 847 aws 848 access_key 849 secret_key 850 do 851 api_key 852 vars 853 user: var.foo 854 ` 855 856 const dirBasicResourcesStr = ` 857 aws_instance[db] (x1) 858 security_groups 859 vars 860 resource: aws_security_group.firewall.*.id 861 aws_instance[web] (x1) 862 ami 863 network_interface 864 security_groups 865 vars 866 resource: aws_security_group.firewall.foo 867 user: var.foo 868 aws_security_group[firewall] (x5) 869 ` 870 871 const dirBasicVariablesStr = ` 872 foo 873 bar 874 bar 875 ` 876 877 const dirOverrideOutputsStr = ` 878 web_ip 879 vars 880 resource: aws_instance.web.private_ip 881 ` 882 883 const dirOverrideProvidersStr = ` 884 aws 885 access_key 886 secret_key 887 do 888 api_key 889 vars 890 user: var.foo 891 ` 892 893 const dirOverrideResourcesStr = ` 894 aws_instance[db] (x1) 895 ami 896 security_groups 897 aws_instance[web] (x1) 898 ami 899 foo 900 network_interface 901 security_groups 902 vars 903 resource: aws_security_group.firewall.foo 904 user: var.foo 905 aws_security_group[firewall] (x5) 906 ` 907 908 const dirOverrideVariablesStr = ` 909 foo 910 bar 911 bar 912 ` 913 914 const importProvidersStr = ` 915 aws 916 bar 917 foo 918 ` 919 920 const importResourcesStr = ` 921 aws_security_group[db] (x1) 922 aws_security_group[web] (x1) 923 ` 924 925 const importVariablesStr = ` 926 bar (required) 927 <> 928 <> 929 foo 930 bar 931 bar 932 ` 933 934 const modulesModulesStr = ` 935 bar 936 source = baz 937 memory 938 ` 939 940 const provisionerResourcesStr = ` 941 aws_instance[web] (x1) 942 ami 943 security_groups 944 provisioners 945 shell 946 path 947 vars 948 resource: aws_security_group.firewall.foo 949 user: var.foo 950 ` 951 952 const connectionResourcesStr = ` 953 aws_instance[web] (x1) 954 ami 955 security_groups 956 provisioners 957 shell 958 path 959 shell 960 path 961 vars 962 resource: aws_security_group.firewall.foo 963 user: var.foo 964 ` 965 966 const variablesVariablesStr = ` 967 bar 968 <> 969 <> 970 baz 971 foo 972 <> 973 foo (required) 974 <> 975 <> 976 ` 977 978 const createBeforeDestroyResourcesStr = ` 979 aws_instance[bar] (x1) 980 ami 981 aws_instance[web] (x1) 982 ami 983 ` 984 985 const ignoreChangesResourcesStr = ` 986 aws_instance[bar] (x1) 987 ami 988 aws_instance[baz] (x1) 989 ami 990 aws_instance[web] (x1) 991 ami 992 `