github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/website/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 ## Initialization 116 117 The first command to run for a new configuration -- or after checking out 118 an existing configuration from version control -- is `terraform init`, which 119 initializes various local settings and data that will be used by subsequent 120 commands. 121 122 In particular, this command will install the plugins for the providers in 123 use within the configuration, which in this case is just the `aws` provider: 124 125 ``` 126 $ terraform init 127 Initializing the backend... 128 Initializing provider plugins... 129 - downloading plugin for provider "aws"... 130 131 The following providers do not have any version constraints in configuration, 132 so the latest version was installed. 133 134 To prevent automatic upgrades to new major versions that may contain breaking 135 changes, it is recommended to add version = "..." constraints to the 136 corresponding provider blocks in configuration, with the constraint strings 137 suggested below. 138 139 * provider.aws: version = "~> 1.0" 140 141 Terraform has been successfully initialized! 142 143 You may now begin working with Terraform. Try running "terraform plan" to see 144 any changes that are required for your infrastructure. All Terraform commands 145 should now work. 146 147 If you ever set or change modules or backend configuration for Terraform, 148 rerun this command to reinitialize your environment. If you forget, other 149 commands will detect it and remind you to do so if necessary. 150 ``` 151 152 The `aws` provider plugin is downloaded and installed in a subdirectory of 153 the current working directory, along with various other book-keeping files. 154 155 The output specifies which version of the plugin was installed, and suggests 156 specifying that version in configuration to ensure that running 157 `terraform init` in future will install a compatible version. This step 158 is not necessary for following the getting started guide, since this 159 configuration will be discarded at the end. 160 161 ## Execution Plan 162 163 Next, let's see what Terraform would do if we asked it to 164 apply this configuration. In the same directory as the 165 `example.tf` file you created, run `terraform plan`. You 166 should see output similar to what is copied below. We've 167 truncated some of the output to save space. 168 169 ``` 170 $ terraform plan 171 # ... 172 173 + aws_instance.example 174 ami: "ami-2757f631" 175 availability_zone: "<computed>" 176 ebs_block_device.#: "<computed>" 177 ephemeral_block_device.#: "<computed>" 178 instance_state: "<computed>" 179 instance_type: "t2.micro" 180 key_name: "<computed>" 181 placement_group: "<computed>" 182 private_dns: "<computed>" 183 private_ip: "<computed>" 184 public_dns: "<computed>" 185 public_ip: "<computed>" 186 root_block_device.#: "<computed>" 187 security_groups.#: "<computed>" 188 source_dest_check: "true" 189 subnet_id: "<computed>" 190 tenancy: "<computed>" 191 vpc_security_group_ids.#: "<computed>" 192 ``` 193 194 `terraform plan` shows what changes Terraform will apply to 195 your infrastructure given the current state of your infrastructure 196 as well as the current contents of your configuration. 197 198 If `terraform plan` failed with an error, read the error message 199 and fix the error that occurred. At this stage, it is probably a 200 syntax error in the configuration. 201 202 The output format is similar to the diff format generated by tools 203 such as Git. The output has a "+" next to "aws\_instance.example", 204 meaning that Terraform will create this resource. Beneath that, 205 it shows the attributes that will be set. When the value displayed 206 is `<computed>`, it means that the value won't be known 207 until the resource is created. 208 209 ## Apply 210 211 The plan looks good, our configuration appears valid, so it's time to 212 create real resources. Run `terraform apply` in the same directory 213 as your `example.tf`, and watch it go! It will take a few minutes 214 since Terraform waits for the EC2 instance to become available. 215 216 ``` 217 $ terraform apply 218 aws_instance.example: Creating... 219 ami: "" => "ami-2757f631" 220 instance_type: "" => "t2.micro" 221 [...] 222 223 aws_instance.example: Still creating... (10s elapsed) 224 aws_instance.example: Creation complete 225 226 Apply complete! Resources: 1 added, 0 changed, 0 destroyed. 227 228 # ... 229 ``` 230 231 Done! You can go to the AWS console to prove to yourself that the 232 EC2 instance has been created. 233 234 Terraform also puts some state into the `terraform.tfstate` file 235 by default. This state file is extremely important; it maps various 236 resource metadata to actual resource IDs so that Terraform knows 237 what it is managing. This file must be saved and distributed 238 to anyone who might run Terraform. It is generally recommended to 239 [setup remote state](https://www.terraform.io/docs/state/remote.html) 240 when working with Terraform. This will mean that any potential secrets 241 stored in the state file, will not be checked into version control 242 243 244 You can inspect the state using `terraform show`: 245 246 ``` 247 $ terraform show 248 aws_instance.example: 249 id = i-32cf65a8 250 ami = ami-2757f631 251 availability_zone = us-east-1a 252 instance_state = running 253 instance_type = t2.micro 254 private_ip = 172.31.30.244 255 public_dns = ec2-52-90-212-55.compute-1.amazonaws.com 256 public_ip = 52.90.212.55 257 subnet_id = subnet-1497024d 258 vpc_security_group_ids.# = 1 259 vpc_security_group_ids.3348721628 = sg-67652003 260 ``` 261 262 You can see that by creating our resource, we've also gathered 263 a lot more metadata about it. This metadata can actually be referenced 264 for other resources or outputs, which will be covered later in 265 the getting started guide. 266 267 ## Provisioning 268 269 The EC2 instance we launched at this point is based on the AMI 270 given, but has no additional software installed. If you're running 271 an image-based infrastructure (perhaps creating images with 272 [Packer](https://www.packer.io)), then this is all you need. 273 274 However, many infrastructures still require some sort of initialization 275 or software provisioning step. Terraform supports 276 provisioners, 277 which we'll cover a little bit later in the getting started guide, 278 in order to do this. 279 280 ## Next 281 282 Congratulations! You've built your first infrastructure with Terraform. 283 You've seen the configuration syntax, an example of a basic execution 284 plan, and understand the state file. 285 286 Next, we're going to move on to [changing and destroying infrastructure](/intro/getting-started/change.html).