Defining Resources

LinuxBeginner
Practice Now

Introduction

In the previous lab, we set up our kitchen (installed Terraform). Now, it is time to write the menu.

In Terraform, you usually do not describe every low-level step manually. Instead, you describe the desired infrastructure objects. Each managed object is represented as a resource.

Resources are the main units Terraform manages. They are the bridge between code in your .tf files and real objects in the target platform.

Think of it like ordering at a restaurant. You don't tell the chef "chop an onion, sauté it, beat two eggs..."; you just say "I want an Omelette". Terraform is the waiter who takes your order (configuration) and ensures the kitchen (Docker) prepares exactly what you asked for.

This is the core Terraform workflow: define resources, preview the proposed changes, and then apply them.

Define the Image

We start by stating what ingredients we need. In the Docker world, before you can run a container, you need an Image (which is like a frozen package of the software).

First, let's go into our project folder and create our order sheet, the main.tf file.

cd ~/project
touch main.tf

Open main.tf using the text editor nano.

nano main.tf

We always start by telling Terraform who will be doing the work (the Provider). Copy and paste this standard block to the top of your file to set up the Docker provider:

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {}

Now, we add our first request: the Nginx image. Append this code to your main.tf below the provider block (use arrow keys to move down):

resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = false
}

After pasting the code, save your work. Press Ctrl + O, hit Enter to confirm, and then press Ctrl + X to exit the editor.

Let's decode this language:

  • resource: This word tells Terraform "I want to order something."
  • "docker_image": This is the Type of item we are ordering. Integrating with AWS? This might be aws_instance.
  • "nginx": This is a Name we give to this item in our notebook so we can refer to it later. It doesn't change anything in the real world.
  • name = "nginx:latest": This is the specific parameter sent to Docker. It tells Docker exactly which image to download.

Your blueprint now has a provider and one resource instruction.

Define the Container

An image sits on the disk, but a Container is the running application. It's like the difference between a recipe and the actual meal on the plate.

We will now add a second resource to our main.tf file. This new resource depends on the first one.

Open main.tf again using nano:

nano main.tf

Use the arrow keys to move to the bottom of the file, and paste this block at the end:

resource "docker_container" "web" {
  image = docker_image.nginx.image_id
  name  = "tutorial"
  ports {
    internal = 80
    external = 8000
  }
}

Notice the magic in the line image = docker_image.nginx.image_id.

That reference is more than a convenience. It lets Terraform build a dependency graph so it can determine creation order automatically.

Instead of typing "nginx:latest" again, we point to the resource we defined earlier (docker_image.nginx). This tells Terraform: "Don't try to create this container until you have finished preparing the image." This is how we create Dependencies.

We also added a ports block. This opens a window from your computer (port 8000) into the container (port 80), allowing you to see the website.

Initialize and Plan

Before we let Terraform make changes, we need to initialize the project (download the tools) and then preview the plan.

First, run init to install the Docker provider plugins:

terraform init

Now, imagine if the waiter brought your food immediately without confirming the order. That would be risky! Terraform has a safety feature called Plan. It looks at what you asked for, looks at what already exists, and calculates the difference.

Run the plan command:

terraform plan

Look closely at the output. You will see green + signs next to the resources. This symbols means "I will create this."

The plan phase is one of Terraform's most valuable safety features. It lets you inspect the proposed changes before anything real is modified.

Top tip: Always read the plan. It is your last chance to catch mistakes before they become real infrastructure.

Apply Changes

The plan looked good. Now it is time to tell the waiter: "Make it so!"

The apply command executes the plan.

terraform apply

Terraform is very careful. It will show you the plan one more time and ask for a final confirmation. You must type yes to proceed.

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

Once you type yes and hit Enter, Terraform will contact Docker, pull the image, and start the container.

Let's check if it worked! We can use standard Docker commands to see if the container is running:

docker ps

You can also test the website we just deployed. Since we mapped port 8000, we can access it using curl:

curl localhost:8000

If you see the HTML code for "Welcome to nginx!", you have successfully deployed your first infrastructure using code!

Summary

Congratulations! You have completed the core Terraform workflow.

In this lab, you learned:

  • Defining Resources: How to specify what you want (Images and Containers) in main.tf.
  • References: How to link resources together (like telling a container which image to use).
  • Plan: Previewing the "bill" before you commit.
  • Apply: Creating the actual infrastructure.

This cycle of Write -> Plan -> Apply is exactly how professionals manage massive cloud infrastructures. You've just taken your first step towards becoming a DevOps engineer.