github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/website/source/intro/getting-started/build.html.md (about) 1 --- 2 layout: "intro" 3 page_title: "Build Infrastructure" 4 sidebar_current: "gettingstarted-build" 5 description: |- 6 With Terraform installed, let's dive right into it and start creating some infrastructure. 7 --- 8 9 # Build Infrastructure 10 11 With Terraform installed, let's dive right into it and start creating 12 some infrastructure. 13 14 We'll build infrastructure on 15 [AWS](https://aws.amazon.com) for the getting started guide 16 since it is popular and generally understood, but Terraform 17 can [manage many providers](/docs/providers/index.html), 18 including multiple providers in a single configuration. 19 Some examples of this are in the 20 [use cases section](/intro/use-cases.html). 21 22 If you don't have an AWS account, 23 [create one now](https://aws.amazon.com/free/). 24 For the getting started guide, we'll only be using resources 25 which qualify under the AWS 26 [free-tier](https://aws.amazon.com/free/), 27 meaning it will be free. 28 If you already have an AWS account, you may be charged some 29 amount of money, but it shouldn't be more than a few dollars 30 at most. 31 32 ~> **Warning!** If you're not using an account that qualifies under the AWS 33 [free-tier](https://aws.amazon.com/free/), you may be charged to run these 34 examples. The most you should be charged should only be a few dollars, but 35 we're not responsible for any charges that may incur. 36 37 ## Configuration 38 39 The set of files used to describe infrastructure in Terraform is simply 40 known as a Terraform _configuration_. We're going to write our first 41 configuration now to launch a single AWS EC2 instance. 42 43 The format of the configuration files is 44 [documented here](/docs/configuration/index.html). 45 Configuration files can 46 [also be JSON](/docs/configuration/syntax.html), but we recommend only using JSON when the 47 configuration is generated by a machine. 48 49 The entire configuration is shown below. We'll go over each part 50 after. Save the contents to a file named `example.tf`. Verify that 51 there are no other `*.tf` files in your directory, since Terraform 52 loads all of them. 53 54 ```hcl 55 provider "aws" { 56 access_key = "ACCESS_KEY_HERE" 57 secret_key = "SECRET_KEY_HERE" 58 region = "us-east-1" 59 } 60 61 resource "aws_instance" "example" { 62 ami = "ami-2757f631" 63 instance_type = "t2.micro" 64 } 65 ``` 66 67 ~> **Note**: The above configuration is designed to work on most EC2 accounts, 68 with access to a default VPC. For EC2 Classic users, please use `t1.micro` for 69 `instance_type`, and `ami-408c7f28` for the `ami`. 70 71 Replace the `ACCESS_KEY_HERE` and `SECRET_KEY_HERE` with your 72 AWS access key and secret key, available from 73 [this page](https://console.aws.amazon.com/iam/home?#security_credential). 74 We're hardcoding them for now, but will extract these into 75 variables later in the getting started guide. 76 77 ~> **Note**: If you simply leave out AWS credentials, Terraform will 78 automatically search for saved API credentials (for example, 79 in `~/.aws/credentials`) or IAM instance profile credentials. 80 This option is much cleaner for situations where tf files are checked into 81 source control or where there is more than one admin user. 82 See details [here](https://aws.amazon.com/blogs/apn/terraform-beyond-the-basics-with-aws/). 83 Leaving IAM credentials out of the Terraform configs allows you to leave those 84 credentials out of source control, and also use different IAM credentials 85 for each user without having to modify the configuration files. 86 87 This is a complete configuration that Terraform is ready to apply. 88 The general structure should be intuitive and straightforward. 89 90 The `provider` block is used to configure the named provider, in 91 our case "aws." A provider is responsible for creating and 92 managing resources. Multiple provider blocks can exist if a 93 Terraform configuration is composed of multiple providers, 94 which is a common situation. 95 96 The `resource` block defines a resource that exists within 97 the infrastructure. A resource might be a physical component such 98 as an EC2 instance, or it can be a logical resource such as 99 a Heroku application. 100 101 The resource block has two strings before opening the block: 102 the resource type and the resource name. In our example, the 103 resource type is "aws\_instance" and the name is "example." 104 The prefix of the type maps to the provider. In our case 105 "aws\_instance" automatically tells Terraform that it is 106 managed by the "aws" provider. 107 108 Within the resource block itself is configuration for that 109 resource. This is dependent on each resource provider and 110 is fully documented within our 111 [providers reference](/docs/providers/index.html). For our EC2 instance, we specify 112 an AMI for Ubuntu, and request a "t2.micro" instance so we 113 qualify under the free tier. 114 115 ## Execution Plan 116 117 Next, let's see what Terraform would do if we asked it to 118 apply this configuration. In the same directory as the 119 `example.tf` file you created, run `terraform plan`. You 120 should see output similar to what is copied below. We've 121 truncated some of the output to save space. 122 123 ``` 124 $ terraform plan 125 # ... 126 127 + aws_instance.example 128 ami: "ami-2757f631" 129 availability_zone: "<computed>" 130 ebs_block_device.#: "<computed>" 131 ephemeral_block_device.#: "<computed>" 132 instance_state: "<computed>" 133 instance_type: "t2.micro" 134 key_name: "<computed>" 135 placement_group: "<computed>" 136 private_dns: "<computed>" 137 private_ip: "<computed>" 138 public_dns: "<computed>" 139 public_ip: "<computed>" 140 root_block_device.#: "<computed>" 141 security_groups.#: "<computed>" 142 source_dest_check: "true" 143 subnet_id: "<computed>" 144 tenancy: "<computed>" 145 vpc_security_group_ids.#: "<computed>" 146 ``` 147 148 `terraform plan` shows what changes Terraform will apply to 149 your infrastructure given the current state of your infrastructure 150 as well as the current contents of your configuration. 151 152 If `terraform plan` failed with an error, read the error message 153 and fix the error that occurred. At this stage, it is probably a 154 syntax error in the configuration. 155 156 The output format is similar to the diff format generated by tools 157 such as Git. The output has a "+" next to "aws\_instance.example", 158 meaning that Terraform will create this resource. Beneath that, 159 it shows the attributes that will be set. When the value displayed 160 is `<computed>`, it means that the value won't be known 161 until the resource is created. 162 163 ## Apply 164 165 The plan looks good, our configuration appears valid, so it's time to 166 create real resources. Run `terraform apply` in the same directory 167 as your `example.tf`, and watch it go! It will take a few minutes 168 since Terraform waits for the EC2 instance to become available. 169 170 ``` 171 $ terraform apply 172 aws_instance.example: Creating... 173 ami: "" => "ami-2757f631" 174 instance_type: "" => "t2.micro" 175 [...] 176 177 aws_instance.example: Still creating... (10s elapsed) 178 aws_instance.example: Creation complete 179 180 Apply complete! Resources: 1 added, 0 changed, 0 destroyed. 181 182 # ... 183 ``` 184 185 Done! You can go to the AWS console to prove to yourself that the 186 EC2 instance has been created. 187 188 Terraform also puts some state into the `terraform.tfstate` file 189 by default. This state file is extremely important; it maps various 190 resource metadata to actual resource IDs so that Terraform knows 191 what it is managing. This file must be saved and distributed 192 to anyone who might run Terraform. It is generally recommended to 193 [setup remote state](https://www.terraform.io/docs/state/remote.html) 194 when working with Terraform. This will mean that any potential secrets 195 stored in the state file, will not be checked into version control 196 197 198 You can inspect the state using `terraform show`: 199 200 ``` 201 $ terraform show 202 aws_instance.example: 203 id = i-32cf65a8 204 ami = ami-2757f631 205 availability_zone = us-east-1a 206 instance_state = running 207 instance_type = t2.micro 208 private_ip = 172.31.30.244 209 public_dns = ec2-52-90-212-55.compute-1.amazonaws.com 210 public_ip = 52.90.212.55 211 subnet_id = subnet-1497024d 212 vpc_security_group_ids.# = 1 213 vpc_security_group_ids.3348721628 = sg-67652003 214 ``` 215 216 You can see that by creating our resource, we've also gathered 217 a lot more metadata about it. This metadata can actually be referenced 218 for other resources or outputs, which will be covered later in 219 the getting started guide. 220 221 ## Provisioning 222 223 The EC2 instance we launched at this point is based on the AMI 224 given, but has no additional software installed. If you're running 225 an image-based infrastructure (perhaps creating images with 226 [Packer](https://www.packer.io)), then this is all you need. 227 228 However, many infrastructures still require some sort of initialization 229 or software provisioning step. Terraform supports 230 provisioners, 231 which we'll cover a little bit later in the getting started guide, 232 in order to do this. 233 234 ## Next 235 236 Congratulations! You've built your first infrastructure with Terraform. 237 You've seen the configuration syntax, an example of a basic execution 238 plan, and understand the state file. 239 240 Next, we're going to move on to [changing and destroying infrastructure](/intro/getting-started/change.html).