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 }