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