github.com/loicalbertin/terraform@v0.6.15-0.20170626182346-8e2583055467/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 ## Plan and Apply on different machines 78 79 When running in an orchestration tool, it can be difficult or impossible to 80 ensure that the `plan` and `apply` subcommands are run on the same machine, 81 in the same directory, with all of the same files present. 82 83 Running `plan` and `apply` on different machines requires some additional 84 steps to ensure correct behavior. A robust strategy is as follows: 85 86 * After `plan` completes, archive the entire working directory, including the 87 `.terraform` subdirectory created during `init`, and save it somewhere 88 where it will be available to the apply step. A common choice is as a 89 "build artifact" within the chosen orchestration tool. 90 * Before running `apply`, obtain the archive created in the previous step 91 and extract it _at the same absolute path_. This re-creates everything 92 that was present after plan, avoiding strange issues where local files 93 were created during the plan step. 94 95 Terraform currently makes some assumptions which must be accommodated by 96 such an automation setup: 97 98 * The saved plan file can contain absolute paths to child modules and other 99 data files referred to by configuration. Therefore it is necessary to ensure 100 that the archived configuration is extracted at an identical absolute path. 101 This is most commonly achieved by running Terraform in some sort of isolation, 102 such as a Docker container, where the filesystem layout can be controlled. 103 * Terraform assumes that the plan will be applied on the same operating system 104 and CPU architecture as where it was created. For example, this means that 105 it is not possible to create a plan on a Windows computer and then apply it 106 on a Linux server. 107 * Terraform expects the provider plugins that were used used to produce a 108 plan to be available and identical when the plan is applied, to ensure 109 that the plan is interpreted correctly. An error will be produced if 110 Terraform or any plugins are upgraded between creating and applying a plan. 111 * Terraform can't automatically detect if the credentials used to create a 112 plan grant access to the same resources used to apply that plan. If using 113 different credentials for each (e.g. to generate the plan using read-only 114 credentials) it is important to ensure that the two are consistent 115 in which account on the corresponding service they belong to. 116 117 ~> The plan file contains a full copy of the configuration, the state that 118 the plan applies to, and any variables passed to `terraform plan`. If any of 119 these contain sensitive data then the archived working directory containing 120 the plan file should be protected accordingly. For provider authentication 121 credentials, it is recommended to use environment variables instead where 122 possible since these are _not_ included in the plan or persisted to disk 123 by Terraform in any other way. 124 125 ## Interactive Approval of Plans 126 127 Another challenge with automating the Terraform workflow is the desire for an 128 interactive approval step between plan and apply. To implement this robustly, 129 it is important to ensure that either only one plan can be outstanding at a 130 time or that the two steps are connected such that approving a plan passes 131 along enough information to the apply step to ensure that the correct plan is 132 applied, as opposed to some later plan that also exists. 133 134 Different orchestration tools address this in different ways, but generally 135 this is implemented via a _build pipeline_ feature, where different steps 136 can be applied in sequence, with later steps having access to data produced 137 by earlier steps. 138 139 The recommended approach is to allow only one plan to be outstanding at a 140 time. When a plan is applied, any other existing plans that were produced 141 against the same state are invalidated, since they must now be recomputed 142 relative to the new state. By forcing plans to be approved (or dismissed) in 143 sequence, this can be avoided. 144 145 ## Auto-Approval of Plans 146 147 While manual review of plans is strongly recommended for production 148 use-cases, it is sometimes desirable to take a more automatic approach 149 when deploying in pre-production or development situations. 150 151 Where manual approval is not required, a simpler sequence of commands 152 can be used: 153 154 * `terraform init -input=false` 155 * `terraform apply -input=false -auto-approve=true` 156 157 This variant of the `apply` command implicitly creates a new plan and then 158 immediately applies it. The `-auto-approve=true` option tells Terraform not 159 to require interactive approval of the plan before applying it. 160 161 ~> When Terraform is empowered to make destructive changes to infrastructure, 162 manual review of plans is always recommended unless downtime is tolerated 163 in the event of unintended changes. Use automatic apply **only** with 164 non-critical infrastructure. 165 166 ## Testing Pull Requests with `terraform plan` 167 168 `terraform plan` can be used as a way to perform certain limited verification 169 of the validity of a Terraform configuration, without affecting real 170 infrastructure. Although the plan step updates the state to match real 171 resources, thus ensuring an accurate plan, the updated state is _not_ 172 persisted, and so this command can safely be used to produce "throwaway" plans 173 that are created only to aid in code review. 174 175 When implementing such a workflow, hooks can be used within the code review 176 tool in question (for example, Github Pull Requests) to trigger an orchestration 177 tool for each new commit under review. Terraform can be run in this case 178 as follows: 179 180 * `terraform plan -input=false` 181 182 As in the "main" workflow, it may be necessary to provide `-var` or `-var-file` 183 as appropriate. The `-out` option is not used in this scenario because a 184 plan produced for code review purposes will never be applied. Instead, a 185 new plan can be created and applied from the primary version control branch 186 once the change is merged. 187 188 ~> Beware that passing sensitive/secret data to Terraform via 189 variables or via environment variables will make it possible for anyone who 190 can submit a PR to discover those values, so this flow must be 191 used with care on an open source project, or on any private project where 192 some or all contributors should not have direct access to credentials, etc. 193 194 ## Multi-environment Deployment 195 196 Automation of Terraform often goes hand-in-hand with creating the same 197 configuration multiple times to produce parallel environments for use-cases 198 such as pre-release testing or multi-tenant infrastructure. Automation 199 in such a situation can help ensure that the correct settings are used for 200 each environment, and that the working directory is properly configured 201 before each operation. 202 203 The two most interesting commands for multi-environment orchestration are 204 `terraform init` and `terraform workspace`. The former can be used with 205 additional options to tailor the backend configuration for any differences 206 between environments, while the latter can be used to safely switch between 207 multiple states for the same config stored in a single backend. 208 209 Where possible, it's recommended to use a single backend configuration for 210 all environments and use the `terraform workspace` command to switch 211 between workspaces: 212 213 * `terraform init -input=false` 214 * `terraform workspace select QA` 215 216 In this usage model, a fixed naming scheme is used within the backend 217 storage to allow multiple states to exist without any further configuration. 218 219 Alternatively, the automation tool can set the environment variable 220 `TF_WORKSPACE` to an existing workspace name, which overrides any selection 221 made with the `terraform workspace select` command. Using this environment 222 variable is recommended only for non-interactive usage, since in a local shell 223 environment it can be easy to forget the variable is set and apply changes 224 to the wrong state. 225 226 In some more complex situations it is impossible to share the same 227 [backend configuration](/docs/backends/config.html) across environments. For 228 example, the environments may exist in entirely separate accounts within the 229 target service, and thus need to use different credentials or endpoints for the 230 backend itself. In such situations, backend configuration settings can be 231 overridden via 232 [the `-backend-config` option to `terraform init`](/docs/commands/init.html#backend-config). 233 234 ## Pre-installed Plugins 235 236 In default usage, [`terraform init`](/docs/commands/init.html#backend-config) 237 downloads and installs the plugins for any providers used in the configuration 238 automatically, placing them in a subdirectory of the `.terraform` directory. 239 This affords a simpler workflow for straightforward cases, and allows each 240 configuration to potentially use different versions of plugins. 241 242 In automation environments, it can be desirable to disable this behavior 243 and instead provide a fixed set of plugins already installed on the system 244 where Terraform is running. This then avoids the overhead of re-downloading 245 the plugins on each execution, and allows the system administrator to control 246 which plugins are available. 247 248 To use this mechanism, create a directory somewhere on the system where 249 Terraform will run and place into it the plugin executable files. The 250 plugin release archives are available for download on 251 [releases.hashicorp.com](https://releases.hashicorp.com/). Be sure to 252 download the appropriate archive for the target operating system and 253 architecture. 254 255 After extracting the necessary plugins, the contents of the new plugin 256 directory will look something like this: 257 258 ``` 259 $ ls -lah /usr/lib/custom-terraform-plugins 260 -rwxrwxr-x 1 user user 84M Jun 13 15:13 terraform-provider-aws-v1.0.0-x3 261 -rwxrwxr-x 1 user user 84M Jun 13 15:15 terraform-provider-rundeck-v2.3.0-x3 262 -rwxrwxr-x 1 user user 84M Jun 13 15:15 terraform-provider-mysql-v1.2.0-x3 263 ``` 264 265 The version information at the end of the filenames is important so that 266 Terraform can infer the version number of each plugin. It is allowed to 267 concurrently install multiple versions of the same provider plugin, 268 which will then be used to satisfy 269 [provider version constraints](/docs/configuration/providers.html#provider-versions) 270 from Terraform configurations. 271 272 With this directory populated, the usual auto-download and 273 [plugin discovery](/docs/plugins/basics.html#installing-a-plugin) 274 behavior can be bypassed using the `-plugin-dir` option to `terraform init`: 275 276 * `terraform init -input=false -plugin-dir=/usr/lib/custom-terraform-plugins` 277 278 When this option is used, only the plugins in the given directory are 279 available for use. This gives the system administrator a high level of 280 control over the execution environment, but on the other hand it prevents 281 use of newer plugin versions that have not yet been installed into the 282 local plugin directory. Which approach is more appropriate will depend on 283 unique constraints within each organization. 284 285 ## Terraform Enterprise 286 287 As an alternative to home-grown automation solutions, Hashicorp offers 288 [Terraform Enterprise](https://www.hashicorp.com/products/terraform/). 289 290 Internally, Terraform Enterprise runs the same Terraform CLI commands 291 described above, using the same release binaries offered for download on this 292 site. 293 294 Terraform Enterprise builds on the core Terraform CLI functionality to add 295 additional features such as role-based access control, orchestration of the 296 plan and apply lifecycle, a user interface for reviewing and approving plans, 297 and much more. 298 299 It will always be possible to run Terraform via in-house automation, to 300 allow for usage in situations where Terraform Enterprise is not appropriate. 301 It is recommended to consider Terraform Enterprise as an alternative to 302 in-house solutions, since it provides an out-of-the-box solution that 303 already incorporates the best practices described in this guide and can thus 304 reduce time spent developing and maintaining an in-house alternative.