@@ -16,4 +16,95 @@ learned so far is good enough. But if you need to do some initial
1616setup on your instances, provisioners let you upload files,
1717run shell scripts, etc.
1818
19+ ## Defining a Provisioner
1920
21+ To define a provisioner, modify the resource block defining the
22+ "example" EC2 instance to look like the following:
23+
24+ ```
25+ resource "aws_instance" "example" {
26+ ami = "ami-aa7ab6c2"
27+ instance_type = "t1.micro"
28+
29+ provisioner "local-exec" {
30+ command = "echo ${aws_instance.example.public_ip} > file.txt"
31+ }
32+ }
33+ ```
34+
35+ This adds a ` provision ` block within the ` resource ` block. Multiple
36+ ` provision ` blocks can be added to define multiple provisoining steps.
37+ Terraform supports
38+ [ multiple provisioners] ( /docs/provisioners/index.html ) ,
39+ but for this example we use the "local-exec" provisioner.
40+
41+ The "local-exec" provisioner executes a command locally on the machine
42+ running Terraform. We're using this provisioner versus the others so
43+ we don't have to worry about specifying any
44+ [ connection info] ( /docs/provisioners/connection.html ) right now.
45+
46+ ## Running Provisioners
47+
48+ Provisioners are run only when a resource is _ created_ . They
49+ are not a replacement for configuration management and changing
50+ the software of an already-running server, and are instead just
51+ meant as a way to bootstrap a server. For configuration management,
52+ you should use Terraform provisioning to bootstrap a real configuration
53+ management solution.
54+
55+ Make sure that your infrastructure is
56+ [ destroyed] ( /intro/getting-started/destroy.html ) if it isn't already,
57+ then run ` apply ` :
58+
59+ ```
60+ $ terraform apply
61+ aws_instance.example: Creating...
62+ ami: "" => "ami-aa7ab6c2"
63+ instance_type: "" => "t1.micro"
64+ aws_eip.ip: Creating...
65+ instance: "" => "i-213f350a"
66+
67+ Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
68+ ```
69+
70+ Terraform currently doesn't output anything to indicate the provisioners
71+ have run. This is going to be fixed soon. However, we can verify
72+ everything worked by looking at the "file.txt" file:
73+
74+ ```
75+ $ cat file.txt
76+ 54.192.26.128
77+ ```
78+
79+ It contains the IP, just ask we asked!
80+
81+ ## Failed Provisioners and Tainted Resources
82+
83+ If a resource successfully creates but fails during provision,
84+ Terraform will error and mark the resource as "tainted." A
85+ resource that is tainted has been physically created, but can't
86+ be considered safe to use since provisioning failed.
87+
88+ When you generate your next execution plan, Terraform will remove
89+ any tainted resources and create new resources, attempting to
90+ provision again. It does not attempt to restart provisioning on the
91+ same resource because it isn't guaranteed to be safe.
92+
93+ Terraform does not automatically roll back and destroy the resource
94+ during the apply when the failure happens, because that would go
95+ against the execution plan: the execution plan would've said a
96+ resource will be created, but does not say it will ever be deleted.
97+ But if you create an execution plan with a tainted resource, the
98+ plan will clearly state that the resource will be destroyed because
99+ it is tainted.
100+
101+ ## Next
102+
103+ Provisioning is important for being able to bootstrap instances.
104+ As another reminder, it is not a replacement for configuration
105+ management. It is meant to simply bootstrap machines. If you use
106+ configuration management, you should use the provisioning as a way
107+ to bootstrap the configuration management utility.
108+
109+ In the next section, we start looking at variables as a way to
110+ better parameterize our configurations.
0 commit comments