This is the Day 25 of learning Terraform

Download as pdf or txt
Download as pdf or txt
You are on page 1of 25

Day: - 25

Title: Terraform Input Variables with Collection Type lists


Description: Learn about Terraform Input Variables with Collection Type lists
Explanation: - This Terraform implementation demonstrates how to create and manage Azure
resources using variables and type constructors, with a focus on the list type.

Step-01 & Step-02: Introduction to list type and variable definition

- Purpose: Define a reusable variable of type list(string) to store a sequence of IP address ranges
for a virtual network's address space.

- Technical Details: The list type in Terraform represents an ordered sequence of values, where
each value is of the same type (in this case, string).
- A variable block (variable "virtual_network_address_space") is defined with a type
constraint (type = list(string)), ensuring only a list of strings is accepted.
- The default value is specified as a list of IP CIDR blocks.

- Example Code:
variable "virtual_network_address_space" {
description = "Virtual Network Address Space"
type = list(string)
default = ["10.0.0.0/16", "10.1.0.0/16", "10.2.0.0/16"]
}
This ensures that if no value is passed, a default sequence of IPs will be used.

- Overriding the Default:


The terraform.tfvars file provides a way to override the default variable value with project-
specific IP ranges:
virtual_network_address_space = ["10.3.0.0/16", "10.4.0.0/16", "10.5.0.0/16"]

Step-03: Using the variable in Virtual Network resource

- Purpose: Integrate the virtual_network_address_space variable into the Azure Virtual


Network resource definition.
- Technical Details:

- The address_space property of the azurerm_virtual_network resource is dynamically


populated using the variable.
- This eliminates hardcoding and allows flexibility for different environments or
configurations.

resource "azurerm_virtual_network" "myvnet" {


name = "${var.business_unit}-${var.environment}-${var.virtual_network_name}"
address_space = var.virtual_network_address_space
location = azurerm_resource_group.myrg.location
resource_group_name = azurerm_resource_group.myrg.name
}

Step-04: Subnet Definition

- Purpose: Create subnets within the virtual network. While the example hardcodes an
address_prefix, it can be similarly parameterized.

- Technical Details:

resource "azurerm_subnet" "mysubnet" {


name = "${azurerm_virtual_network.myvnet.name}-${var.subnet_name}"
resource_group_name = azurerm_resource_group.myrg.name
virtual_network_name = azurerm_virtual_network.myvnet.name
address_prefixes = ["10.3.0.0/24"]
}

- The subnet name dynamically incorporates the virtual network name for clarity.
- Subnet address prefixes are explicitly provided as a list.
Step-06: Executing Terraform Commands

1. Initialization: terraform init initializes the Terraform working directory and downloads
provider plugins.
2. Validation: terraform validate checks syntax and configuration correctness.
3. Formatting: terraform fmt standardizes file formatting.
4. Plan & Apply:
terraform plan previews resource changes.
terraform apply -auto-approve executes the changes.

Step-07 & Step-08: Accessing and Referencing List Values

- Purpose: Demonstrates how to reference individual elements in the list using index-based
access.

- Technical Details:
- Indexing allows selective usage of list elements.

address_space = [var.virtual_network_address_space[0]]

- This sets the virtual network address space to the first CIDR block only, useful for testing
or specific configurations.

Step-09: Observations

- Changing the address_space to a single value results in only one address space being
associated with the virtual network.
- This can be verified through the Azure Management Console after applying changes.
Step-10: Cleanup

- Resource Destruction:terraform destroy -auto-approve removes all resources created by


Terraform.
- File Cleanup:Deletes Terraform state files and plugin directories to reset the workspace.
- Rollback Changes: Restores the original variable usage in resource definitions to maintain
modularity:

address_space = var.virtual_network_address_space

Technical Highlights:

1. Type Constraints: Enforce strong typing for variables to ensure predictable behavior.
2. Dynamic Resource Configuration: Use variables to make resources reusable and
environment-agnostic.
3. Terraform Commands: Essential steps for managing resources effectively.

This modular and parameterized approach is essential for infrastructure as code (IaC) best
practices, making configurations flexible and scalable.
Terraform Manifest-v1: -

c1-versions.tf

Explanation: - The code provided represents a typical Terraform configuration file that defines
a Terraform block, a provider block, and a random string resource. Below is a detailed
explanation of each section:
1. Terraform Block

The Terraform block is used to configure the version of Terraform and the required providers
for the configuration.

Code:

terraform {
required_version = ">= 1.0.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 2.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.0"
}
}
}

Explanation:

1. required_version:

- Ensures that the Terraform CLI version is at least 1.0.0.


- If an incompatible version is used, Terraform will throw an error.
2. required_providers:

- Specifies the providers required for this configuration:

- azurerm: Azure Resource Manager provider for managing Azure resources.


- source: Specifies the provider’s namespace (hashicorp) and name (azurerm).
- version: Ensures the provider version is >= 2.0.

- random: Generates random values (used here for creating random strings).
- source: The random provider from hashicorp.
- version: Ensures the provider version is >= 3.0`.

2. Provider Block

The provider block specifies the configuration for the Azure Resource Manager (azurerm)
provider.

Code:

provider "azurerm" {
features {}
}

Explanation:

1. Provider:
- Defines the Azure Resource Manager (azurerm) provider.

2. features {}:
- A mandatory block (even if empty) that enables features specific to the Azure provider.
- Leaving it empty means default settings are applied.
3. Random String Resource
The random_string resource generates a random string, which can be used for naming or other
dynamic configuration purposes.

Code:

resource "random_string" "myrandom" {


length = 6
upper = false
special = false
number = false
}

Explanation:

1. Resource Type:
-random_string: A resource provided by the random provider to create random strings.

2. Resource Name:
- myrandom: The local name of this resource within the configuration.

3. Arguments:
- length = :
- Specifies the length of the generated string (6 characters in this case).

- upper = false:
- Excludes uppercase letters from the string.

- special = false:
- Excludes special characters from the string.
- number = false:
- Excludes numbers from the string.

- Result: The string will consist of 6 lowercase alphabetic characters.

Overall Purpose

This Terraform configuration:

1. Ensures the environment is set up with the required Terraform version and provider plugins.
2. Configures the Azure provider (azurerm) for managing Azure resources.
3. Generates a random lowercase string (without special characters or numbers) that can be
used dynamically in other resources, such as naming conventions for Azure resources.

Usage Example

- You could use the generated string from random_string.myrandom as part of a resource name:

resource "azurerm_resource_group" "example" {


name = "example-rg-${random_string.myrandom.result}"
location = "East US"
}

- This would create a resource group with a name like example-rg-abcdef, ensuring unique
names when re-deploying.
Terraform Manifest: -

c2-resource-group.tf
Explanation: - This Terraform code defines input variables that are used throughout the Terraform
configuration to make it dynamic and reusable. Input variables allow users to customize the values for
a Terraform module without hardcoding them in the configuration.

1. Purpose of Input Variables

- Input Variables: These are placeholders for values that can be passed into a Terraform module. They
help:

- Increase flexibility by making the configuration reusable for different environments or scenarios.

- Avoid hardcoding values in Terraform scripts.

2. Structure of an Input Variable

Each variable follows a common structure:

variable "variable_name" {

description = "Description of what the variable is used for"

type = <data type>

default = <default value>

Components:

1. variable: Declares a variable block.

2. "variable_name": The name of the variable, which will be referenced in the code as
var.<variable_name>.

3. description: Describes the purpose of the variable. Helps users understand what the variable is used
for.

4. type: Specifies the data type of the variable, such as string, number, list, or map.

5. default: (Optional) Provides a default value. If no value is supplied during execution, Terraform uses
this default.
3. Variables in the Code

1. Business Unit Name

variable "business_unit" {

description = "Business Unit Name"

type = string

default = "hr"

- Defines a variable named business_unit.

- Purpose: Specifies the logical grouping or department (e.g., HR, Finance).

- Default: "hr". If no other value is supplied, this will be used.

2. Environment Name

variable "environment" {

description = "Environment Name"

type = string

default = "dev"

- Purpose: Identifies the deployment environment (e.g., development, staging, production).

- Default: "dev".

3. Resource Group Name

variable "resource_group_name" {

description = "Resource Group Name"

type = string

default = "myrg"

}
- Purpose: Represents the name of the Azure Resource Group.

- Default: "myrg".

4. Resource Group Location

variable "resource_group_location" {

description = "Resource Group Location"

type = string

default = "East US"

- Purpose: Specifies the Azure region where the Resource Group will be created.

- Default: "East US" (equivalent to eastus in Azure).

5. Virtual Network Name

variable "virtual_network_name" {

description = "Virtual Network Name"

type = string

default = "myvnet"

- Purpose: Represents the name of an Azure Virtual Network.

- Default: "myvnet".

6. Extensibility

The section titled YOU CAN ADD LIKE THIS MANY MORE argument values" lists additional resource
names that can be parameterized using variables:
- Examples of potential variables:

1. Subnet Name: Name for subnets in the Virtual Network.

2. Public IP Name: Name for public IP addresses.

3. Network Interface Name: Name for network interfaces attached to virtual machines.

4. Virtual Machine Name: Name for Azure virtual machines.

5. VM OS Disk Name: Name of the operating system disk of a virtual machine.

6. ...and more.

These can be defined in the same way as the variables above.

5. Benefits

- Reusability: The module can be reused for different environments by simply changing variable values.

- Clarity: Descriptions provide clear documentation for anyone using the configuration.

- Customization: Default values can be overridden during runtime using a terraform.tfvars file or CLI
arguments.

6. Example Usage

When applying the configuration, Terraform resolves variables by:

1. Using default values (as provided in this file).

2. Overriding defaults via:

- A terraform.tfvars file:

business_unit = "finance"

environment = "prod"

resource_group_name = "rg-finance-prod"

resource_group_location = "West US"

virtual_network_name = "vnet-prod"
- CLI arguments:

terraform apply -var="business_unit=finance" -var="environment=prod"

7. Example Scenario

Using this configuration:

- For the HR Development Environment:

- Resource Group Name: hr-dev-myrg

- Location: East US

- For the Finance Production Environment:

- Resource Group Name: finance-prod-myrg

- Location: West US (overridden during runtime).

Terraform Manifest: -

c3-virtual-network.tf
Explanation: - This Terraform code block defines an Azure Resource Group using the
azurerm_resource_group resource. A resource group in Azure is a container that holds related
resources for an Azure solution.

1. Resource Block Declaration

resource "azurerm_resource_group" "myrg" {

- resource: Specifies a resource to create and manage in Terraform.

- azurerm_resource_group: The type of resource being created, which is an Azure Resource Group in
this case. It uses the AzureRM Terraform provider.

- "myrg": The unique name given to this resource within the Terraform configuration. You use this
name to reference the resource in other parts of your code.

2. Properties/Attributes

name

name = "${var.business_unit}-${var.environment}-${var.resource_group_name}"

- Specifies the name of the Azure Resource Group.

- The value is dynamically constructed using variables. Here's what each part means:

- ${}: Denotes string interpolation in Terraform, allowing you to insert variables or expressions into
strings.

- var.business_unit: Refers to a variable named business_unit, likely defined elsewhere in the


Terraform configuration. This variable might represent a logical grouping (e.g., "finance" or
"marketing").

- var.environment: Refers to another variable, typically used to denote the environment, such as dev,
test, or prod.

- var.resource_group_name: A variable that represents a specific part of the resource group's name.

When these variables are defined, the resulting name could look like:
finance-prod-my-rg

location

location = var.resource_group_location

- Specifies the Azure region where the resource group will be created.

- var.resource_group_location: Refers to a variable containing the location, e.g., `eastus`, `westus2`,


etc.

3. Comments

name = "my-rg1"

name = var.resource_group_name

- These are commented-out lines, likely for testing or future use:

- name = "my-rg1": Shows a hardcoded example of a resource group name.

- name = var.resource_group_name: Demonstrates a simpler use of a variable for the resource group
name, without string interpolation.

These comments provide alternatives for how the name can be defined.

4. Usage

- This resource will create a Resource Group in Azure with:

- A name composed of the business_unit, environment, and resource_group_name variables.

- A location defined by the resource_group_location variable.

5. Example Variable Definitions

To make this resource functional, the referenced variables (business_unit, environment,


resource_group_name, resource_group_location) must be defined in the Terraform configuration,
typically in a variables.tf file or inline. For example:

variable "business_unit" {

default = "finance"

}
variable "environment" {

default = "prod"

variable "resource_group_name" {

default = "my-rg"

variable "resource_group_location" {

default = "eastus"

6. Final Generated Resource Group

If these variable values are used, the created resource group will have:

- Name: finance-prod-my-rg

- Location: eastus

Terraform Manifest: -

C4-virtual-network.tf
Explanation: - This Terraform code creates an Azure networking setup involving a virtual
network, subnet, public IP addresses, and network interfaces.

1. Virtual Network

Code:

resource "azurerm_virtual_network" "myvnet" {


name = "myvnet-1"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.myrg.location
resource_group_name = azurerm_resource_group.myrg.name
}

Explanation:

1. Resource Type:
- azurerm_virtual_network: Used to create a virtual network in Azure.

2. Resource Name:
- myvnet: A logical identifier to reference this virtual network resource in the code.

3. Arguments**:
- name: Specifies the name of the virtual network (myvnet-1).
- address_space: Defines the IP range of the virtual network as a CIDR block (10.0.0.0/16).
- location: Uses the location of the associated resource group
(azurerm_resource_group.myrg.location).
- resource_group_name: Refers to the name of the resource group
(azurerm_resource_group.myrg.name).
4. Purpose:
- Provides an isolated network environment to host resources securely.

2. Subnet
Code:

resource "azurerm_subnet" "mysubnet" {


name = "mysubnet-1"
resource_group_name = azurerm_resource_group.myrg.name
virtual_network_name = azurerm_virtual_network.myvnet.name
address_prefixes = ["10.0.2.0/24"]
}

Explanation:

1. Resource Type:
- azurerm_subnet: Used to create a subnet within a virtual network.

2. Resource Name:
- mysubnet: A logical name for referencing the subnet resource.

3. Arguments:
- name: Specifies the name of the subnet (mysubnet-1).
- resource_group_name: Associates the subnet with the resource group
(azurerm_resource_group.myrg.name).
- virtual_network_name: Associates the subnet with the virtual network
(azurerm_virtual_network.myvnet.name).
- address_prefixes: Defines the IP range of the subnet (10.0.2.0/24).
4. Purpose:
- Creates a smaller segment within the virtual network for resource allocation and
management.

3. Public IP Addresses

Code:

resource "azurerm_public_ip" "mypublicip" {


for_each = toset(["vm1", "vm2"])
name = "mypublicip-${each.key}"
resource_group_name = azurerm_resource_group.myrg.name
location = azurerm_resource_group.myrg.location
allocation_method = "Static"
domain_name_label = "app1-${each.key}-${random_string.myrandom.id}"
}

Explanation:

1. Resource Type:
- azurerm_public_ip: Creates a public IP address.

2. for_each Loop:
- Uses toset(["vm1", "vm2"]) to create a public IP for each key (vm1, vm2).
- Each key allows distinct public IP configuration for separate VMs.

3. Arguments:

- name: Dynamically generates names (mypublicip-vm1 and mypublicip-vm2).


- resource_group_name: Associates the public IP with the resource group
(azurerm_resource_group.myrg.name).
- location: Uses the location of the resource group.
- allocation_method: Specifies a **static** IP allocation (the IP remains fixed after
assignment).
- domain_name_label: Creates a DNS name label for each public IP (e.g., app1-vm1-xyz123).
4. Purpose:
- Provides external IP addresses for resources (e.g., VMs) to make them accessible over the
internet.
4. Network Interfaces

Code:
resource "azurerm_network_interface" "myvmnic" {
for_each = toset(["vm1", "vm2"])
name = "vmnic-${each.key}"
location = azurerm_resource_group.myrg.location
resource_group_name = azurerm_resource_group.myrg.name

ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.mysubnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.mypublicip[each.key].id
}
}

Explanation:

1. Resource Type:
- azurerm_network_interface: Creates network interfaces for VMs.

2. for_each Loop: - Similar to the public IP block, it uses toset(["vm1", "vm2"]) to create one
network interface for each key.
3. Arguments:
- name: Generates unique names (vmnic-vm1, vmnic-vm2).
- location: Inherits the location of the resource group.
- resource_group_name: Links the network interface to the resource group.

4. ip_configuration Block:
- Defines the network settings for the interface.
- name: A logical identifier for the IP configuration (internal).
- subnet_id: Connects the network interface to the subnet (azurerm_subnet.mysubnet.id).
- private_ip_address_allocation: Specifies dynamic private IP allocation.
- public_ip_address_id: Attaches the associated public IP
(azurerm_public_ip.mypublicip[each.key].id).

5. Purpose:
- Connects VMs to the virtual network and assigns them public/private IP addresses for
internal and external communication.

Flow of Resources

1. Virtual Network (myvnet):


- Acts as the overarching network where resources are deployed.

2. Subnet (mysubnet):
- Segments the virtual network for specific resource grouping and IP management.

3. Public IPs (mypublicip):


- Provides internet-facing static IPs for VMs.

4. Network Interfaces (myvmnic):


- Connects VMs to the subnet and assigns public/private IPs for communication.
Dynamic Resource Creation (for_each)
- Why Use for_each?
- It simplifies the creation of multiple similar resources (e.g., public IPs and NICs) by looping
over a set of keys (vm1, vm2).
- Dynamic resource creation minimizes repetitive code and ensures scalability.
Result

After running this Terraform configuration:


1. A virtual network and subnet are created.
2. Two public IP addresses (mypublicip-vm1, mypublicip-vm2) are provisioned.
3. Two network interfaces (vmnic-vm1, vmnic-vm2) are created and linked to the subnet and
their respective public IPs.

Real-World Application

This configuration sets up the foundational network infrastructure for deploying multiple VMs
with distinct network interfaces and public IPs. It's common in scenarios like:
- Hosting web applications.
- Setting up a cluster of VMs for load balancing.
- Providing isolated environments for testing or development.

You might also like