diff --git a/website/source/intro/getting-started/build.html.md b/website/source/intro/getting-started/build.html.md index e0a19274b3..646e83654a 100644 --- a/website/source/intro/getting-started/build.html.md +++ b/website/source/intro/getting-started/build.html.md @@ -194,6 +194,19 @@ a lot more metadata about it. This metadata can actually be referenced for other resources or outputs, which will be covered later in the getting started guide. +## Provisioning + +The EC2 instance we launched at this point is based on the AMI +given, but has no additional software installed. If you're running +an image-based infrastructure (perhaps creating images with +[Packer](http://www.packer.io)), then this is all you need. + +However, many infrastructures still require some sort of initialization +or software provisioning step. Terraform supports +provisioners, +which we'll cover a little bit later in the getting started guide, +in order to do this. + ## Next Congratulations! You've built your first infrastructure with Terraform. diff --git a/website/source/intro/getting-started/provision.html.md b/website/source/intro/getting-started/provision.html.md index dd1caa3886..563609655b 100644 --- a/website/source/intro/getting-started/provision.html.md +++ b/website/source/intro/getting-started/provision.html.md @@ -16,4 +16,95 @@ learned so far is good enough. But if you need to do some initial setup on your instances, provisioners let you upload files, run shell scripts, etc. +## Defining a Provisioner +To define a provisioner, modify the resource block defining the +"example" EC2 instance to look like the following: + +``` +resource "aws_instance" "example" { + ami = "ami-aa7ab6c2" + instance_type = "t1.micro" + + provisioner "local-exec" { + command = "echo ${aws_instance.example.public_ip} > file.txt" + } +} +``` + +This adds a `provision` block within the `resource` block. Multiple +`provision` blocks can be added to define multiple provisoining steps. +Terraform supports +[multiple provisioners](/docs/provisioners/index.html), +but for this example we use the "local-exec" provisioner. + +The "local-exec" provisioner executes a command locally on the machine +running Terraform. We're using this provisioner versus the others so +we don't have to worry about specifying any +[connection info](/docs/provisioners/connection.html) right now. + +## Running Provisioners + +Provisioners are run only when a resource is _created_. They +are not a replacement for configuration management and changing +the software of an already-running server, and are instead just +meant as a way to bootstrap a server. For configuration management, +you should use Terraform provisioning to bootstrap a real configuration +management solution. + +Make sure that your infrastructure is +[destroyed](/intro/getting-started/destroy.html) if it isn't already, +then run `apply`: + +``` +$ terraform apply +aws_instance.example: Creating... + ami: "" => "ami-aa7ab6c2" + instance_type: "" => "t1.micro" +aws_eip.ip: Creating... + instance: "" => "i-213f350a" + +Apply complete! Resources: 2 added, 0 changed, 0 destroyed. +``` + +Terraform currently doesn't output anything to indicate the provisioners +have run. This is going to be fixed soon. However, we can verify +everything worked by looking at the "file.txt" file: + +``` +$ cat file.txt +54.192.26.128 +``` + +It contains the IP, just ask we asked! + +## Failed Provisioners and Tainted Resources + +If a resource successfully creates but fails during provision, +Terraform will error and mark the resource as "tainted." A +resource that is tainted has been physically created, but can't +be considered safe to use since provisioning failed. + +When you generate your next execution plan, Terraform will remove +any tainted resources and create new resources, attempting to +provision again. It does not attempt to restart provisioning on the +same resource because it isn't guaranteed to be safe. + +Terraform does not automatically roll back and destroy the resource +during the apply when the failure happens, because that would go +against the execution plan: the execution plan would've said a +resource will be created, but does not say it will ever be deleted. +But if you create an execution plan with a tainted resource, the +plan will clearly state that the resource will be destroyed because +it is tainted. + +## Next + +Provisioning is important for being able to bootstrap instances. +As another reminder, it is not a replacement for configuration +management. It is meant to simply bootstrap machines. If you use +configuration management, you should use the provisioning as a way +to bootstrap the configuration management utility. + +In the next section, we start looking at variables as a way to +better parameterize our configurations. diff --git a/website/source/layouts/intro.erb b/website/source/layouts/intro.erb index 24789da79d..68e1d9ff6d 100644 --- a/website/source/layouts/intro.erb +++ b/website/source/layouts/intro.erb @@ -46,6 +46,10 @@ Resource Dependencies +