github.com/hugorut/terraform@v1.1.3/src/terraform/context_import_test.go (about) 1 package terraform 2 3 import ( 4 "errors" 5 "strings" 6 "testing" 7 8 "github.com/hugorut/terraform/src/addrs" 9 "github.com/hugorut/terraform/src/configs/configschema" 10 "github.com/hugorut/terraform/src/providers" 11 "github.com/hugorut/terraform/src/states" 12 "github.com/zclconf/go-cty/cty" 13 ) 14 15 func TestContextImport_basic(t *testing.T) { 16 p := testProvider("aws") 17 m := testModule(t, "import-provider") 18 ctx := testContext2(t, &ContextOpts{ 19 Providers: map[addrs.Provider]providers.Factory{ 20 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 21 }, 22 }) 23 24 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 25 ImportedResources: []providers.ImportedResource{ 26 { 27 TypeName: "aws_instance", 28 State: cty.ObjectVal(map[string]cty.Value{ 29 "id": cty.StringVal("foo"), 30 }), 31 }, 32 }, 33 } 34 35 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 36 Targets: []*ImportTarget{ 37 { 38 Addr: addrs.RootModuleInstance.ResourceInstance( 39 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 40 ), 41 ID: "bar", 42 }, 43 }, 44 }) 45 if diags.HasErrors() { 46 t.Fatalf("unexpected errors: %s", diags.Err()) 47 } 48 actual := strings.TrimSpace(state.String()) 49 expected := strings.TrimSpace(testImportStr) 50 if actual != expected { 51 t.Fatalf("wrong final state\ngot:\n%s\nwant:\n%s", actual, expected) 52 } 53 } 54 55 func TestContextImport_countIndex(t *testing.T) { 56 p := testProvider("aws") 57 m := testModule(t, "import-provider") 58 ctx := testContext2(t, &ContextOpts{ 59 Providers: map[addrs.Provider]providers.Factory{ 60 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 61 }, 62 }) 63 64 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 65 ImportedResources: []providers.ImportedResource{ 66 { 67 TypeName: "aws_instance", 68 State: cty.ObjectVal(map[string]cty.Value{ 69 "id": cty.StringVal("foo"), 70 }), 71 }, 72 }, 73 } 74 75 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 76 Targets: []*ImportTarget{ 77 { 78 Addr: addrs.RootModuleInstance.ResourceInstance( 79 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.IntKey(0), 80 ), 81 ID: "bar", 82 }, 83 }, 84 }) 85 if diags.HasErrors() { 86 t.Fatalf("unexpected errors: %s", diags.Err()) 87 } 88 89 actual := strings.TrimSpace(state.String()) 90 expected := strings.TrimSpace(testImportCountIndexStr) 91 if actual != expected { 92 t.Fatalf("bad: \n%s", actual) 93 } 94 } 95 96 func TestContextImport_collision(t *testing.T) { 97 p := testProvider("aws") 98 m := testModule(t, "import-provider") 99 ctx := testContext2(t, &ContextOpts{ 100 Providers: map[addrs.Provider]providers.Factory{ 101 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 102 }, 103 }) 104 105 state := states.BuildState(func(s *states.SyncState) { 106 s.SetResourceInstanceCurrent( 107 addrs.Resource{ 108 Mode: addrs.ManagedResourceMode, 109 Type: "aws_instance", 110 Name: "foo", 111 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 112 &states.ResourceInstanceObjectSrc{ 113 AttrsFlat: map[string]string{ 114 "id": "bar", 115 }, 116 Status: states.ObjectReady, 117 }, 118 addrs.AbsProviderConfig{ 119 Provider: addrs.NewDefaultProvider("aws"), 120 Module: addrs.RootModule, 121 }, 122 ) 123 }) 124 125 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 126 ImportedResources: []providers.ImportedResource{ 127 { 128 TypeName: "aws_instance", 129 State: cty.ObjectVal(map[string]cty.Value{ 130 "id": cty.StringVal("foo"), 131 }), 132 }, 133 }, 134 } 135 136 state, diags := ctx.Import(m, state, &ImportOpts{ 137 Targets: []*ImportTarget{ 138 { 139 Addr: addrs.RootModuleInstance.ResourceInstance( 140 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 141 ), 142 ID: "bar", 143 }, 144 }, 145 }) 146 if !diags.HasErrors() { 147 t.Fatalf("succeeded; want an error indicating that the resource already exists in state") 148 } 149 150 actual := strings.TrimSpace(state.String()) 151 expected := `aws_instance.foo: 152 ID = bar 153 provider = provider["registry.terraform.io/hashicorp/aws"]` 154 155 if actual != expected { 156 t.Fatalf("bad: \n%s", actual) 157 } 158 } 159 160 func TestContextImport_missingType(t *testing.T) { 161 p := testProvider("aws") 162 m := testModule(t, "import-provider") 163 164 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 165 ImportedResources: []providers.ImportedResource{ 166 { 167 State: cty.ObjectVal(map[string]cty.Value{ 168 "id": cty.StringVal("foo"), 169 }), 170 }, 171 }, 172 } 173 174 ctx := testContext2(t, &ContextOpts{ 175 Providers: map[addrs.Provider]providers.Factory{ 176 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 177 }, 178 }) 179 180 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 181 Targets: []*ImportTarget{ 182 { 183 Addr: addrs.RootModuleInstance.ResourceInstance( 184 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 185 ), 186 ID: "bar", 187 }, 188 }, 189 }) 190 if !diags.HasErrors() { 191 t.Fatal("should error") 192 } 193 194 actual := strings.TrimSpace(state.String()) 195 expected := "<no state>" 196 if actual != expected { 197 t.Fatalf("bad: \n%s", actual) 198 } 199 } 200 201 func TestContextImport_moduleProvider(t *testing.T) { 202 p := testProvider("aws") 203 204 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 205 ImportedResources: []providers.ImportedResource{ 206 { 207 TypeName: "aws_instance", 208 State: cty.ObjectVal(map[string]cty.Value{ 209 "id": cty.StringVal("foo"), 210 }), 211 }, 212 }, 213 } 214 215 p.ConfigureProviderFn = func(req providers.ConfigureProviderRequest) (resp providers.ConfigureProviderResponse) { 216 foo := req.Config.GetAttr("foo").AsString() 217 if foo != "bar" { 218 resp.Diagnostics = resp.Diagnostics.Append(errors.New("not bar")) 219 } 220 221 return 222 } 223 224 m := testModule(t, "import-provider") 225 ctx := testContext2(t, &ContextOpts{ 226 Providers: map[addrs.Provider]providers.Factory{ 227 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 228 }, 229 }) 230 231 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 232 Targets: []*ImportTarget{ 233 { 234 Addr: addrs.RootModuleInstance.ResourceInstance( 235 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 236 ), 237 ID: "bar", 238 }, 239 }, 240 }) 241 if diags.HasErrors() { 242 t.Fatalf("unexpected errors: %s", diags.Err()) 243 } 244 245 if !p.ConfigureProviderCalled { 246 t.Fatal("didn't configure provider") 247 } 248 249 actual := strings.TrimSpace(state.String()) 250 expected := strings.TrimSpace(testImportStr) 251 if actual != expected { 252 t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual) 253 } 254 } 255 256 // Importing into a module requires a provider config in that module. 257 func TestContextImport_providerModule(t *testing.T) { 258 p := testProvider("aws") 259 m := testModule(t, "import-module") 260 ctx := testContext2(t, &ContextOpts{ 261 Providers: map[addrs.Provider]providers.Factory{ 262 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 263 }, 264 }) 265 266 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 267 ImportedResources: []providers.ImportedResource{ 268 { 269 TypeName: "aws_instance", 270 State: cty.ObjectVal(map[string]cty.Value{ 271 "id": cty.StringVal("foo"), 272 }), 273 }, 274 }, 275 } 276 277 p.ConfigureProviderFn = func(req providers.ConfigureProviderRequest) (resp providers.ConfigureProviderResponse) { 278 foo := req.Config.GetAttr("foo").AsString() 279 if foo != "bar" { 280 resp.Diagnostics = resp.Diagnostics.Append(errors.New("not bar")) 281 } 282 283 return 284 } 285 286 _, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 287 Targets: []*ImportTarget{ 288 { 289 Addr: addrs.RootModuleInstance.Child("child", addrs.NoKey).ResourceInstance( 290 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 291 ), 292 ID: "bar", 293 }, 294 }, 295 }) 296 if diags.HasErrors() { 297 t.Fatalf("unexpected errors: %s", diags.Err()) 298 } 299 300 if !p.ConfigureProviderCalled { 301 t.Fatal("didn't configure provider") 302 } 303 } 304 305 // Test that import will interpolate provider configuration and use 306 // that configuration for import. 307 func TestContextImport_providerConfig(t *testing.T) { 308 testCases := map[string]struct { 309 module string 310 value string 311 }{ 312 "variables": { 313 module: "import-provider-vars", 314 value: "bar", 315 }, 316 "locals": { 317 module: "import-provider-locals", 318 value: "baz-bar", 319 }, 320 } 321 for name, test := range testCases { 322 t.Run(name, func(t *testing.T) { 323 p := testProvider("aws") 324 m := testModule(t, test.module) 325 ctx := testContext2(t, &ContextOpts{ 326 Providers: map[addrs.Provider]providers.Factory{ 327 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 328 }, 329 }) 330 331 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 332 ImportedResources: []providers.ImportedResource{ 333 { 334 TypeName: "aws_instance", 335 State: cty.ObjectVal(map[string]cty.Value{ 336 "id": cty.StringVal("foo"), 337 }), 338 }, 339 }, 340 } 341 342 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 343 Targets: []*ImportTarget{ 344 { 345 Addr: addrs.RootModuleInstance.ResourceInstance( 346 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 347 ), 348 ID: "bar", 349 }, 350 }, 351 SetVariables: InputValues{ 352 "foo": &InputValue{ 353 Value: cty.StringVal("bar"), 354 SourceType: ValueFromCaller, 355 }, 356 }, 357 }) 358 if diags.HasErrors() { 359 t.Fatalf("unexpected errors: %s", diags.Err()) 360 } 361 362 if !p.ConfigureProviderCalled { 363 t.Fatal("didn't configure provider") 364 } 365 366 if foo := p.ConfigureProviderRequest.Config.GetAttr("foo").AsString(); foo != test.value { 367 t.Fatalf("bad value %#v; want %#v", foo, test.value) 368 } 369 370 actual := strings.TrimSpace(state.String()) 371 expected := strings.TrimSpace(testImportStr) 372 if actual != expected { 373 t.Fatalf("bad: \n%s", actual) 374 } 375 }) 376 } 377 } 378 379 // Test that provider configs can't reference resources. 380 func TestContextImport_providerConfigResources(t *testing.T) { 381 p := testProvider("aws") 382 pTest := testProvider("test") 383 m := testModule(t, "import-provider-resources") 384 ctx := testContext2(t, &ContextOpts{ 385 Providers: map[addrs.Provider]providers.Factory{ 386 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 387 addrs.NewDefaultProvider("test"): testProviderFuncFixed(pTest), 388 }, 389 }) 390 391 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 392 ImportedResources: []providers.ImportedResource{ 393 { 394 TypeName: "aws_instance", 395 State: cty.ObjectVal(map[string]cty.Value{ 396 "id": cty.StringVal("foo"), 397 }), 398 }, 399 }, 400 } 401 402 _, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 403 Targets: []*ImportTarget{ 404 { 405 Addr: addrs.RootModuleInstance.ResourceInstance( 406 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 407 ), 408 ID: "bar", 409 }, 410 }, 411 }) 412 if !diags.HasErrors() { 413 t.Fatal("should error") 414 } 415 if got, want := diags.Err().Error(), `The configuration for provider["registry.terraform.io/hashicorp/aws"] depends on values that cannot be determined until apply.`; !strings.Contains(got, want) { 416 t.Errorf("wrong error\n got: %s\nwant: %s", got, want) 417 } 418 } 419 420 func TestContextImport_refresh(t *testing.T) { 421 p := testProvider("aws") 422 m := testModule(t, "import-provider") 423 ctx := testContext2(t, &ContextOpts{ 424 Providers: map[addrs.Provider]providers.Factory{ 425 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 426 }, 427 }) 428 429 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 430 ImportedResources: []providers.ImportedResource{ 431 { 432 TypeName: "aws_instance", 433 State: cty.ObjectVal(map[string]cty.Value{ 434 "id": cty.StringVal("foo"), 435 }), 436 }, 437 }, 438 } 439 440 p.ReadResourceFn = nil 441 442 p.ReadResourceResponse = &providers.ReadResourceResponse{ 443 NewState: cty.ObjectVal(map[string]cty.Value{ 444 "id": cty.StringVal("foo"), 445 "foo": cty.StringVal("bar"), 446 }), 447 } 448 449 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 450 Targets: []*ImportTarget{ 451 { 452 Addr: addrs.RootModuleInstance.ResourceInstance( 453 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 454 ), 455 ID: "bar", 456 }, 457 }, 458 }) 459 if diags.HasErrors() { 460 t.Fatalf("unexpected errors: %s", diags.Err()) 461 } 462 463 actual := strings.TrimSpace(state.String()) 464 expected := strings.TrimSpace(testImportRefreshStr) 465 if actual != expected { 466 t.Fatalf("bad: \n%s", actual) 467 } 468 } 469 470 func TestContextImport_refreshNil(t *testing.T) { 471 p := testProvider("aws") 472 m := testModule(t, "import-provider") 473 ctx := testContext2(t, &ContextOpts{ 474 Providers: map[addrs.Provider]providers.Factory{ 475 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 476 }, 477 }) 478 479 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 480 ImportedResources: []providers.ImportedResource{ 481 { 482 TypeName: "aws_instance", 483 State: cty.ObjectVal(map[string]cty.Value{ 484 "id": cty.StringVal("foo"), 485 }), 486 }, 487 }, 488 } 489 490 p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse { 491 return providers.ReadResourceResponse{ 492 NewState: cty.NullVal(cty.DynamicPseudoType), 493 } 494 } 495 496 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 497 Targets: []*ImportTarget{ 498 { 499 Addr: addrs.RootModuleInstance.ResourceInstance( 500 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 501 ), 502 ID: "bar", 503 }, 504 }, 505 }) 506 if !diags.HasErrors() { 507 t.Fatal("should error") 508 } 509 510 actual := strings.TrimSpace(state.String()) 511 expected := "<no state>" 512 if actual != expected { 513 t.Fatalf("bad: \n%s", actual) 514 } 515 } 516 517 func TestContextImport_module(t *testing.T) { 518 p := testProvider("aws") 519 m := testModule(t, "import-module") 520 ctx := testContext2(t, &ContextOpts{ 521 Providers: map[addrs.Provider]providers.Factory{ 522 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 523 }, 524 }) 525 526 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 527 ImportedResources: []providers.ImportedResource{ 528 { 529 TypeName: "aws_instance", 530 State: cty.ObjectVal(map[string]cty.Value{ 531 "id": cty.StringVal("foo"), 532 }), 533 }, 534 }, 535 } 536 537 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 538 Targets: []*ImportTarget{ 539 { 540 Addr: addrs.RootModuleInstance.Child("child", addrs.IntKey(0)).ResourceInstance( 541 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 542 ), 543 ID: "bar", 544 }, 545 }, 546 }) 547 if diags.HasErrors() { 548 t.Fatalf("unexpected errors: %s", diags.Err()) 549 } 550 551 actual := strings.TrimSpace(state.String()) 552 expected := strings.TrimSpace(testImportModuleStr) 553 if actual != expected { 554 t.Fatalf("bad: \n%s", actual) 555 } 556 } 557 558 func TestContextImport_moduleDepth2(t *testing.T) { 559 p := testProvider("aws") 560 m := testModule(t, "import-module") 561 ctx := testContext2(t, &ContextOpts{ 562 Providers: map[addrs.Provider]providers.Factory{ 563 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 564 }, 565 }) 566 567 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 568 ImportedResources: []providers.ImportedResource{ 569 { 570 TypeName: "aws_instance", 571 State: cty.ObjectVal(map[string]cty.Value{ 572 "id": cty.StringVal("foo"), 573 }), 574 }, 575 }, 576 } 577 578 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 579 Targets: []*ImportTarget{ 580 { 581 Addr: addrs.RootModuleInstance.Child("child", addrs.IntKey(0)).Child("nested", addrs.NoKey).ResourceInstance( 582 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 583 ), 584 ID: "baz", 585 }, 586 }, 587 }) 588 if diags.HasErrors() { 589 t.Fatalf("unexpected errors: %s", diags.Err()) 590 } 591 592 actual := strings.TrimSpace(state.String()) 593 expected := strings.TrimSpace(testImportModuleDepth2Str) 594 if actual != expected { 595 t.Fatalf("bad: \n%s", actual) 596 } 597 } 598 599 func TestContextImport_moduleDiff(t *testing.T) { 600 p := testProvider("aws") 601 m := testModule(t, "import-module") 602 ctx := testContext2(t, &ContextOpts{ 603 Providers: map[addrs.Provider]providers.Factory{ 604 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 605 }, 606 }) 607 608 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 609 ImportedResources: []providers.ImportedResource{ 610 { 611 TypeName: "aws_instance", 612 State: cty.ObjectVal(map[string]cty.Value{ 613 "id": cty.StringVal("foo"), 614 }), 615 }, 616 }, 617 } 618 619 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 620 Targets: []*ImportTarget{ 621 { 622 Addr: addrs.RootModuleInstance.Child("child", addrs.IntKey(0)).ResourceInstance( 623 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 624 ), 625 ID: "baz", 626 }, 627 }, 628 }) 629 if diags.HasErrors() { 630 t.Fatalf("unexpected errors: %s", diags.Err()) 631 } 632 633 actual := strings.TrimSpace(state.String()) 634 expected := strings.TrimSpace(testImportModuleStr) 635 if actual != expected { 636 t.Fatalf("\nexpected: %q\ngot: %q\n", expected, actual) 637 } 638 } 639 640 func TestContextImport_multiState(t *testing.T) { 641 p := testProvider("aws") 642 m := testModule(t, "import-provider") 643 644 p.GetProviderSchemaResponse = getProviderSchemaResponseFromProviderSchema(&ProviderSchema{ 645 Provider: &configschema.Block{ 646 Attributes: map[string]*configschema.Attribute{ 647 "foo": {Type: cty.String, Optional: true}, 648 }, 649 }, 650 ResourceTypes: map[string]*configschema.Block{ 651 "aws_instance": { 652 Attributes: map[string]*configschema.Attribute{ 653 "id": {Type: cty.String, Computed: true}, 654 }, 655 }, 656 "aws_instance_thing": { 657 Attributes: map[string]*configschema.Attribute{ 658 "id": {Type: cty.String, Computed: true}, 659 }, 660 }, 661 }, 662 }) 663 664 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 665 ImportedResources: []providers.ImportedResource{ 666 { 667 TypeName: "aws_instance", 668 State: cty.ObjectVal(map[string]cty.Value{ 669 "id": cty.StringVal("foo"), 670 }), 671 }, 672 { 673 TypeName: "aws_instance_thing", 674 State: cty.ObjectVal(map[string]cty.Value{ 675 "id": cty.StringVal("bar"), 676 }), 677 }, 678 }, 679 } 680 681 ctx := testContext2(t, &ContextOpts{ 682 Providers: map[addrs.Provider]providers.Factory{ 683 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 684 }, 685 }) 686 687 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 688 Targets: []*ImportTarget{ 689 { 690 Addr: addrs.RootModuleInstance.ResourceInstance( 691 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 692 ), 693 ID: "bar", 694 }, 695 }, 696 }) 697 if diags.HasErrors() { 698 t.Fatalf("unexpected errors: %s", diags.Err()) 699 } 700 701 actual := strings.TrimSpace(state.String()) 702 expected := strings.TrimSpace(testImportMultiStr) 703 if actual != expected { 704 t.Fatalf("bad: \n%s", actual) 705 } 706 } 707 708 func TestContextImport_multiStateSame(t *testing.T) { 709 p := testProvider("aws") 710 m := testModule(t, "import-provider") 711 712 p.GetProviderSchemaResponse = getProviderSchemaResponseFromProviderSchema(&ProviderSchema{ 713 Provider: &configschema.Block{ 714 Attributes: map[string]*configschema.Attribute{ 715 "foo": {Type: cty.String, Optional: true}, 716 }, 717 }, 718 ResourceTypes: map[string]*configschema.Block{ 719 "aws_instance": { 720 Attributes: map[string]*configschema.Attribute{ 721 "id": {Type: cty.String, Computed: true}, 722 }, 723 }, 724 "aws_instance_thing": { 725 Attributes: map[string]*configschema.Attribute{ 726 "id": {Type: cty.String, Computed: true}, 727 }, 728 }, 729 }, 730 }) 731 732 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 733 ImportedResources: []providers.ImportedResource{ 734 { 735 TypeName: "aws_instance", 736 State: cty.ObjectVal(map[string]cty.Value{ 737 "id": cty.StringVal("foo"), 738 }), 739 }, 740 { 741 TypeName: "aws_instance_thing", 742 State: cty.ObjectVal(map[string]cty.Value{ 743 "id": cty.StringVal("bar"), 744 }), 745 }, 746 { 747 TypeName: "aws_instance_thing", 748 State: cty.ObjectVal(map[string]cty.Value{ 749 "id": cty.StringVal("qux"), 750 }), 751 }, 752 }, 753 } 754 755 ctx := testContext2(t, &ContextOpts{ 756 Providers: map[addrs.Provider]providers.Factory{ 757 addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), 758 }, 759 }) 760 761 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 762 Targets: []*ImportTarget{ 763 { 764 Addr: addrs.RootModuleInstance.ResourceInstance( 765 addrs.ManagedResourceMode, "aws_instance", "foo", addrs.NoKey, 766 ), 767 ID: "bar", 768 }, 769 }, 770 }) 771 if diags.HasErrors() { 772 t.Fatalf("unexpected errors: %s", diags.Err()) 773 } 774 775 actual := strings.TrimSpace(state.String()) 776 expected := strings.TrimSpace(testImportMultiSameStr) 777 if actual != expected { 778 t.Fatalf("bad: \n%s", actual) 779 } 780 } 781 782 func TestContextImport_noConfigModuleImport(t *testing.T) { 783 p := testProvider("aws") 784 m := testModuleInline(t, map[string]string{ 785 "main.tf": ` 786 locals { 787 xs = toset(["foo"]) 788 } 789 790 module "a" { 791 for_each = local.xs 792 source = "./a" 793 } 794 795 module "b" { 796 for_each = local.xs 797 source = "./b" 798 y = module.a[each.key].y 799 } 800 `, 801 "a/main.tf": ` 802 output "y" { 803 value = "bar" 804 } 805 `, 806 "b/main.tf": ` 807 variable "y" { 808 type = string 809 } 810 811 resource "test_resource" "unused" { 812 value = var.y 813 } 814 `, 815 }) 816 817 p.GetProviderSchemaResponse = getProviderSchemaResponseFromProviderSchema(&ProviderSchema{ 818 Provider: &configschema.Block{ 819 Attributes: map[string]*configschema.Attribute{ 820 "foo": {Type: cty.String, Optional: true}, 821 }, 822 }, 823 ResourceTypes: map[string]*configschema.Block{ 824 "test_resource": { 825 Attributes: map[string]*configschema.Attribute{ 826 "id": {Type: cty.String, Computed: true}, 827 }, 828 }, 829 }, 830 }) 831 832 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 833 ImportedResources: []providers.ImportedResource{ 834 { 835 TypeName: "test_resource", 836 State: cty.ObjectVal(map[string]cty.Value{ 837 "id": cty.StringVal("test"), 838 }), 839 }, 840 }, 841 } 842 p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ 843 ImportedResources: []providers.ImportedResource{ 844 { 845 TypeName: "test_resource", 846 State: cty.ObjectVal(map[string]cty.Value{ 847 "id": cty.StringVal("test"), 848 }), 849 }, 850 }, 851 } 852 853 ctx := testContext2(t, &ContextOpts{ 854 Providers: map[addrs.Provider]providers.Factory{ 855 addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), 856 }, 857 }) 858 859 state, diags := ctx.Import(m, states.NewState(), &ImportOpts{ 860 Targets: []*ImportTarget{ 861 { 862 Addr: addrs.RootModuleInstance.ResourceInstance( 863 addrs.ManagedResourceMode, "test_resource", "test", addrs.NoKey, 864 ), 865 ID: "test", 866 }, 867 }, 868 }) 869 if diags.HasErrors() { 870 t.Fatal(diags.ErrWithWarnings()) 871 } 872 873 ri := state.ResourceInstance(mustResourceInstanceAddr("test_resource.test")) 874 expected := `{"id":"test"}` 875 if ri == nil || ri.Current == nil { 876 t.Fatal("no state is recorded for resource instance test_resource.test") 877 } 878 if string(ri.Current.AttrsJSON) != expected { 879 t.Fatalf("expected %q, got %q\n", expected, ri.Current.AttrsJSON) 880 } 881 } 882 883 const testImportStr = ` 884 aws_instance.foo: 885 ID = foo 886 provider = provider["registry.terraform.io/hashicorp/aws"] 887 ` 888 889 const testImportCountIndexStr = ` 890 aws_instance.foo.0: 891 ID = foo 892 provider = provider["registry.terraform.io/hashicorp/aws"] 893 ` 894 895 const testImportModuleStr = ` 896 <no state> 897 module.child[0]: 898 aws_instance.foo: 899 ID = foo 900 provider = provider["registry.terraform.io/hashicorp/aws"] 901 ` 902 903 const testImportModuleDepth2Str = ` 904 <no state> 905 module.child[0].nested: 906 aws_instance.foo: 907 ID = foo 908 provider = provider["registry.terraform.io/hashicorp/aws"] 909 ` 910 911 const testImportMultiStr = ` 912 aws_instance.foo: 913 ID = foo 914 provider = provider["registry.terraform.io/hashicorp/aws"] 915 aws_instance_thing.foo: 916 ID = bar 917 provider = provider["registry.terraform.io/hashicorp/aws"] 918 ` 919 920 const testImportMultiSameStr = ` 921 aws_instance.foo: 922 ID = foo 923 provider = provider["registry.terraform.io/hashicorp/aws"] 924 aws_instance_thing.foo: 925 ID = bar 926 provider = provider["registry.terraform.io/hashicorp/aws"] 927 aws_instance_thing.foo-1: 928 ID = qux 929 provider = provider["registry.terraform.io/hashicorp/aws"] 930 ` 931 932 const testImportRefreshStr = ` 933 aws_instance.foo: 934 ID = foo 935 provider = provider["registry.terraform.io/hashicorp/aws"] 936 foo = bar 937 `