github.com/hugorut/terraform@v1.1.3/website/docs/language/resources/provisioners/syntax.mdx (about)

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