github.com/sixgill/terraform@v0.9.0-beta2.0.20170316214032-033f6226ae50/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  
    11  	"github.com/hashicorp/terraform/config/module"
    12  	"github.com/hashicorp/terraform/state"
    13  	"github.com/hashicorp/terraform/terraform"
    14  )
    15  
    16  // This is the name of the default, initial state that every backend
    17  // must have. This state cannot be deleted.
    18  const DefaultStateName = "default"
    19  
    20  // Error value to return when a named state operation isn't supported.
    21  // This must be returned rather than a custom error so that the Terraform
    22  // CLI can detect it and handle it appropriately.
    23  var ErrNamedStatesNotSupported = errors.New("named states not supported")
    24  
    25  // Backend is the minimal interface that must be implemented to enable Terraform.
    26  type Backend interface {
    27  	// Ask for input and configure the backend. Similar to
    28  	// terraform.ResourceProvider.
    29  	Input(terraform.UIInput, *terraform.ResourceConfig) (*terraform.ResourceConfig, error)
    30  	Validate(*terraform.ResourceConfig) ([]string, []error)
    31  	Configure(*terraform.ResourceConfig) error
    32  
    33  	// State returns the current state for this environment. This state may
    34  	// not be loaded locally: the proper APIs should be called on state.State
    35  	// to load the state. If the state.State is a state.Locker, it's up to the
    36  	// caller to call Lock and Unlock as needed.
    37  	//
    38  	// If the named state doesn't exist it will be created. The "default" state
    39  	// is always assumed to exist.
    40  	State(name string) (state.State, error)
    41  
    42  	// DeleteState removes the named state if it exists. It is an error
    43  	// to delete the default state.
    44  	//
    45  	// DeleteState does not prevent deleting a state that is in use. It is the
    46  	// responsibility of the caller to hold a Lock on the state when calling
    47  	// this method.
    48  	DeleteState(name string) error
    49  
    50  	// States returns a list of configured named states.
    51  	States() ([]string, error)
    52  }
    53  
    54  // Enhanced implements additional behavior on top of a normal backend.
    55  //
    56  // Enhanced backends allow customizing the behavior of Terraform operations.
    57  // This allows Terraform to potentially run operations remotely, load
    58  // configurations from external sources, etc.
    59  type Enhanced interface {
    60  	Backend
    61  
    62  	// Operation performs a Terraform operation such as refresh, plan, apply.
    63  	// It is up to the implementation to determine what "performing" means.
    64  	// This DOES NOT BLOCK. The context returned as part of RunningOperation
    65  	// should be used to block for completion.
    66  	// If the state used in the operation can be locked, it is the
    67  	// responsibility of the Backend to lock the state for the duration of the
    68  	// running operation.
    69  	Operation(context.Context, *Operation) (*RunningOperation, error)
    70  }
    71  
    72  // Local implements additional behavior on a Backend that allows local
    73  // operations in addition to remote operations.
    74  //
    75  // This enables more behaviors of Terraform that require more data such
    76  // as `console`, `import`, `graph`. These require direct access to
    77  // configurations, variables, and more. Not all backends may support this
    78  // so we separate it out into its own optional interface.
    79  type Local interface {
    80  	// Context returns a runnable terraform Context. The operation parameter
    81  	// doesn't need a Type set but it needs other options set such as Module.
    82  	Context(*Operation) (*terraform.Context, state.State, error)
    83  }
    84  
    85  // An operation represents an operation for Terraform to execute.
    86  //
    87  // Note that not all fields are supported by all backends and can result
    88  // in an error if set. All backend implementations should show user-friendly
    89  // errors explaining any incorrectly set values. For example, the local
    90  // backend doesn't support a PlanId being set.
    91  //
    92  // The operation options are purposely designed to have maximal compatibility
    93  // between Terraform and Terraform Servers (a commercial product offered by
    94  // HashiCorp). Therefore, it isn't expected that other implementation support
    95  // every possible option. The struct here is generalized in order to allow
    96  // even partial implementations to exist in the open, without walling off
    97  // remote functionality 100% behind a commercial wall. Anyone can implement
    98  // against this interface and have Terraform interact with it just as it
    99  // would with HashiCorp-provided Terraform Servers.
   100  type Operation struct {
   101  	// Type is the operation to perform.
   102  	Type OperationType
   103  
   104  	// PlanId is an opaque value that backends can use to execute a specific
   105  	// plan for an apply operation.
   106  	//
   107  	// PlanOutBackend is the backend to store with the plan. This is the
   108  	// backend that will be used when applying the plan.
   109  	PlanId         string
   110  	PlanRefresh    bool   // PlanRefresh will do a refresh before a plan
   111  	PlanOutPath    string // PlanOutPath is the path to save the plan
   112  	PlanOutBackend *terraform.BackendState
   113  
   114  	// Module settings specify the root module to use for operations.
   115  	Module *module.Tree
   116  
   117  	// Plan is a plan that was passed as an argument. This is valid for
   118  	// plan and apply arguments but may not work for all backends.
   119  	Plan *terraform.Plan
   120  
   121  	// The options below are more self-explanatory and affect the runtime
   122  	// behavior of the operation.
   123  	Destroy   bool
   124  	Targets   []string
   125  	Variables map[string]interface{}
   126  
   127  	// Input/output/control options.
   128  	UIIn  terraform.UIInput
   129  	UIOut terraform.UIOutput
   130  
   131  	// If LockState is true, the Operation must Lock any
   132  	// state.Lockers for its duration, and Unlock when complete.
   133  	LockState bool
   134  
   135  	// Environment is the named state that should be loaded from the Backend.
   136  	Environment string
   137  }
   138  
   139  // RunningOperation is the result of starting an operation.
   140  type RunningOperation struct {
   141  	// Context should be used to track Done and Err for errors.
   142  	//
   143  	// For implementers of a backend, this context should not wrap the
   144  	// passed in context. Otherwise, canceling the parent context will
   145  	// immediately mark this context as "done" but those aren't the semantics
   146  	// we want: we want this context to be done only when the operation itself
   147  	// is fully done.
   148  	context.Context
   149  
   150  	// Err is the error of the operation. This is populated after
   151  	// the operation has completed.
   152  	Err error
   153  
   154  	// PlanEmpty is populated after a Plan operation completes without error
   155  	// to note whether a plan is empty or has changes.
   156  	PlanEmpty bool
   157  
   158  	// State is the final state after the operation completed. Persisting
   159  	// this state is managed by the backend. This should only be read
   160  	// after the operation completes to avoid read/write races.
   161  	State *terraform.State
   162  }