Getting started with Terraform on AWS
Tags: terraform, aws, devops
Published: 2020-07-07 06:26:15

---
title: Getting started with Terraform on AWS
published: true
description: It seems overwhelming at first but at the end it is very easy to start working managing your infrastructure using Terraform
tags: terraform, aws, devops
---

It is overwhelming at first to start managing the infrastructure using Terraform. It also seems like an overkill if you are not a big company with devops team but at the end you will thank yourself for that but it is really easier than you think. 

# Getting started

First you need to install terraform:

```
brew install terraform
```

Than create the directory where you will store your files:

```
mkdir terraform
cd terraform
```

And start creating your infrastructure. 

Let's start by creating a simple init.tf file:

```
provider "aws" {
  region = "us-east-1"
}
```

In order for this to work you need properly configured [aws-cli](https://aws.amazon.com/cli/) with the credentials saved in `~/.aws/credentials` file. This will save you from putting your secrets into the terraform files and allow you to commit everything to the source control. 

Other useful options are:
- profile - if you have multiple profiles in you .aws/credentials
- shared_credentials_file - if you want to use credentials file 

More about that: https://www.terraform.io/docs/providers/aws/index.html#shared-credentials-file

# Initializing terraform

```
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (hashicorp/aws) 2.56.0...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.aws: version = "~> 2.56"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

```

# Creating the first AWS resource

As an example we will create an S3 bucket. 
In order to do that we will create the s3.tf file:

```
resource "aws_s3_bucket" "private-backups" {
  bucket = "private-backups"
  acl = "private"
  tags = {
    product = "infra"
  }
}
```

As you can see it is fairly straightforward and selfexplanatory.

We can now see what will be executed if we apply the command by executing:

```
tf plan
```

Once validated we can just apply:

```
tf apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_s3_bucket.private-backups will be created
  + resource "aws_s3_bucket" "private-backups" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "private-backups"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "product" = "infra"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + versioning {
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_s3_bucket.private-backups: Creating...
aws_s3_bucket.private-backups: Still creating... [10s elapsed]
aws_s3_bucket.private-backups: Still creating... [20s elapsed]
aws_s3_bucket.private-backups: Still creating... [30s elapsed]
aws_s3_bucket.private-backups: Creation complete after 30s [id=private-backups]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

```

If we now execute the plan it will just say that nothing needs to be changed:

```
tf plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

aws_s3_bucket.private-backups: Refreshing state... [id=private-backups]

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
```

The next step would be to submit the files to some source control so we keep track of the changes.