Let us now look at some of the considerations to keep in mind
while making use of provisioners.
We learned how to use provisioners in Terraform
in the previous lecture.
While they are great for running tasks
such as a bootstrap script using remote exec,
Terraform recommends to use provisioners sparingly,
and this is because of a couple of reasons.
Making use of provisioners
increase the complexity of the configuration,
and since we can, basically, run any system supported command
within the command or inline argument,
Terraform plan has no way
to accurately model the actions of a provisioner.
Secondly, as we saw in the example of remote exec,
a connection block must be defined for some provisioners to work.
This means that the network connectivity from the local machine
and the authentication must be established
before the provisioner is run.
And this may not always be desirable or feasible.
In order to avoid this,
Terraform recommends to make use of provisioners
that are native to the resource.
We already saw an example of this when we use user data
while creating the EC2 instance for Terraform.
User data is a native feature of AWS EC2,
and it runs during the instance launch time
without having to define the connection block.
The user data argument is specific to the AWS EC2 resource,
but there are similar arguments for other cloud providers
that can be used in the same way,
instead of using the remote-exec provisioner.
Some of these options are listed here.
As a best practice,
it is recommended to keep
the post provisioning tasks to a minimum
and build custom images
that will have all the software and configurations
required for a resource, beforehand.
Following the same example as before,
instead of installing NGINX during launch time,
using user data or remote-exec provisioner,
make sure that we use a custom AMI of Ubuntu
which already has NGINX installed.
And this is where templating tools come into the picture.
We can build custom AMIs,
either from an existing instance
that has all the software and configuration installed,
or make use of tools like Packer
which can do this in a declarative way.
Once this image is built,
we can use it to build an AWS Instance,
and this time,
there is no need to use user data for remote-exec provisioner
to install NGINX.