Terraform Tutorial · Terraform Basics · Lesson 5 of 25

Terraform Resources

Resources are the infrastructure objects Terraform creates and manages. Learn the resource syntax, references between resources, dependencies and lifecycle rules.

Resource blocks

resource "aws_s3_bucket" "assets" {
  bucket = "acme-website-assets"
}

resource "aws_s3_bucket_versioning" "assets" {
  bucket = aws_s3_bucket.assets.id     # a reference to another resource
  versioning_configuration {
    status = "Enabled"
  }
}

The two labels are the resource type (aws_s3_bucket, defined by the provider) and a local name (assets) used to refer to it as aws_s3_bucket.assets.

References create dependencies

Because the versioning resource refers to aws_s3_bucket.assets.id, Terraform knows it must create the bucket first. You rarely need to say the order yourself. When there is no reference but order matters, use depends_on:

resource "aws_instance" "app" {
  # ...
  depends_on = [aws_iam_role_policy.app]
}
One resource referring to another
terraform {
  required_providers {
    local = { source = "hashicorp/local", version = "~> 2.5" }
  }
}

resource "local_file" "config" {
  filename = "${path.module}/app.conf"
  content  = "port=8080"
}

resource "local_file" "readme" {
  filename = "${path.module}/README.txt"
  content  = "Config file: ${local_file.config.filename}"
}

Output

Terraform will perform the following actions:

  # local_file.config will be created
  + resource "local_file" "config" {
      + content              = "port=8080"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./app.conf"
      + id                   = (known after apply)
    }

  # local_file.readme will be created
  + resource "local_file" "readme" {
      + content              = "Config file: ./app.conf"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./README.txt"
      + id                   = (known after apply)
    }

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

Run this on your computer — see “Get Started” for setup.

Lifecycle rules

resource "aws_instance" "web" {
  # ...
  lifecycle {
    create_before_destroy = true          # replace without downtime
    prevent_destroy       = true          # refuse to delete it
    ignore_changes        = [tags["LastDeployed"]]  # changes made outside Terraform are OK
  }
}

Create, update, replace

In a plan, + means create, ~ update in place, - destroy and -/+ replace (destroy and re-create, because some arguments, such as an EC2 instance's AMI, can't be changed in place). Always read the plan before applying.

Test yourself

In a plan, what does -/+ mean?

  1. The resource will be updated in place
  2. The resource will be destroyed and re-created
  3. The resource will be imported
  4. Nothing will change
Show answer

Answer: The resource will be destroyed and re-created