github.com/jzbruno/terraform@v0.10.3-0.20180104230435-18975d727047/website/guides/running-terraform-in-automation.html.md (about) 1 --- 2 layout: "guides" 3 page_title: "Running Terraform in Automation - Guides" 4 sidebar_current: "guides-running-terraform-in-automation" 5 description: |- 6 Terraform can, with some caveats, be run in automated processes such as 7 continuous delivery pipelines. Ths guide describes some techniques for 8 doing so and some gotchas to watch out for. 9 --- 10 11 # Running Terraform in Automation 12 13 ~> **This is an advanced guide!** When getting started with Terraform, it's 14 recommended to use it locally from the command line. Automation can become 15 valuable once Terraform is being used regularly in production, or by a larger 16 team, but this guide assumes familiarity with the the normal, local CLI 17 workflow. 18 19 For teams that use Terraform as a key part of a change management and 20 deployment pipeline, it can be desirable to orchestrate Terraform runs in some 21 sort of automation in order to ensure consistency between runs, and provide 22 other interesting features such as integration with version control hooks. 23 24 Automation of Terraform can come in various forms, and to varying degrees. 25 Some teams continue to run Terraform locally but use _wrapper scripts_ to 26 prepare a consistent working directory for Terraform to run in, while other 27 teams run Terraform entirely within an orchestration tool such as Jenkins. 28 29 This guide covers some things that should be considered when implementing 30 such automation, both to ensure safe operation of Terraform and to accommodate 31 some current limitations in Terraform's workflow that require careful 32 attention in automation. 33 34 The guide assumes that Terraform will be running in an _non-interactive_ 35 environment, where it is not possible to prompt for input at the terminal. 36 This is not necessarily true for wrapper scripts, but is often true when 37 running in orchestration tools. 38 39 This is a general guide, giving an overview of things to consider when 40 implementing orchestration of Terraform. Due to its general nature, it is not 41 possible to go into specifics about any particular tools, though other 42 tool-specific guides may be produced later if best practices emerge around 43 such a tool. 44 45 ## Automated Workflow Overview 46 47 When running Terraform in automation, the focus is usually on the core 48 plan/apply cycle. The main path, then, is the broadly same as for CLI 49 usage: 50 51 1. Initialize the Terraform working directory. 52 2. Produce a plan for changing resources to match the current configuration. 53 3. Have a human operator review that plan, to ensure it is acceptable. 54 4. Apply the changes described by the plan. 55 56 Steps 1, 2 and 4 can be carried out using the familiar Terraform CLI commands, 57 with some additional options: 58 59 * `terraform init -input=false` to initialize the working directory. 60 * `terraform plan -out=tfplan -input=false` to create a plan and save it to the local file `tfplan`. 61 * `terraform apply -input=false tfplan` to apply the plan stored in the file `tfplan`. 62 63 The `-input=false` option indicates that Terraform should not attempt to 64 prompt for input, and instead expect all necessary values to be provided by 65 either configuration files or the command line. It may therefore be necessary 66 to use the `-var` and `-var-file` options on `terraform plan` to specify any 67 variable values that would traditionally have been manually-entered under 68 interactive usage. 69 70 It is strongly recommended to use a backend that supports 71 [remote state](/docs/state/remote.html), since that allows Terraform to 72 automatically save the state in a persistent location where it can be found 73 and updated by subsequent runs. Selecting a backend that supports 74 [state locking](/docs/state/locking.html) will additionally provide safety 75 against race conditions that can be caused by concurrent Terraform runs. 76 77 ## Controlling Terraform Output in Automation 78 79 By default, some Terraform commands conclude by presenting a description 80 of a possible next step to the user, often including a specific command 81 to run next. 82 83 An automation tool will often abstract away the details of exactly which 84 commands are being run, causing these messages to be confusing and 85 un-actionable, and possibly harmful if they inadvertently encourage a user to 86 bypass the automation tool entirely. 87 88 When the environment variable `TF_IN_AUTOMATION` is set to any non-empty 89 value, Terraform makes some minor adjustments to its output to de-emphasize 90 specific commands to run. The specific changes made will vary over time, 91 but generally-speaking Terraform will consider this variable to indicate that 92 there is some wrapping application that will help the user with the next 93 step. 94 95 To reduce complexity, this feature is implemented primarily for the main 96 workflow commands described above. Other ancillary commands may still produce 97 command line suggestions, regardless of this setting. 98 99 ## Plan and Apply on different machines 100 101 When running in an orchestration tool, it can be difficult or impossible to 102 ensure that the `plan` and `apply` subcommands are run on the same machine, 103 in the same directory, with all of the same files present. 104 105 Running `plan` and `apply` on different machines requires some additional 106 steps to ensure correct behavior. A robust strategy is as follows: 107 108 * After `plan` completes, archive the entire working directory, including the 109 `.terraform` subdirectory created during `init`, and save it somewhere 110 where it will be available to the apply step. A common choice is as a 111 "build artifact" within the chosen orchestration tool. 112 * Before running `apply`, obtain the archive created in the previous step 113 and extract it _at the same absolute path_. This re-creates everything 114 that was present after plan, avoiding strange issues where local files 115 were created during the plan step. 116 117 Terraform currently makes some assumptions which must be accommodated by 118 such an automation setup: 119 120 * The saved plan file can contain absolute paths to child modules and other 121 data files referred to by configuration. Therefore it is necessary to ensure 122 that the archived configuration is extracted at an identical absolute path. 123 This is most commonly achieved by running Terraform in some sort of isolation, 124 such as a Docker container, where the filesystem layout can be controlled. 125 * Terraform assumes that the plan will be applied on the same operating system 126 and CPU architecture as where it was created. For example, this means that 127 it is not possible to create a plan on a Windows computer and then apply it 128 on a Linux server. 129 * Terraform expects the provider plugins that were used to produce a 130 plan to be available and identical when the plan is applied, to ensure 131 that the plan is interpreted correctly. An error will be produced if 132 Terraform or any plugins are upgraded between creating and applying a plan. 133 * Terraform can't automatically detect if the credentials used to create a 134 plan grant access to the same resources used to apply that plan. If using 135 different credentials for each (e.g. to generate the plan using read-only 136 credentials) it is important to ensure that the two are consistent 137 in which account on the corresponding service they belong to. 138 139 ~> The plan file contains a full copy of the configuration, the state that 140 the plan applies to, and any variables passed to `terraform plan`. If any of 141 these contain sensitive data then the archived working directory containing 142 the plan file should be protected accordingly. For provider authentication 143 credentials, it is recommended to use environment variables instead where 144 possible since these are _not_ included in the plan or persisted to disk 145 by Terraform in any other way. 146 147 ## Interactive Approval of Plans 148 149 Another challenge with automating the Terraform workflow is the desire for an 150 interactive approval step between plan and apply. To implement this robustly, 151 it is important to ensure that either only one plan can be outstanding at a 152 time or that the two steps are connected such that approving a plan passes 153 along enough information to the apply step to ensure that the correct plan is 154 applied, as opposed to some later plan that also exists. 155 156 Different orchestration tools address this in different ways, but generally 157 this is implemented via a _build pipeline_ feature, where different steps 158 can be applied in sequence, with later steps having access to data produced 159 by earlier steps. 160 161 The recommended approach is to allow only one plan to be outstanding at a 162 time. When a plan is applied, any other existing plans that were produced 163 against the same state are invalidated, since they must now be recomputed 164 relative to the new state. By forcing plans to be approved (or dismissed) in 165 sequence, this can be avoided. 166 167 ## Auto-Approval of Plans 168 169 While manual review of plans is strongly recommended for production 170 use-cases, it is sometimes desirable to take a more automatic approach 171 when deploying in pre-production or development situations. 172 173 Where manual approval is not required, a simpler sequence of commands 174 can be used: 175 176 * `terraform init -input=false` 177 * `terraform apply -input=false -auto-approve` 178 179 This variant of the `apply` command implicitly creates a new plan and then 180 immediately applies it. The `-auto-approve` option tells Terraform not 181 to require interactive approval of the plan before applying it. 182 183 ~> When Terraform is empowered to make destructive changes to infrastructure, 184 manual review of plans is always recommended unless downtime is tolerated 185 in the event of unintended changes. Use automatic approval **only** with 186 non-critical infrastructure. 187 188 ## Testing Pull Requests with `terraform plan` 189 190 `terraform plan` can be used as a way to perform certain limited verification 191 of the validity of a Terraform configuration, without affecting real 192 infrastructure. Although the plan step updates the state to match real 193 resources, thus ensuring an accurate plan, the updated state is _not_ 194 persisted, and so this command can safely be used to produce "throwaway" plans 195 that are created only to aid in code review. 196 197 When implementing such a workflow, hooks can be used within the code review 198 tool in question (for example, Github Pull Requests) to trigger an orchestration 199 tool for each new commit under review. Terraform can be run in this case 200 as follows: 201 202 * `terraform plan -input=false` 203 204 As in the "main" workflow, it may be necessary to provide `-var` or `-var-file` 205 as appropriate. The `-out` option is not used in this scenario because a 206 plan produced for code review purposes will never be applied. Instead, a 207 new plan can be created and applied from the primary version control branch 208 once the change is merged. 209 210 ~> Beware that passing sensitive/secret data to Terraform via 211 variables or via environment variables will make it possible for anyone who 212 can submit a PR to discover those values, so this flow must be 213 used with care on an open source project, or on any private project where 214 some or all contributors should not have direct access to credentials, etc. 215 216 ## Multi-environment Deployment 217 218 Automation of Terraform often goes hand-in-hand with creating the same 219 configuration multiple times to produce parallel environments for use-cases 220 such as pre-release testing or multi-tenant infrastructure. Automation 221 in such a situation can help ensure that the correct settings are used for 222 each environment, and that the working directory is properly configured 223 before each operation. 224 225 The two most interesting commands for multi-environment orchestration are 226 `terraform init` and `terraform workspace`. The former can be used with 227 additional options to tailor the backend configuration for any differences 228 between environments, while the latter can be used to safely switch between 229 multiple states for the same config stored in a single backend. 230 231 Where possible, it's recommended to use a single backend configuration for 232 all environments and use the `terraform workspace` command to switch 233 between workspaces: 234 235 * `terraform init -input=false` 236 * `terraform workspace select QA` 237 238 In this usage model, a fixed naming scheme is used within the backend 239 storage to allow multiple states to exist without any further configuration. 240 241 Alternatively, the automation tool can set the environment variable 242 `TF_WORKSPACE` to an existing workspace name, which overrides any selection 243 made with the `terraform workspace select` command. Using this environment 244 variable is recommended only for non-interactive usage, since in a local shell 245 environment it can be easy to forget the variable is set and apply changes 246 to the wrong state. 247 248 In some more complex situations it is impossible to share the same 249 [backend configuration](/docs/backends/config.html) across environments. For 250 example, the environments may exist in entirely separate accounts within the 251 target service, and thus need to use different credentials or endpoints for the 252 backend itself. In such situations, backend configuration settings can be 253 overridden via 254 [the `-backend-config` option to `terraform init`](/docs/commands/init.html#backend-config). 255 256 ## Pre-installed Plugins 257 258 In default usage, [`terraform init`](/docs/commands/init.html#backend-config) 259 downloads and installs the plugins for any providers used in the configuration 260 automatically, placing them in a subdirectory of the `.terraform` directory. 261 This affords a simpler workflow for straightforward cases, and allows each 262 configuration to potentially use different versions of plugins. 263 264 In automation environments, it can be desirable to disable this behavior 265 and instead provide a fixed set of plugins already installed on the system 266 where Terraform is running. This then avoids the overhead of re-downloading 267 the plugins on each execution, and allows the system administrator to control 268 which plugins are available. 269 270 To use this mechanism, create a directory somewhere on the system where 271 Terraform will run and place into it the plugin executable files. The 272 plugin release archives are available for download on 273 [releases.hashicorp.com](https://releases.hashicorp.com/). Be sure to 274 download the appropriate archive for the target operating system and 275 architecture. 276 277 After extracting the necessary plugins, the contents of the new plugin 278 directory will look something like this: 279 280 ``` 281 $ ls -lah /usr/lib/custom-terraform-plugins 282 -rwxrwxr-x 1 user user 84M Jun 13 15:13 terraform-provider-aws-v1.0.0-x3 283 -rwxrwxr-x 1 user user 84M Jun 13 15:15 terraform-provider-rundeck-v2.3.0-x3 284 -rwxrwxr-x 1 user user 84M Jun 13 15:15 terraform-provider-mysql-v1.2.0-x3 285 ``` 286 287 The version information at the end of the filenames is important so that 288 Terraform can infer the version number of each plugin. It is allowed to 289 concurrently install multiple versions of the same provider plugin, 290 which will then be used to satisfy 291 [provider version constraints](/docs/configuration/providers.html#provider-versions) 292 from Terraform configurations. 293 294 With this directory populated, the usual auto-download and 295 [plugin discovery](/docs/plugins/basics.html#installing-a-plugin) 296 behavior can be bypassed using the `-plugin-dir` option to `terraform init`: 297 298 * `terraform init -input=false -plugin-dir=/usr/lib/custom-terraform-plugins` 299 300 When this option is used, only the plugins in the given directory are 301 available for use. This gives the system administrator a high level of 302 control over the execution environment, but on the other hand it prevents 303 use of newer plugin versions that have not yet been installed into the 304 local plugin directory. Which approach is more appropriate will depend on 305 unique constraints within each organization. 306 307 Plugins can also be provided along with the configuration by creating a 308 `terraform.d/plugins/OS_ARCH` directory, which will be searched before 309 automatically downloading additional plugins. The `-get-plugins=false` flag can 310 be used to prevent Terraform from automatically downloading additional plugins. 311 312 ## Terraform Enterprise 313 314 As an alternative to home-grown automation solutions, Hashicorp offers 315 [Terraform Enterprise](https://www.hashicorp.com/products/terraform/). 316 317 Internally, Terraform Enterprise runs the same Terraform CLI commands 318 described above, using the same release binaries offered for download on this 319 site. 320 321 Terraform Enterprise builds on the core Terraform CLI functionality to add 322 additional features such as role-based access control, orchestration of the 323 plan and apply lifecycle, a user interface for reviewing and approving plans, 324 and much more. 325 326 It will always be possible to run Terraform via in-house automation, to 327 allow for usage in situations where Terraform Enterprise is not appropriate. 328 It is recommended to consider Terraform Enterprise as an alternative to 329 in-house solutions, since it provides an out-of-the-box solution that 330 already incorporates the best practices described in this guide and can thus 331 reduce time spent developing and maintaining an in-house alternative.