github.com/ticketmaster/terraform@v0.10.0-beta2.0.20170711045249-a12daf5aba4f/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`. If you use a region other than
    70  `us-east-1` then you will need to choose an AMI in that region
    71  as AMI IDs are region specific.
    72  
    73  Replace the `ACCESS_KEY_HERE` and `SECRET_KEY_HERE` with your
    74  AWS access key and secret key, available from
    75  [this page](https://console.aws.amazon.com/iam/home?#security_credential).
    76  We're hardcoding them for now, but will extract these into
    77  variables later in the getting started guide.
    78  
    79  ~> **Note**: If you simply leave out AWS credentials, Terraform will
    80  automatically search for saved API credentials (for example,
    81  in `~/.aws/credentials`) or IAM instance profile credentials.
    82  This option is much cleaner for situations where tf files are checked into
    83  source control or where there is more than one admin user.
    84  See details [here](https://aws.amazon.com/blogs/apn/terraform-beyond-the-basics-with-aws/).
    85  Leaving IAM credentials out of the Terraform configs allows you to leave those
    86  credentials out of source control, and also use different IAM credentials
    87  for each user without having to modify the configuration files.
    88  
    89  This is a complete configuration that Terraform is ready to apply.
    90  The general structure should be intuitive and straightforward.
    91  
    92  The `provider` block is used to configure the named provider, in
    93  our case "aws." A provider is responsible for creating and
    94  managing resources. Multiple provider blocks can exist if a
    95  Terraform configuration is composed of multiple providers,
    96  which is a common situation.
    97  
    98  The `resource` block defines a resource that exists within
    99  the infrastructure. A resource might be a physical component such
   100  as an EC2 instance, or it can be a logical resource such as
   101  a Heroku application.
   102  
   103  The resource block has two strings before opening the block:
   104  the resource type and the resource name. In our example, the
   105  resource type is "aws\_instance" and the name is "example."
   106  The prefix of the type maps to the provider. In our case
   107  "aws\_instance" automatically tells Terraform that it is
   108  managed by the "aws" provider.
   109  
   110  Within the resource block itself is configuration for that
   111  resource. This is dependent on each resource provider and
   112  is fully documented within our
   113  [providers reference](/docs/providers/index.html). For our EC2 instance, we specify
   114  an AMI for Ubuntu, and request a "t2.micro" instance so we
   115  qualify under the free tier.
   116  
   117  ## Initialization
   118  
   119  The first command to run for a new configuration -- or after checking out
   120  an existing configuration from version control -- is `terraform init`, which
   121  initializes various local settings and data that will be used by subsequent
   122  commands.
   123  
   124  In particular, this command will install the plugins for the providers in
   125  use within the configuration, which in this case is just the `aws` provider:
   126  
   127  ```
   128  $ terraform init
   129  Initializing the backend...
   130  Initializing provider plugins...
   131  - downloading plugin for provider "aws"...
   132  
   133  The following providers do not have any version constraints in configuration,
   134  so the latest version was installed.
   135  
   136  To prevent automatic upgrades to new major versions that may contain breaking
   137  changes, it is recommended to add version = "..." constraints to the
   138  corresponding provider blocks in configuration, with the constraint strings
   139  suggested below.
   140  
   141  * provider.aws: version = "~> 1.0"
   142  
   143  Terraform has been successfully initialized!
   144  
   145  You may now begin working with Terraform. Try running "terraform plan" to see
   146  any changes that are required for your infrastructure. All Terraform commands
   147  should now work.
   148  
   149  If you ever set or change modules or backend configuration for Terraform,
   150  rerun this command to reinitialize your environment. If you forget, other
   151  commands will detect it and remind you to do so if necessary.
   152  ```
   153  
   154  The `aws` provider plugin is downloaded and installed in a subdirectory of
   155  the current working directory, along with various other book-keeping files.
   156  
   157  The output specifies which version of the plugin was installed, and suggests
   158  specifying that version in configuration to ensure that running
   159  `terraform init` in future will install a compatible version. This step
   160  is not necessary for following the getting started guide, since this
   161  configuration will be discarded at the end.
   162  
   163  ## Execution Plan
   164  
   165  Next, let's see what Terraform would do if we asked it to
   166  apply this configuration. In the same directory as the
   167  `example.tf` file you created, run `terraform plan`. You
   168  should see output similar to what is copied below. We've
   169  truncated some of the output to save space.
   170  
   171  ```
   172  $ terraform plan
   173  # ...
   174  
   175  + aws_instance.example
   176      ami:                      "ami-2757f631"
   177      availability_zone:        "<computed>"
   178      ebs_block_device.#:       "<computed>"
   179      ephemeral_block_device.#: "<computed>"
   180      instance_state:           "<computed>"
   181      instance_type:            "t2.micro"
   182      key_name:                 "<computed>"
   183      placement_group:          "<computed>"
   184      private_dns:              "<computed>"
   185      private_ip:               "<computed>"
   186      public_dns:               "<computed>"
   187      public_ip:                "<computed>"
   188      root_block_device.#:      "<computed>"
   189      security_groups.#:        "<computed>"
   190      source_dest_check:        "true"
   191      subnet_id:                "<computed>"
   192      tenancy:                  "<computed>"
   193      vpc_security_group_ids.#: "<computed>"
   194  ```
   195  
   196  `terraform plan` shows what changes Terraform will apply to
   197  your infrastructure given the current state of your infrastructure
   198  as well as the current contents of your configuration.
   199  
   200  If `terraform plan` failed with an error, read the error message
   201  and fix the error that occurred. At this stage, it is probably a
   202  syntax error in the configuration.
   203  
   204  The output format is similar to the diff format generated by tools
   205  such as Git. The output has a "+" next to "aws\_instance.example",
   206  meaning that Terraform will create this resource. Beneath that,
   207  it shows the attributes that will be set. When the value displayed
   208  is `<computed>`, it means that the value won't be known
   209  until the resource is created.
   210  
   211  ## Apply
   212  
   213  The plan looks good, our configuration appears valid, so it's time to
   214  create real resources. Run `terraform apply` in the same directory
   215  as your `example.tf`, and watch it go! It will take a few minutes
   216  since Terraform waits for the EC2 instance to become available.
   217  
   218  ```
   219  $ terraform apply
   220  aws_instance.example: Creating...
   221    ami:                      "" => "ami-2757f631"
   222    instance_type:            "" => "t2.micro"
   223    [...]
   224  
   225  aws_instance.example: Still creating... (10s elapsed)
   226  aws_instance.example: Creation complete
   227  
   228  Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
   229  
   230  # ...
   231  ```
   232  
   233  Done! You can go to the AWS console to prove to yourself that the
   234  EC2 instance has been created.
   235  
   236  Terraform also puts some state into the `terraform.tfstate` file
   237  by default. This state file is extremely important; it maps various
   238  resource metadata to actual resource IDs so that Terraform knows
   239  what it is managing. This file must be saved and distributed
   240  to anyone who might run Terraform. It is generally recommended to
   241  [setup remote state](https://www.terraform.io/docs/state/remote.html)
   242  when working with Terraform. This will mean that any potential secrets
   243  stored in the state file, will not be checked into version control
   244  
   245  
   246  You can inspect the state using `terraform show`:
   247  
   248  ```
   249  $ terraform show
   250  aws_instance.example:
   251    id = i-32cf65a8
   252    ami = ami-2757f631
   253    availability_zone = us-east-1a
   254    instance_state = running
   255    instance_type = t2.micro
   256    private_ip = 172.31.30.244
   257    public_dns = ec2-52-90-212-55.compute-1.amazonaws.com
   258    public_ip = 52.90.212.55
   259    subnet_id = subnet-1497024d
   260    vpc_security_group_ids.# = 1
   261    vpc_security_group_ids.3348721628 = sg-67652003
   262  ```
   263  
   264  You can see that by creating our resource, we've also gathered
   265  a lot more metadata about it. This metadata can actually be referenced
   266  for other resources or outputs, which will be covered later in
   267  the getting started guide.
   268  
   269  ## Provisioning
   270  
   271  The EC2 instance we launched at this point is based on the AMI
   272  given, but has no additional software installed. If you're running
   273  an image-based infrastructure (perhaps creating images with
   274  [Packer](https://www.packer.io)), then this is all you need.
   275  
   276  However, many infrastructures still require some sort of initialization
   277  or software provisioning step. Terraform supports
   278  provisioners,
   279  which we'll cover a little bit later in the getting started guide,
   280  in order to do this.
   281  
   282  ## Next
   283  
   284  Congratulations! You've built your first infrastructure with Terraform.
   285  You've seen the configuration syntax, an example of a basic execution
   286  plan, and understand the state file.
   287  
   288  Next, we're going to move on to [changing and destroying infrastructure](/intro/getting-started/change.html).