Terraform Getting Started
Date published:
Terraform is a tool that allows users to deploy resources to multiple cloud providers, AWS, Azure, GCP, and even on-premise infrastructure. It has a platform-agnostic approach that doesn’t require programming knowledge. The providers interact with the APIs and provider and on-premise resources. One of the benefits is using it to declare and deploy infrastructure to multiple systems.
Terraform is a great way to start your infrastructure as a code in Azure. I will be showing some of the basics fundamentals of using it and how to deploy any resources. In this blog, I will explain how the fundamentals of using terraform
Here are some of the frequently used commands when working using terraform.
-
terraform init - initialize directory and pull down the provider
-
terraform plan - creates a plan that lets you preview the changes before deploying the resource to your infrastructure. By default, it compares the configuration file with the remote resource to see if it is up to date. Otherwise, you can see the changes.
-
terraform apply - Apply the changes to the configuration.
-
terraform destroy - destroy the resource deploy in the state file
Extra useful commands
-
terraform refresh - reconcile the state in Terraform state file with real-world resources
-
terraform state list - list the terraform state
-
terraform state show - display details stored in the terraform state file for the resource.
- How to create a config file?
Terraform Project – A directory/folder that contains one or more Terraform files that are all a part of the same infrastructure deployment.
Terraform used configuration files to store all the code. For example, if we declare that we want two virtual machines in the code, Terraform will build them but later wish to make changes to one of the virtual machines. Terraform will remove the other virtual machine from the environment because it is no longer in the code and then re-deploy it. The code in the configuration file starts with a .tf extension.
- What is Terraform Provider?
The provider will be the cloud provider to deploy the resource, such as azurerm for azure resources. . A provider is like a plugin that Terraform uses to create and manage your resources. Multiple provider blocks are used in a Terraform configuration to collect resources from different providers.
#Azure provider
provider "azurerm" {
features {}
}
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.40.0"
}
}
}
- How to create a terraform resource?
Resources – The primary construct in Terraform. These are the things that will be provisioned, like Storage Accounts, Virtual Machines, Virtual Networks, etc.
The example below shows how to create a resource group in Azure.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.40.0"
}
}
}
create resource group
resource "azurerm_resource_group" "rg" {
name = "rg-terraexample"
location = "westus2"
tags = {
Environment = "terraexample"
}
}
- How to use Terraform Variable?
Variables – This is a name given to a value to reference in one or more locations within a Terraform file. These are often called input variables passed to your terraform configuration before deployment.
variable.tf
variable "application" {
type = string
description = "Application name"
}
variable "location" {
type = string
description = "location"
}
You can reference the variable name “application” in the main.tf by using the label created for the resource group by using the {var. application} or just using var. location.
resource "azurerm_resource_group" "rg" {
name = "rg-${var.application}"
location = var.location
}
4.1) Output Variable - Return the output file on the terraform command line. Output variable created in an output.tf file. It would output the ID of the network security group.
Example of creating output.tf
output "nsg_id" {
description = "ID of the Network Security Group"
value = azurerm_network_security_group.nsg.id
}
This subnet resource created takes the output from the remote backend state file is the terraformdemo. It would reference the data block of the terraform state file and output the label. See below in the state file section for the backend file.
Example of creating a subnet
resource "azurerm_subnet" "app_subnet" {
name = "snet-dev-001"
resource_group_name = data.terraform_remote_state.terraformdemo.outputs.rg_name
virtual_network_name = data.terraform_remote_state.terraformdemo.outputs.vnet_name
address_prefixes = ["10.0.2.0/24"]
}
- What is Terraform State File
Terraform State file keeps track of resources created by your configuration and maps them to real-world resources. This is the default in a local file named “terraform. tfstate”, but it can also be stored remotely, which works better in a team environment. A local state file is when the terraform configuration store the file locally. Any changes to the terraform code will also make changes to the state file displayed by running:
- terraform state list - View the name of the state file
- terraform state show ’name of state file'
You can store the state file remotely when working in a large team and want to secure it. I would recommend keeping the file in azure storage with a blob container. it is created by running the following command:
Create RG for storing State Files
az group create --location westus2 --name rg-terraformstate
Create Storage Account
az storage account create –name terrastatestorage2188
–resource-group rg-terraformstate –location westus2 –sku Standard_LRS
Create Storage Container
az storage container create –name terraformdemo
–account-name terrastatestorage2188
Backend remote state file - The data block type is the terraform remote state labelled terraformdemo. Inside, the data block has information that it would retrieve from the backend block in the main.tf or the provider.tf file. When authenticating to the backend state file
data "terraform_remote_state" "terraformdemo" {
backend = "azurerm"
config = {
resource_group_name = "rg-terraformstate"
storage_account_name = "terrastatestorage2188"
container_name = "terraformdemo"
key = "dev.terraform.tfstate"
}
}
When authenticating the backend state file in Azure storage, you can do it using a few methods here. Still, I would recommend doing it as an environment variable locally or creating a service principal via Azure DevOps. When authenticating this way, it would avoid putting keys in your terraform code like the access key of the storage account.
I will be showing how you can use your storage account access key as an environment variable to authenticate to Azure.
Open Powershell and run the following command with your ClientID, Client Secret, Subscription ID and Tenant ID.
$env:ARM_CLIENT_ID="00000000-0000-0000-0000-000000000000"
$env:ARM_CLIENT_SECRET="00000000-0000-0000-0000-000000000000"
$env:ARM_SUBSCRIPTION_ID="00000000-0000-0000-0000-000000000000"
$env:ARM_TENANT_ID="00000000-0000-0000-0000-000000000000"
Run the gci env: ARM_* command to view the environment variable
- How to use Module – A module is essentially a directory that contains Terraform files across multiple Terraform deployment projects or teams. Modules are a set of codes that are used together. A module comprises root modules and child modules. The root module is where you define all your code in the working directory and a child module can call other modules to include in your resource. A child module can call multiple times within the same code, and multiple codes can use the same child module.
Modules can be used to create lightweight abstractions, so that you can describe your infrastructure in terms of its architecture, rather than directly in terms of physical objects.
Declare the storage account module in the main.tf file in the root of the module directory folder.
Create resource group
resource "azurerm_resource_group" "rg" {
name = "rg-myapp"
location = "westus"
}
Create Storage Account
module "storage_account1" {
source = "./modules/storage-account"
saname = "statfdemosa24234"
rgname = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
}
I hope this helps you learn the basics of using terraform :)
References :