Terraform Part3

Resources and Data Sources

Resources vs. Data Sources in Terraform

Terraform provides two key constructs to manage infrastructure

1. Resources

A resource in Terraform represents a cloud infrastructure component, such as an EC2 instance, a VPC, or a database. Resources are created, updated, and deleted based on the Terraform configuration file

Example: Creating a new AWS subnet inside a VPC.

2. Data Sources

Data sources in Terraform allow querying existing cloud infrastructure components instead of creating new ones. This is useful when you need to reference an existing VPC, IAM role, or security group in your Terraform configuration.

Example: Fetching an existing AWS VPC by its ID.

When to Use Resources vs. Data Sources

  • Use resources when you need to create or manage cloud components.
  • Use data sources when you need to fetch details of existing infrastructure to avoid duplication.

AWS VPC and SUBNET configuration

Terraform uses the resource block to create infrastructure components in AWS. Each resource has a specific name defined by the provider documentation.

Creating a VPC

  • The VPC resource is named using the aws_vpc prefix.
  • The cidr_block parameter defines the private IP range for the VPC.
  • Tags can be added to resources.

 

resource “aws_vpc” “main” {

    cidr_block       = “10.0.0.0/16”

    instance_tenancy = “default”

 

    tags = {

        Name = “main”

    }

}

 

Creating a Subnet

  • The subnet must be associated with a VPC, referenced by vpc_id.
  • The subnet receives a subset of the VPC’s IP range defined in cidr_block.
  • The availability zone can be specified manually.

resource “aws_subnet” “dev-subnet-1” {

    vpc_id            = aws_vpc.main.id

    cidr_block        = “10.0.10.0/24”

    availability_zone = “eu-central-1a”

}

Complete Terraform Configuration

provider “aws” {

    region     = “eu-central-1”

    access_key = “AKIAUZ7NN5BBID2IQDHY”

    secret_key = “HCVKNGYyYzKU5hSs4/pwKM2KWFC5hGRKAG/DaniW”

}

resource “aws_vpc” “development-vpc” {

    cidr_block = “10.0.0.0/16”

    instance_tenancy = “default”

 

    tags = {

        Name = “main”

    }

}

resource “aws_subnet” “dev-subnet-1” {

    vpc_id            = aws_vpc.development-vpc.id

    cidr_block        = “10.0.10.0/24”

    availability_zone = “eu-central-1a”

}

 

Terraform allows referencing resources that do not yet exist using resource_name.attribute. This ensures dependencies are correctly handled.

Terraform apply

Applying Terraform Configuration

To create defined resources, use the terraform apply command. It identifies resources that need to be created and applies the configuration.

Steps to Apply Terraform Configuration

  1. Run Terraform Apply
    • Inside the Terraform project folder, execute terraform apply
    • Terraform analyses the configuration and lists planned actions.
  2. Review the Plan
    • Terraform displays a summary of what will be created.
    • A green + symbol indicates new resources (e.g., AWS VPC, Subnet).
    • Some attributes (like CIDR block) are user-defined, while others (like IDs) are auto-generated.
  3. Confirm Execution
    • Type yes to confirm the changes.
    • Terraform creates the resources and displays the output.
  4. Verify in AWS Console
    • Refresh the AWS console to see the newly created VPC and Subnet.
    • The VPC ID is auto-generated.

Querying Existing AWS Resources

  • To create a subnet inside an existing VPC, retrieve the VPC ID from AWS manually or query it is using Terraform’s data component.
  • The data block fetches existing resources instead of creating new ones.
  • AWS documentation provides details on available attributes for querying.

Creating Another Subnet

  • Copy an existing subnet’s CIDR block and modify it for uniqueness.
  • Apply the updated configuration using:

terraform apply

  • Terraform ensures the new subnet does not conflict with existing ones.

This process automates infrastructure deployment and allows managing resources efficiently.

 

data “aws_vpc” “existing_vpc” {

    default = true

}

 

resource “aws_subnet” “dev-subnet-2” {

    vpc_id            = data.aws_vpc.existing_vpc.id

    cidr_block        = “172.31.48.0/20”

    availability_zone = “eu-central-1a”

}

Terraform syntax is straightforward, intuitive, and consistent across different providers. Regardless of the provider used, the structure remains uniform. The provider definition acts like importing a library, while resources and data function as calls within that library—resources create new infrastructure, whereas data retrieves existing components.

User credentials must have the necessary permissions to create or query resources. When terraform apply is executed again without changes, Terraform detects no updates are needed due to its declarative nature. Instead of specifying each step, Terraform defines the desired end state and determines the necessary actions to achieve it.

Terraform is idempotent, meaning running the same configuration multiple times always results in the same state. This prevents accidental modifications and eliminates the need for users to track the current infrastructure state manually. Terraform ensures the environment aligns with the declared configuration, making necessary adjustments automatically.

Changing Resources in Terraform

To update existing resources, we modify the configuration and apply changes. Adding a tags parameter allows naming resources for better organization. Tags in AWS are key-value pairs, and specifying “Name” assigns a readable identifier to resources.

Terraform detects changes using symbols:

  • + (plus) → Indicates a new resource creation.
  • ~ (tilde) → Represents modifications to an existing resource.
  • – (minus, red color) → Marks a resource or attribute for deletion.

When a tag is added, Terraform identifies the change (~) and updates the AWS subnet accordingly. If a tag is removed, Terraform recognizes the deletion (-) and updates the state to reflect the change. Running terraform apply ensures the infrastructure remains aligned with the desired configuration.

 

provider “aws” {

    region     = “eu-central-1”

    access_key = “AKIAUZ7NN5BBID2IQDHY”

    secret_key = “HCVKNGYyYzKU5hSs4/pwKM2KWFC5hGRKAG/DaniW”

}

 

resource “aws_vpc” “development-vpc” {

    cidr_block = “10.0.0.0/16”

    tags = {

        Name = “development”

    }

}

 

resource “aws_subnet” “dev-subnet-1” {

    vpc_id            = aws_vpc.development-vpc.id

    cidr_block        = “10.0.10.0/24”

    availability_zone = “eu-central-1a”

    tags = {

        Name = “subnet-1-dev”

    }

}

 

Removing / Destroying Resources

To remove a resource, such as subnet 2, there are two methods:

  1. Removing from the Terraform File
    Deleting the resource from the configuration file prompts Terraform to compare the current state (subnet exists) with the desired state (no subnet). Running terraform apply marks the resource for removal and deletes it, including all attributes. If anything, other than “yes” is entered, the process is canceled.
  2. Using Terraform Command
    Running terraform destroy -target aws_subnet.dev-subnet-2 removes the specific resource. Like terraform apply, it requires confirmation before deletion.

Which Method to Use?
Using terraform apply is recommended because terraform destroy with a target option can create inconsistencies between the configuration file and the actual state. Best practice in Infrastructure as Code dictates that changes should be made through configuration files to maintain consistency, especially in team environments.