Photo by Danist
Soh
on
Unsplash
As defined in the Terraform documentation, provisioners can be used to model specific actions on the local machine running the Terraform Core or on a remote machine to prepare servers or other infrastructure objects. But HashiCorp clearly states in its documentation that they should be used as the last solution ! which I will explain in this article.
Provisioners are the feature to use when what’s needed is not clearly addressed by Terraform. You can copy data with to the newly created resources, run scripts or specific tasks like installing or upgrading modules.
There are 3 types of provisioners :
File Provisioner :
Used to copy files or directories to the newly created resources and underneath it’s using ssh or winrm. Does the job of an scp.
In this article I used this provisioner inside a null resource to copy my kubernetes configuration files to a newly created VM where I installed minikube. You can define it inside the vm resources as well but i prefer to use them in a separate module as they shouldn’t be mixed with the resources objects. And this is how I did it :
|
|
you will need to add the ssh connection details since it’s using it behind the scenes.
remote-exec Provisioner:
This provisioner invokes a script on the newly created resource. it’s similar to connecting to the resource and running a bash or a command in the terminal.
It can be used inside the Terraform resource object and in that case it will be invoked once the resource is created, or it can be used inside a null resource which is my prefered approche as it separates this non terraform behavior from the real terraform behavior.
|
|
you can not pass any arguments to the script or command, so the best way is to use file provisioner to copy the files to the resources and then invoke them with the remote-exec provisioner like I did above for my script that installs minikube on the azure-vm.
to pay attention to is that by default, provisioners that fail will also cause the Terraform apply to fail. To avoid that, the on_failure**** can be used.
|
|
In this example, I am using inline which is a series of command, the on_failure will apply only to the final command in the list !
local-exec Provisioner:
Technically this one is very similar to the one before in terms of behavior or use but it works in the local machine ruining Terraform. It invokes a script or a command on local once the resource it’s declared in is created.
|
|
It’s the only provisioner that doesn’t need any ssh or winrm connection details as it runs locally.
Why you should avoid provisioner or use them only as a last resort ?
First, Terraform cannot model the actions of provisioners as part of a plan, as they can in principle take any action (the possible commands is “limitless”) which means you won’t get anything about the provisioners in your tfstate. Even if you have them in null resources like I did.
Second, as you I mentioned above file and remote-exec provisioners require connection credentials to function and that adds unnecessary complexity to the Terraform configuration (Mixing day 1 and day 2 tasks).
So as HashiCorp recommends in the docs try using other techniques first, and use provisioners only if there is no other option but you should know them especially if you are planning to pass the Terraform certification exam.
HashiCorp Certified: Terraform Associate was issued by HashiCorp to Zakaria EL BAZI.
All you need to know about Terraform provisioners and why you should avoid them. was originally published in AWS Morocco on Medium, where people are continuing the conversation by highlighting and responding to this story.
The content, views, and opinions expressed on this blog, awsmorocco.com, are solely those of the authors and contributors and not those of Amazon Web Services (AWS) or its affiliates. This blog is independent and not officially endorsed by, associated with, or sponsored by Amazon Web Services or any of its affiliates.
All trademarks, service marks, trade names, trade dress, product names, and logos appearing on the blog are the property of their respective owners, including in some instances Amazon.com, Inc. or its affiliates. Amazon Web Services®, AWS®, and any related logos are trademarks or registered trademarks of Amazon.com, Inc. or its affiliates.
awsmorocco.com aims to provide informative and insightful commentary, news, and updates about Amazon Web Services and related technologies, tailored for the Moroccan community. However, readers should be aware that this content is not a substitute for direct, professional advice from AWS or a certified AWS professional.
We make every effort to provide timely and accurate information but make no claims, promises, or guarantees about the accuracy, completeness, or adequacy of the information contained in or linked to from this blog.
For official information, please refer to the official Amazon Web Services website or contact AWS directly.