github.com/dougneal/terraform@v0.6.15-0.20170330092735-b6a3840768a4/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 }