mirror of
https://github.com/hashicorp/terraform.git
synced 2026-05-28 04:03:27 -04:00
stackeval: Make some provisioners available to stack components
This makes the built-in "remote-exec" and "file" provisioners available for use in the modules that implement stack components. These are both relatively easy and low-risk to include because they are builtins and don't require anything from outside of Terraform itself. For now this intentionally excludes local-exec because we'll want to think about what constraints we want to put on it, if any, to help ensure we can meet the goal of stack configurations being portable between different execution environments without significant modification, and our current stacks execution environment doesn't guarantee the availability of any external software _at all_. The motivation for adding this now is just to give some better feedback when someone uses a module using one of these provisioners, since otherwise they'll see just a confusing generic error message from the modules runtime about the provisioners not being available. I expect we'll revisit this later and consider expanding it to at least include local-exec, and _maybe_ external provisioner plugins, although that's more questionable because the provisioner plugin mechanism is incredibly legacy and doesn't have any way to work outside of local Terraform CLI usage today. There are no tests here yet because these provisioners are not mockable and would depend on having an SSH or WinRM server to connect to. Later we should ponder how to make this more testable, which might mean making another part of the system responsible for actually providing the provisioner factories and thus our tests here can use fakes. The goal here is just to get this done in a relatively lightweight way for better feedback during preview though, so we're not yet ready to make significant time investments here.
This commit is contained in:
parent
6071e06f1a
commit
3c14eeb945
1 changed files with 34 additions and 0 deletions
|
|
@ -12,6 +12,8 @@ import (
|
|||
"github.com/zclconf/go-cty/cty/convert"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
fileProvisioner "github.com/hashicorp/terraform/internal/builtin/provisioners/file"
|
||||
remoteExecProvisioner "github.com/hashicorp/terraform/internal/builtin/provisioners/remote-exec"
|
||||
"github.com/hashicorp/terraform/internal/collections"
|
||||
"github.com/hashicorp/terraform/internal/configs/configschema"
|
||||
"github.com/hashicorp/terraform/internal/instances"
|
||||
|
|
@ -19,6 +21,7 @@ import (
|
|||
"github.com/hashicorp/terraform/internal/plans"
|
||||
"github.com/hashicorp/terraform/internal/promising"
|
||||
"github.com/hashicorp/terraform/internal/providers"
|
||||
"github.com/hashicorp/terraform/internal/provisioners"
|
||||
"github.com/hashicorp/terraform/internal/stacks/stackaddrs"
|
||||
"github.com/hashicorp/terraform/internal/stacks/stackconfig/stackconfigtypes"
|
||||
"github.com/hashicorp/terraform/internal/stacks/stackplan"
|
||||
|
|
@ -490,6 +493,7 @@ func (c *ComponentInstance) CheckModuleTreePlan(ctx context.Context) (*plans.Pla
|
|||
},
|
||||
},
|
||||
PreloadedProviderSchemas: providerSchemas,
|
||||
Provisioners: c.availableProvisioners(),
|
||||
})
|
||||
if err != nil {
|
||||
// Should not get here because we should always pass a valid
|
||||
|
|
@ -662,6 +666,7 @@ func (c *ComponentInstance) ApplyModuleTreePlan(ctx context.Context, plan *plans
|
|||
tfHook,
|
||||
},
|
||||
PreloadedProviderSchemas: providerSchemas,
|
||||
Provisioners: c.availableProvisioners(),
|
||||
})
|
||||
if err != nil {
|
||||
// Should not get here because we should always pass a valid
|
||||
|
|
@ -1301,6 +1306,35 @@ func (c *ComponentInstance) resourceTypeSchema(ctx context.Context, providerType
|
|||
return ret, nil
|
||||
}
|
||||
|
||||
// availableProvisioners returns the table of provisioner factories that should
|
||||
// be made available to modules in this component.
|
||||
func (c *ComponentInstance) availableProvisioners() map[string]provisioners.Factory {
|
||||
return map[string]provisioners.Factory{
|
||||
"remote-exec": func() (provisioners.Interface, error) {
|
||||
return remoteExecProvisioner.New(), nil
|
||||
},
|
||||
"file": func() (provisioners.Interface, error) {
|
||||
return fileProvisioner.New(), nil
|
||||
},
|
||||
"local-exec": func() (provisioners.Interface, error) {
|
||||
// We don't yet have any way to ensure a consistent execution
|
||||
// environment for local-exec, which means that use of this
|
||||
// provisioner is very likely to hurt portability between
|
||||
// local and remote usage of stacks. Existing use of local-exec
|
||||
// also tends to assume a writable module directory, whereas
|
||||
// stack components execute from a read-only directory.
|
||||
//
|
||||
// Therefore we'll leave this unavailable for now with an explicit
|
||||
// error message, although we might revisit this later if there's
|
||||
// a strong reason to allow it and if we can find a suitable
|
||||
// way to avoid the portability pitfalls that might inhibit
|
||||
// moving execution of a stack from one execution environment to
|
||||
// another.
|
||||
return nil, fmt.Errorf("local-exec provisioners are not supported in stack components; use provider functionality or remote provisioners instead")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ComponentInstance) tracingName() string {
|
||||
return c.Addr().String()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue