Skip to main content
Welcome to this hands-on tutorial on provisioning an AWS EC2 instance using OpenTofu (a community-driven fork of Terraform). You’ll learn how to:
  • Create and configure an EC2 instance
  • Manage SSH keys
  • Apply user data scripts
  • Use provisioners for automation
  • Allocate and associate an Elastic IP
  • Understand Terraform’s dependency graph
This guide assumes you have AWS credentials configured and the OpenTofu CLI installed.

Prerequisites

  • OpenTofu CLI installed (tofu version)
  • AWS CLI configured (aws configure)
  • An SSH key pair (we’ll generate one in step 2)

1. Provision a Simple EC2 Instance

  1. Change to your project directory and open main.tf:
  2. Define the EC2 resource and variables:
  3. Initialize and apply:
    Example output:
Inspect your instance attributes:

2. Create an SSH Key Pair

Generate an SSH key pair on your local machine:
Then add this to main.tf:
Apply the change:
You should see:

3. Attach the Key to the EC2 Instance

Update the aws_instance block to reference the key:
Re-apply:

4. Install Nginx via User Data

Provision your instance to install Nginx at launch:
  1. Create install-nginx.sh:
  2. Reference it in your EC2 resource:
User data scripts run only on the first instance launch. Future tofu apply runs will not re-execute user_data.
Attempt to apply:
You’ll see no changes if the instance already exists.

5. Provisioners and Connection Blocks

Terraform supports three built-in provisioners. Only local-exec does not require a connection block. Remember: provisioners must be nested inside the resource block they target.

6. Retrieve the Public IPv4 Address

After creating your EC2 instance, run:
Look for the public_ip attribute (for example, 54.214.169.15).

7. Reserve and Associate an Elastic IP

An Elastic IP (EIP) is a static public IPv4 address. Add this resource:
To save the public DNS to a file, use a local-exec provisioner:
This block allocates and associates an Elastic IP, then writes the instance’s public DNS to /root/serverless_publicDNS.txt.
The image shows a split-screen view with a task description on the left about creating an Elastic IP in Terraform, and a code editor on the right displaying a Terraform configuration file with AWS resources.
Apply your changes:
Inspect the EIP:
Note the public_ip (e.g., 52.47.169.195).

8. Understanding Dependency Direction

Because aws_eip.eip references aws_instance.cerberus.id, Terraform automatically creates the EC2 instance before allocating the EIP. There’s no reverse dependency.
Terraform’s graph engine infers resource creation order by scanning references. No explicit depends_on is needed here.
The image shows a split screen with a multiple-choice question on the left and a code editor on the right displaying Terraform configuration files. The terminal at the bottom shows the output of a Terraform apply command.

That completes this lab. Thank you for following along!

Watch Video

Practice Lab