command/import: Fix allow-missing-config option
We previously intentionally removed support for the allow-missing-config option to terraform import, requiring that all imported resources have matching config. See #24412. However, the option was not removed from the import command, and it is widely used. This commit reintroduces support for importing with a missing configuration by falling back to implying the provider FQN based on the resource type.
This commit is contained in:
parent
3178d7d7ac
commit
9ab9ef6291
|
@ -601,7 +601,7 @@ func TestImport_providerConfigWithVarFile(t *testing.T) {
|
||||||
testStateOutput(t, statePath, testImportStr)
|
testStateOutput(t, statePath, testImportStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImport_disallowMissingResourceConfig(t *testing.T) {
|
func TestImport_allowMissingResourceConfig(t *testing.T) {
|
||||||
defer testChdir(t, testFixturePath("import-missing-resource-config"))()
|
defer testChdir(t, testFixturePath("import-missing-resource-config"))()
|
||||||
|
|
||||||
statePath := testTempFile(t)
|
statePath := testTempFile(t)
|
||||||
|
@ -643,15 +643,15 @@ func TestImport_disallowMissingResourceConfig(t *testing.T) {
|
||||||
"bar",
|
"bar",
|
||||||
}
|
}
|
||||||
|
|
||||||
if code := c.Run(args); code != 1 {
|
if code := c.Run(args); code != 0 {
|
||||||
t.Fatalf("import succeeded; expected failure")
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := ui.ErrorWriter.String()
|
if !p.ImportResourceStateCalled {
|
||||||
|
t.Fatal("ImportResourceState should be called")
|
||||||
if want := `Error: Resource test_instance.foo not found in the configuration.`; !strings.Contains(msg, want) {
|
|
||||||
t.Errorf("incorrect message\nwant substring: %s\ngot:\n%s", want, msg)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testStateOutput(t, statePath, testImportStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImport_emptyConfig(t *testing.T) {
|
func TestImport_emptyConfig(t *testing.T) {
|
||||||
|
|
|
@ -49,40 +49,6 @@ func TestContextImport_basic(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Importing a resource which does not exist in the configuration results in an error
|
|
||||||
func TestContextImport_basic_errpr(t *testing.T) {
|
|
||||||
p := testProvider("aws")
|
|
||||||
m := testModule(t, "import-provider")
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
Providers: map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
p.ImportStateReturn = []*InstanceState{
|
|
||||||
&InstanceState{
|
|
||||||
ID: "foo",
|
|
||||||
Ephemeral: EphemeralState{Type: "aws_instance"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
_, diags := ctx.Import(&ImportOpts{
|
|
||||||
Targets: []*ImportTarget{
|
|
||||||
&ImportTarget{
|
|
||||||
Addr: addrs.RootModuleInstance.ResourceInstance(
|
|
||||||
addrs.ManagedResourceMode, "aws_instance", "test", addrs.NoKey,
|
|
||||||
),
|
|
||||||
ID: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if !diags.HasErrors() {
|
|
||||||
t.Fatal("should error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContextImport_countIndex(t *testing.T) {
|
func TestContextImport_countIndex(t *testing.T) {
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
m := testModule(t, "import-provider")
|
m := testModule(t, "import-provider")
|
||||||
|
|
|
@ -30,29 +30,25 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
||||||
return fmt.Errorf("Module %s not found.", target.Addr.Module.Module())
|
return fmt.Errorf("Module %s not found.", target.Addr.Module.Module())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the resource config
|
|
||||||
rsCfg := modCfg.Module.ResourceByAddr(target.Addr.Resource.Resource)
|
|
||||||
if rsCfg == nil {
|
|
||||||
return fmt.Errorf("Resource %s not found in the configuration.", target.Addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the provider FQN for the resource from the resource configuration
|
|
||||||
providerFqn := rsCfg.Provider
|
|
||||||
|
|
||||||
// This is only likely to happen in misconfigured tests.
|
|
||||||
if rsCfg == nil {
|
|
||||||
return fmt.Errorf("provider for resource %s not found in the configuration.", target.Addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the provider local config for the resource
|
|
||||||
localpCfg := rsCfg.ProviderConfigAddr()
|
|
||||||
|
|
||||||
providerAddr := addrs.AbsProviderConfig{
|
providerAddr := addrs.AbsProviderConfig{
|
||||||
Provider: providerFqn,
|
|
||||||
Alias: localpCfg.Alias,
|
|
||||||
Module: target.Addr.Module.Module(),
|
Module: target.Addr.Module.Module(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to find the resource config
|
||||||
|
rsCfg := modCfg.Module.ResourceByAddr(target.Addr.Resource.Resource)
|
||||||
|
if rsCfg != nil {
|
||||||
|
// Get the provider FQN for the resource from the resource configuration
|
||||||
|
providerAddr.Provider = rsCfg.Provider
|
||||||
|
|
||||||
|
// Get the alias from the resource's provider local config
|
||||||
|
providerAddr.Alias = rsCfg.ProviderConfigAddr().Alias
|
||||||
|
} else {
|
||||||
|
// Resource has no matching config, so use an implied provider
|
||||||
|
// based on the resource type
|
||||||
|
rsProviderType := target.Addr.Resource.Resource.ImpliedProvider()
|
||||||
|
providerAddr.Provider = modCfg.Module.ImpliedProviderForUnqualifiedType(rsProviderType)
|
||||||
|
}
|
||||||
|
|
||||||
node := &graphNodeImportState{
|
node := &graphNodeImportState{
|
||||||
Addr: target.Addr,
|
Addr: target.Addr,
|
||||||
ID: target.ID,
|
ID: target.ID,
|
||||||
|
|
Loading…
Reference in New Issue