github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/website/docs/language/resources/provisioners/syntax.html.md (about) 1 --- 2 layout: "language" 3 page_title: "Provisioners" 4 sidebar_current: "docs-provisioners" 5 description: |- 6 Using provisioners in Terraform to execute scripts on a local or remote machine as part of resource creation or destruction. 7 --- 8 9 # Provisioners 10 11 Provisioners can be used to model specific actions on the local machine or on 12 a remote machine in order to prepare servers or other infrastructure objects 13 for service. 14 15 ## Provisioners are a Last Resort 16 17 > **Hands-on:** To learn about more declarative ways to handle provisioning actions, try the [Provision Infrastructure Deployed with Terraform](https://learn.hashicorp.com/collections/terraform/provision?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn. 18 19 Terraform includes the concept of provisioners as a measure of pragmatism, 20 knowing that there will always be certain behaviors that can't be directly 21 represented in Terraform's declarative model. 22 23 However, they also add a considerable amount of complexity and uncertainty to 24 Terraform usage. Firstly, Terraform cannot model the actions of provisioners 25 as part of a plan because they can in principle take any action. Secondly, 26 successful use of provisioners requires coordinating many more details than 27 Terraform usage usually requires: direct network access to your servers, 28 issuing Terraform credentials to log in, making sure that all of the necessary 29 external software is installed, etc. 30 31 The following sections describe some situations which can be solved with 32 provisioners in principle, but where better solutions are also available. We do 33 not recommend using provisioners for any of the use-cases described in the 34 following sections. 35 36 Even if your specific use-case is not described in the following sections, we 37 still recommend attempting to solve it using other techniques first, and use 38 provisioners only if there is no other option. 39 40 ### Passing data into virtual machines and other compute resources 41 42 When deploying virtual machines or other similar compute resources, we often 43 need to pass in data about other related infrastructure that the software on 44 that server will need to do its job. 45 46 The various provisioners that interact with remote servers over SSH or WinRM 47 can potentially be used to pass such data by logging in to the server and 48 providing it directly, but most cloud computing platforms provide mechanisms 49 to pass data to instances at the time of their creation such that the data 50 is immediately available on system boot. For example: 51 52 * Alibaba Cloud: `user_data` on 53 [`alicloud_instance`](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/instance) 54 or [`alicloud_launch_template`](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/launch_template). 55 * Amazon EC2: `user_data` or `user_data_base64` on 56 [`aws_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance), 57 [`aws_launch_template`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template), 58 and [`aws_launch_configuration`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration). 59 * Amazon Lightsail: `user_data` on 60 [`aws_lightsail_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lightsail_instance). 61 * Microsoft Azure: `custom_data` on 62 [`azurerm_virtual_machine`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine) 63 or [`azurerm_virtual_machine_scale_set`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_scale_set). 64 * Google Cloud Platform: `metadata` on 65 [`google_compute_instance`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) 66 or [`google_compute_instance_group`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance_group). 67 * Oracle Cloud Infrastructure: `metadata` or `extended_metadata` on 68 [`oci_core_instance`](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_instance) 69 or [`oci_core_instance_configuration`](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/core_instance_configuration). 70 * VMware vSphere: Attach a virtual CDROM to 71 [`vsphere_virtual_machine`](https://registry.terraform.io/providers/hashicorp/vsphere/latest/docs/resources/virtual_machine) 72 using the `cdrom` block, containing a file called `user-data.txt`. 73 74 Many official Linux distribution disk images include software called 75 [cloud-init](https://cloudinit.readthedocs.io/en/latest/) that can automatically 76 process in various ways data passed via the means described above, allowing 77 you to run arbitrary scripts and do basic system configuration immediately 78 during the boot process and without the need to access the machine over SSH. 79 80 > **Hands-on:** Try the [Provision Infrastructure with Cloud-Init](https://learn.hashicorp.com/tutorials/terraform/cloud-init?in=terraform/provision&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn. 81 82 If you are building custom machine images, you can make use of the "user data" 83 or "metadata" passed by the above means in whatever way makes sense to your 84 application, by referring to your vendor's documentation on how to access the 85 data at runtime. 86 87 This approach is _required_ if you intend to use any mechanism in your cloud 88 provider for automatically launching and destroying servers in a group, 89 because in that case individual servers will launch unattended while Terraform 90 is not around to provision them. 91 92 Even if you're deploying individual servers directly with Terraform, passing 93 data this way will allow faster boot times and simplify deployment by avoiding 94 the need for direct network access from Terraform to the new server and for 95 remote access credentials to be provided. 96 97 ### Running configuration management software 98 99 As a convenience to users who are forced to use generic operating system 100 distribution images, Terraform includes a number of specialized provisioners 101 for launching specific configuration management products. 102 103 We strongly recommend not using these, and instead running system configuration 104 steps during a custom image build process. For example, 105 [HashiCorp Packer](https://www.packer.io/) offers a similar complement of 106 configuration management provisioners and can run their installation steps 107 during a separate build process, before creating a system disk image that you 108 can deploy many times. 109 110 > **Hands-on:** Try the [Provision Infrastructure with Packer](https://learn.hashicorp.com/tutorials/terraform/packer?in=terraform/provision&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn. 111 112 If you are using configuration management software that has a centralized server 113 component, you will need to delay the _registration_ step until the final 114 system is booted from your custom image. To achieve that, use one of the 115 mechanisms described above to pass the necessary information into each instance 116 so that it can register itself with the configuration management server 117 immediately on boot, without the need to accept commands from Terraform over 118 SSH or WinRM. 119 120 ### First-class Terraform provider functionality may be available 121 122 It is technically possible to use the `local-exec` provisioner to run the CLI 123 for your target system in order to create, update, or otherwise interact with 124 remote objects in that system. 125 126 If you are trying to use a new feature of the remote system that isn't yet 127 supported in its Terraform provider, that might be the only option. However, 128 if there _is_ provider support for the feature you intend to use, prefer to 129 use that provider functionality rather than a provisioner so that Terraform 130 can be fully aware of the object and properly manage ongoing changes to it. 131 132 Even if the functionality you need is not available in a provider today, we 133 suggest to consider `local-exec` usage a temporary workaround and to also 134 open an issue in the relevant provider's repository to discuss adding 135 first-class provider support. Provider development teams often prioritize 136 features based on interest, so opening an issue is a way to record your 137 interest in the feature. 138 139 Provisioners are used to execute scripts on a local or remote machine 140 as part of resource creation or destruction. Provisioners can be used to 141 bootstrap a resource, cleanup before destroy, run configuration management, etc. 142 143 ## How to use Provisioners 144 145 -> **Note:** Provisioners should only be used as a last resort. For most 146 common situations there are better alternatives. For more information, see 147 the sections above. 148 149 If you are certain that provisioners are the best way to solve your problem 150 after considering the advice in the sections above, you can add a 151 `provisioner` block inside the `resource` block of a compute instance. 152 153 ```hcl 154 resource "aws_instance" "web" { 155 # ... 156 157 provisioner "local-exec" { 158 command = "echo The server's IP address is ${self.private_ip}" 159 } 160 } 161 ``` 162 163 The `local-exec` provisioner requires no other configuration, but most other 164 provisioners must connect to the remote system using SSH or WinRM. 165 You must include [a `connection` block](./connection.html) so that Terraform 166 will know how to communicate with the server. 167 168 Terraform includes several built-in provisioners; use the navigation sidebar to 169 view their documentation. 170 171 It's also possible to use third-party provisioners as plugins, by placing them 172 in `%APPDATA%\iaas-rpc.dir\plugins`, `~/.iaas-rpc.dir/plugins`, or the same 173 directory where the Terraform binary is installed. However, we do not recommend 174 using any provisioners except the built-in `file`, `local-exec`, and 175 `remote-exec` provisioners. 176 177 All provisioners support the `when` and `on_failure` meta-arguments, which 178 are described below (see [Destroy-Time Provisioners](#destroy-time-provisioners) 179 and [Failure Behavior](#failure-behavior)). 180 181 ### The `self` Object 182 183 Expressions in `provisioner` blocks cannot refer to their parent resource by 184 name. Instead, they can use the special `self` object. 185 186 The `self` object represents the provisioner's parent resource, and has all of 187 that resource's attributes. For example, use `self.public_ip` to reference an 188 `aws_instance`'s `public_ip` attribute. 189 190 -> **Technical note:** Resource references are restricted here because 191 references create dependencies. Referring to a resource by name within its own 192 block would create a dependency cycle. 193 194 ## Suppressing Provisioner Logs in CLI Output 195 196 The configuration for a `provisioner` block may use sensitive values, such as 197 [`sensitive` variables](/docs/language/values/variables.html#suppressing-values-in-cli-output) or 198 [`sensitive` output values](/docs/language/values/outputs.html#sensitive-suppressing-values-in-cli-output). 199 In this case, all log output from the provisioner is automatically suppressed to 200 prevent the sensitive values from being displayed. 201 202 ## Creation-Time Provisioners 203 204 By default, provisioners run when the resource they are defined within is 205 created. Creation-time provisioners are only run during _creation_, not 206 during updating or any other lifecycle. They are meant as a means to perform 207 bootstrapping of a system. 208 209 If a creation-time provisioner fails, the resource is marked as **tainted**. 210 A tainted resource will be planned for destruction and recreation upon the 211 next `terraform apply`. Terraform does this because a failed provisioner 212 can leave a resource in a semi-configured state. Because Terraform cannot 213 reason about what the provisioner does, the only way to ensure proper creation 214 of a resource is to recreate it. This is tainting. 215 216 You can change this behavior by setting the `on_failure` attribute, 217 which is covered in detail below. 218 219 ## Destroy-Time Provisioners 220 221 If `when = destroy` is specified, the provisioner will run when the 222 resource it is defined within is _destroyed_. 223 224 ```hcl 225 resource "aws_instance" "web" { 226 # ... 227 228 provisioner "local-exec" { 229 when = destroy 230 command = "echo 'Destroy-time provisioner'" 231 } 232 } 233 ``` 234 235 Destroy provisioners are run before the resource is destroyed. If they 236 fail, Terraform will error and rerun the provisioners again on the next 237 `terraform apply`. Due to this behavior, care should be taken for destroy 238 provisioners to be safe to run multiple times. 239 240 Destroy-time provisioners can only run if they remain in the configuration 241 at the time a resource is destroyed. If a resource block with a destroy-time 242 provisioner is removed entirely from the configuration, its provisioner 243 configurations are removed along with it and thus the destroy provisioner 244 won't run. To work around this, a multi-step process can be used to safely 245 remove a resource with a destroy-time provisioner: 246 247 * Update the resource configuration to include `count = 0`. 248 * Apply the configuration to destroy any existing instances of the resource, including running the destroy provisioner. 249 * Remove the resource block entirely from configuration, along with its `provisioner` blocks. 250 * Apply again, at which point no further action should be taken since the resources were already destroyed. 251 252 This limitation may be addressed in future versions of Terraform. For now, 253 destroy-time provisioners must be used sparingly and with care. 254 255 ~> **NOTE:** A destroy-time provisioner within a resource that is tainted _will not_ run. This includes resources that are marked tainted from a failed creation-time provisioner or tainted manually using `terraform taint`. 256 257 ## Multiple Provisioners 258 259 Multiple provisioners can be specified within a resource. Multiple provisioners 260 are executed in the order they're defined in the configuration file. 261 262 You may also mix and match creation and destruction provisioners. Only 263 the provisioners that are valid for a given operation will be run. Those 264 valid provisioners will be run in the order they're defined in the configuration 265 file. 266 267 Example of multiple provisioners: 268 269 ```hcl 270 resource "aws_instance" "web" { 271 # ... 272 273 provisioner "local-exec" { 274 command = "echo first" 275 } 276 277 provisioner "local-exec" { 278 command = "echo second" 279 } 280 } 281 ``` 282 283 ## Failure Behavior 284 285 By default, provisioners that fail will also cause the Terraform apply 286 itself to fail. The `on_failure` setting can be used to change this. The 287 allowed values are: 288 289 - `continue` - Ignore the error and continue with creation or destruction. 290 291 - `fail` - Raise an error and stop applying (the default behavior). If this is a creation provisioner, 292 taint the resource. 293 294 Example: 295 296 ```hcl 297 resource "aws_instance" "web" { 298 # ... 299 300 provisioner "local-exec" { 301 command = "echo The server's IP address is ${self.private_ip}" 302 on_failure = continue 303 } 304 } 305 ```