github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/terraform/context_import_test.go (about)

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