github.com/rvichery/terraform@v0.11.10/backend/backend.go (about)

     1  // Package backend provides interfaces that the CLI uses to interact with
     2  // Terraform. A backend provides the abstraction that allows the same CLI
     3  // to simultaneously support both local and remote operations for seamlessly
     4  // using Terraform in a team environment.
     5  package backend
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"time"
    11  
    12  	"github.com/hashicorp/terraform/command/clistate"
    13  	"github.com/hashicorp/terraform/config/module"
    14  	"github.com/hashicorp/terraform/state"
    15  	"github.com/hashicorp/terraform/terraform"
    16  )
    17  
    18  // DefaultStateName is the name of the default, initial state that every
    19  // backend must have. This state cannot be deleted.
    20  const DefaultStateName = "default"
    21  
    22  // This must be returned rather than a custom error so that the Terraform
    23  // CLI can detect it and handle it appropriately.
    24  var (
    25  	// ErrDefaultStateNotSupported is returned when an operation does not support
    26  	// using the default state, but requires a named state to be selected.
    27  	ErrDefaultStateNotSupported = errors.New("default state not supported\n" +
    28  		"You can create a new workspace with the \"workspace new\" command.")
    29  
    30  	// ErrNamedStatesNotSupported is returned when a named state operation
    31  	// isn't supported.
    32  	ErrNamedStatesNotSupported = errors.New("named states not supported")
    33  
    34  	// ErrOperationNotSupported is returned when an unsupported operation
    35  	// is detected by the configured backend.
    36  	ErrOperationNotSupported = errors.New("operation not supported")
    37  )
    38  
    39  // InitFn is used to initialize a new backend.
    40  type InitFn func() Backend
    41  
    42  // Backend is the minimal interface that must be implemented to enable Terraform.
    43  type Backend interface {
    44  	// Ask for input and configure the backend. Similar to
    45  	// terraform.ResourceProvider.
    46  	Input(terraform.UIInput, *terraform.ResourceConfig) (*terraform.ResourceConfig, error)
    47  	Validate(*terraform.ResourceConfig) ([]string, []error)
    48  	Configure(*terraform.ResourceConfig) error
    49  
    50  	// State returns the current state for this environment. This state may
    51  	// not be loaded locally: the proper APIs should be called on state.State
    52  	// to load the state. If the state.State is a state.Locker, it's up to the
    53  	// caller to call Lock and Unlock as needed.
    54  	//
    55  	// If the named state doesn't exist it will be created. The "default" state
    56  	// is always assumed to exist.
    57  	State(name string) (state.State, error)
    58  
    59  	// DeleteState removes the named state if it exists. It is an error
    60  	// to delete the default state.
    61  	//
    62  	// DeleteState does not prevent deleting a state that is in use. It is the
    63  	// responsibility of the caller to hold a Lock on the state when calling
    64  	// this method.
    65  	DeleteState(name string) error
    66  
    67  	// States returns a list of configured named states.
    68  	States() ([]string, error)
    69  }
    70  
    71  // Enhanced implements additional behavior on top of a normal backend.
    72  //
    73  // Enhanced backends allow customizing the behavior of Terraform operations.
    74  // This allows Terraform to potentially run operations remotely, load
    75  // configurations from external sources, etc.
    76  type Enhanced interface {
    77  	Backend
    78  
    79  	// Operation performs a Terraform operation such as refresh, plan, apply.
    80  	// It is up to the implementation to determine what "performing" means.
    81  	// This DOES NOT BLOCK. The context returned as part of RunningOperation
    82  	// should be used to block for completion.
    83  	// If the state used in the operation can be locked, it is the
    84  	// responsibility of the Backend to lock the state for the duration of the
    85  	// running operation.
    86  	Operation(context.Context, *Operation) (*RunningOperation, error)
    87  }
    88  
    89  // Local implements additional behavior on a Backend that allows local
    90  // operations in addition to remote operations.
    91  //
    92  // This enables more behaviors of Terraform that require more data such
    93  // as `console`, `import`, `graph`. These require direct access to
    94  // configurations, variables, and more. Not all backends may support this
    95  // so we separate it out into its own optional interface.
    96  type Local interface {
    97  	// Context returns a runnable terraform Context. The operation parameter
    98  	// doesn't need a Type set but it needs other options set such as Module.
    99  	Context(*Operation) (*terraform.Context, state.State, error)
   100  }
   101  
   102  // An operation represents an operation for Terraform to execute.
   103  //
   104  // Note that not all fields are supported by all backends and can result
   105  // in an error if set. All backend implementations should show user-friendly
   106  // errors explaining any incorrectly set values. For example, the local
   107  // backend doesn't support a PlanId being set.
   108  //
   109  // The operation options are purposely designed to have maximal compatibility
   110  // between Terraform and Terraform Servers (a commercial product offered by
   111  // HashiCorp). Therefore, it isn't expected that other implementation support
   112  // every possible option. The struct here is generalized in order to allow
   113  // even partial implementations to exist in the open, without walling off
   114  // remote functionality 100% behind a commercial wall. Anyone can implement
   115  // against this interface and have Terraform interact with it just as it
   116  // would with HashiCorp-provided Terraform Servers.
   117  type Operation struct {
   118  	// Type is the operation to perform.
   119  	Type OperationType
   120  
   121  	// PlanId is an opaque value that backends can use to execute a specific
   122  	// plan for an apply operation.
   123  	//
   124  	// PlanOutBackend is the backend to store with the plan. This is the
   125  	// backend that will be used when applying the plan.
   126  	PlanId         string
   127  	PlanRefresh    bool   // PlanRefresh will do a refresh before a plan
   128  	PlanOutPath    string // PlanOutPath is the path to save the plan
   129  	PlanOutBackend *terraform.BackendState
   130  
   131  	// Module settings specify the root module to use for operations.
   132  	Module *module.Tree
   133  
   134  	// Plan is a plan that was passed as an argument. This is valid for
   135  	// plan and apply arguments but may not work for all backends.
   136  	Plan *terraform.Plan
   137  
   138  	// The options below are more self-explanatory and affect the runtime
   139  	// behavior of the operation.
   140  	AutoApprove  bool
   141  	Destroy      bool
   142  	DestroyForce bool
   143  	ModuleDepth  int
   144  	Parallelism  int
   145  	Targets      []string
   146  
   147  	// Variables should only contain any variables passed as command
   148  	// arguments and not any variables read from the terraform.tfvars
   149  	// or *.auto.tfvars files.
   150  	Variables map[string]interface{}
   151  
   152  	// Input/output/control options.
   153  	UIIn  terraform.UIInput
   154  	UIOut terraform.UIOutput
   155  
   156  	// If LockState is true, the Operation must Lock any
   157  	// state.Lockers for its duration, and Unlock when complete.
   158  	LockState bool
   159  
   160  	// StateLocker is used to lock the state while providing UI feedback to the
   161  	// user. This will be supplied by the Backend itself.
   162  	StateLocker clistate.Locker
   163  
   164  	// The duration to retry obtaining a State lock.
   165  	StateLockTimeout time.Duration
   166  
   167  	// Workspace is the name of the workspace that this operation should run
   168  	// in, which controls which named state is used.
   169  	Workspace string
   170  }
   171  
   172  // RunningOperation is the result of starting an operation.
   173  type RunningOperation struct {
   174  	// For implementers of a backend, this context should not wrap the
   175  	// passed in context. Otherwise, cancelling the parent context will
   176  	// immediately mark this context as "done" but those aren't the semantics
   177  	// we want: we want this context to be done only when the operation itself
   178  	// is fully done.
   179  	context.Context
   180  
   181  	// Stop requests the operation to complete early, by calling Stop on all
   182  	// the plugins. If the process needs to terminate immediately, call Cancel.
   183  	Stop context.CancelFunc
   184  
   185  	// Cancel is the context.CancelFunc associated with the embedded context,
   186  	// and can be called to terminate the operation early.
   187  	// Once Cancel is called, the operation should return as soon as possible
   188  	// to avoid running operations during process exit.
   189  	Cancel context.CancelFunc
   190  
   191  	// Err is the error of the operation. This is populated after
   192  	// the operation has completed.
   193  	Err error
   194  
   195  	// ExitCode can be used to set a custom exit code. This enables enhanced
   196  	// backends to set specific exit codes that miror any remote exit codes.
   197  	ExitCode int
   198  
   199  	// PlanEmpty is populated after a Plan operation completes without error
   200  	// to note whether a plan is empty or has changes.
   201  	PlanEmpty bool
   202  
   203  	// State is the final state after the operation completed. Persisting
   204  	// this state is managed by the backend. This should only be read
   205  	// after the operation completes to avoid read/write races.
   206  	State *terraform.State
   207  }