Bird
Raised Fist0
Terraformcloud~5 mins

Terraform's declarative approach - Commands & Configuration

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Terraform helps you create and manage cloud resources by describing what you want, not how to do it. This way, you write a simple plan, and Terraform figures out the steps to make it real.
When you want to set up a virtual server in the cloud without manually clicking buttons.
When you need to create a network and storage for your app and want to keep track of it easily.
When you want to update your cloud setup safely and see what changes will happen before applying them.
When you want to share your cloud setup with teammates so everyone uses the same settings.
When you want to delete all your cloud resources cleanly without leaving leftovers.
Config File - main.tf
main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
  required_version = ">= 1.0"
}

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

resource "aws_s3_bucket" "example_bucket" {
  bucket = "my-example-bucket-terraform-12345"
  acl    = "private"
}

This file tells Terraform to use the AWS provider in the us-east-1 region.

It declares a resource: an S3 bucket named "my-example-bucket-terraform-12345" with private access.

Terraform will create this bucket when you apply the configuration.

Commands
This command sets up Terraform in your folder by downloading the AWS provider plugin. You run it first to prepare your workspace.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching "~> 4.0"... - Installing hashicorp/aws v4.0.0... - Installed hashicorp/aws v4.0.0 (signed by HashiCorp) 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.
This command shows what Terraform will do to reach the desired state. It helps you check before making any changes.
Terminal
terraform plan
Expected OutputExpected
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.example_bucket will be created + resource "aws_s3_bucket" "example_bucket" { + acl = "private" + bucket = "my-example-bucket-terraform-12345" + force_destroy = false + id = (known after apply) + region = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy.
This command applies the changes to create the S3 bucket as described. The -auto-approve flag skips the confirmation step.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_s3_bucket.example_bucket: Creating... aws_s3_bucket.example_bucket: Creation complete after 2s [id=my-example-bucket-terraform-12345] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
→
-auto-approve - Skip manual confirmation to apply changes immediately
This command deletes the S3 bucket and cleans up the resources Terraform created. The -auto-approve flag skips confirmation.
Terminal
terraform destroy -auto-approve
Expected OutputExpected
aws_s3_bucket.example_bucket: Destroying... [id=my-example-bucket-terraform-12345] aws_s3_bucket.example_bucket: Destruction complete after 1s Destroy complete! Resources: 1 destroyed.
→
-auto-approve - Skip manual confirmation to destroy resources immediately
Key Concept

If you remember nothing else from this pattern, remember: you declare what you want, and Terraform figures out how to make it happen.

Common Mistakes
Running terraform apply before terraform init
Terraform needs to download provider plugins first; without init, apply fails.
Always run terraform init first to prepare your workspace.
Changing resources manually in the cloud without updating Terraform files
Terraform's state will not match reality, causing errors or overwriting changes.
Make all changes through Terraform configuration and apply commands.
Not running terraform plan before apply
You might apply unintended changes without seeing what will happen.
Run terraform plan to review changes before applying.
Summary
terraform init prepares your folder by downloading needed plugins.
terraform plan shows what changes Terraform will make to match your desired setup.
terraform apply creates or updates resources to reach the declared state.
terraform destroy removes all resources declared in your configuration.

Practice

(1/5)
1. What does Terraform's declarative approach mean?
terraform apply will create resources based on what you specify, not how to create them.
easy
A. You describe the desired state of infrastructure, not the steps to create it.
B. You write scripts that run commands step-by-step to build infrastructure.
C. You manually create resources in the cloud console and Terraform tracks them.
D. You use Terraform only to delete resources, not create them.

Solution

  1. Step 1: Understand declarative vs imperative

    Declarative means describing the end state, while imperative means describing the steps to get there.
  2. Step 2: Apply to Terraform

    Terraform uses declarative approach by letting you write configuration files that describe what you want, not how to do it.
  3. Final Answer:

    You describe the desired state of infrastructure, not the steps to create it. -> Option A
  4. Quick Check:

    Declarative = Describe desired state [OK]
Hint: Declarative means say what, not how [OK]
Common Mistakes:
  • Confusing declarative with imperative scripting
  • Thinking Terraform runs commands step-by-step
  • Believing Terraform only deletes resources
2. Which Terraform configuration snippet correctly declares an AWS S3 bucket named "mybucket"?
easy
A. resource aws_s3_bucket mybucket { bucket_name = "mybucket" }
B. create aws_s3_bucket mybucket { name = "mybucket" }
C. aws_s3_bucket "mybucket" { bucket_name = "mybucket" }
D. resource "aws_s3_bucket" "mybucket" { bucket = "mybucket" }

Solution

  1. Step 1: Identify correct Terraform resource syntax

    Terraform resource blocks start with 'resource', then resource type in quotes, then resource name in quotes, followed by braces with arguments.
  2. Step 2: Match correct attribute names

    The attribute to name an S3 bucket is 'bucket', not 'bucket_name'. resource "aws_s3_bucket" "mybucket" { bucket = "mybucket" } matches correct syntax and attribute.
  3. Final Answer:

    resource "aws_s3_bucket" "mybucket" { bucket = "mybucket" } -> Option D
  4. Quick Check:

    Correct resource block syntax = resource "aws_s3_bucket" "mybucket" { bucket = "mybucket" } [OK]
Hint: Terraform resource blocks start with resource "type" "name" [OK]
Common Mistakes:
  • Using incorrect keywords like 'create' instead of 'resource'
  • Missing quotes around resource type or name
  • Using wrong attribute names like 'bucket_name'
3. Given this Terraform configuration:
resource "aws_instance" "example" {
  ami           = "ami-123456"
  instance_type = "t2.micro"
}

What will Terraform do when you run terraform apply for the first time?
medium
A. It will delete any existing EC2 instances named example.
B. It will only plan the changes but not create any resources.
C. It will create an AWS EC2 instance with the specified AMI and instance type.
D. It will throw a syntax error due to missing provider block.

Solution

  1. Step 1: Understand resource declaration effect

    The resource block declares an EC2 instance with given AMI and type. Terraform will create it on apply.
  2. Step 2: Consider first apply behavior

    On first apply, Terraform creates resources to match the declared state. Missing provider block is not a syntax error but requires provider configuration elsewhere.
  3. Final Answer:

    It will create an AWS EC2 instance with the specified AMI and instance type. -> Option C
  4. Quick Check:

    First apply creates declared resources [OK]
Hint: terraform apply creates resources declared first time [OK]
Common Mistakes:
  • Confusing plan with apply behavior
  • Expecting deletion instead of creation
  • Assuming missing provider block causes syntax error
4. You wrote this Terraform code:
resource "aws_s3_bucket" "bucket" {
  bucket = "mybucket"
  acl    = "public-read"
}

But Terraform apply fails with an error about bucket name already existing. What is the best fix?
medium
A. Change the bucket name to a unique one because S3 bucket names must be globally unique.
B. Remove the acl attribute to fix the error.
C. Rename the resource block from "bucket" to "mybucket".
D. Run terraform destroy before apply to clear existing buckets.

Solution

  1. Step 1: Understand S3 bucket naming rules

    S3 bucket names must be globally unique across all AWS accounts.
  2. Step 2: Analyze error cause

    The error means the bucket name "mybucket" is already taken by someone else, so Terraform cannot create it.
  3. Step 3: Choose fix

    Changing the bucket name to a unique one solves the problem. Other options do not address uniqueness.
  4. Final Answer:

    Change the bucket name to a unique one because S3 bucket names must be globally unique. -> Option A
  5. Quick Check:

    S3 bucket names must be unique globally [OK]
Hint: S3 bucket names must be unique globally [OK]
Common Mistakes:
  • Thinking acl attribute causes name conflict
  • Renaming resource block does not change bucket name
  • Destroying resources unnecessarily
5. You want to manage a set of AWS EC2 instances with Terraform declaratively. You have a list of instance names and want to create one instance per name. Which Terraform feature best fits this declarative approach?
hard
A. Manually create each instance resource block with a unique name.
B. Use a for_each meta-argument on the resource block with the list of names.
C. Write a shell script to loop and run terraform apply multiple times.
D. Use a count meta-argument with a fixed number and hardcoded names.

Solution

  1. Step 1: Understand declarative resource creation for multiple items

    Terraform's for_each lets you declare multiple instances based on a collection, matching the declarative style.
  2. Step 2: Evaluate options

    Shell scripts and manual blocks are imperative or repetitive, not declarative. Using count with hardcoded names is less flexible than for_each.
  3. Final Answer:

    Use a for_each meta-argument on the resource block with the list of names. -> Option B
  4. Quick Check:

    for_each creates resources declaratively from collections [OK]
Hint: for_each creates multiple resources declaratively [OK]
Common Mistakes:
  • Using imperative loops outside Terraform
  • Hardcoding multiple resource blocks manually
  • Using count without dynamic naming