Picture this: you're gearing up to harness the full potential of Terraform, the ultimate Swiss Army knife for managing your cloud infrastructure. You've got your sights set on orchestrating a symphony of resources, effortlessly spinning up servers, configuring networks, and deploying applications with a single command. But here's the kicker: before you can even dive into the Terraform magic, there's a crucial first step you can't afford to overlook. It's the classic chicken and egg conundrum - which came first? You're itching to wield Terraform's power, yet you find yourself needing a secure sanctuary to house the all-important Terraform state file. Think of it as setting the stage before the performance begins - essential, yet often overlooked.
Fear not, for we're about to unravel the mysteries of Terraform state management and guide you through the labyrinth of storage solutions. Join us as we embark on a journey to demystify the intricacies of choosing, configuring, and integrating the perfect storage account for your Terraform state. From understanding the importance of state management to handpicking the ideal storage solution, we've got you covered every step of the way. So, grab your compass and strap in - it's time to navigate the Terraform terrain like a seasoned explorer.
Preface: Cloud Provider Consideration
Before we proceed, it's important to note that while we'll be using Microsoft Azure in this guide, the process is nearly identical across various cloud providers like AWS or Google Cloud. So, whether you're navigating Azure's portal, AWS Management Console, or Google Cloud Platform dashboard, the principles of Terraform state management remain consistent. Let's dive in!
1. Creating the Storage Account for Terraform State Management
While we're all about automation and letting Terraform do the heavy lifting, there's a minor hiccup at the beginning of our journey. We'll need to manually set up the storage account that'll house our Terraform state file. But fret not, dear reader, for this initial manual setup is just a stepping stone towards the blissful realm of automated infrastructure management.
Here's how we get started:
Navigate to the Azure Portal: https://portal.azure.com/#home
Create a New Storage Account: In the search box on top of the page, search for 'storage account'. This should show the option to create a new storage account.
Configure the Storage Account: Go through the setup process, noting the configuration you selected. This will be needed later when we would like to manage the storage account in Terraform.
Review and Create: Double-check all your configurations to ensure everything looks good, then hit the create button to deploy your storage account. Here is a summary of the storage account that was created for this guide:
Resource group | rg-terraform-ae |
Location | Australia East |
Name | stterraformstatefileae |
Performance | Standard |
Replication | LRS |
Enable hierarchical namespace | Disabled |
Enable SFTP | Disabled |
Enable network file system v3 | Disabled |
Allow cross-tenant replication | Disabled |
Access tier | Hot |
Enable large file shares | Disabled |
Secure transfer | Enabled |
Blob anonymous access | Disabled |
Allow storage account key access | Enabled |
Default to Microsoft Entra authorization in the Azure portal | Disabled |
Minimum TLS version | 1.2 |
Permitted scope for copy operations | From any storage account |
Network connectivity | Public |
Default routing tier | Microsoft |
Point-in-time restore | Disabled |
Blob soft delete | Enabled |
Blob retainment period in days | 7 |
Container soft delete | Enabled |
Container retainment period in days | 7 |
File share soft delete | Enabled |
File share retainment period in days | 7 |
Versioning | Disabled |
Blob change feed | Disabled |
Version-level immutability support | Disabled |
Encryption type | MMK (Microsoft-managed Keys) |
Enable support for customer-managed keys | Blobs and files only |
Enable infrastructure encryption | Enabled |
Tags | CreatedBy: info@datainsightnest.com Environment: dev Owner: datainsightnest Region: austrailiaeast Workload: statefile |
Configure RBAC for Your Storage Account: Congratulations on laying the foundation for managing your Terraform state file! Next, it's essential to set up Role-Based Access Control (RBAC). Typically, this involves assigning a service principal (the same one used for Terraform infrastructure deployment) with 'Storage Blob Data Contributor' permissions.
Create a container named tfstate and upload an empty file named terraform.tfstate.
2. Import your current infrastructure into your state file
Now that we've laid the groundwork by setting up our Azure Storage Account and preparing our Terraform configuration, it's time to delve into the heart of the matter: importing our existing infrastructure into the Terraform state file. This process is akin to taking an inventory of your existing resources and allowing Terraform to manage them moving forward. Let's break this down into easy-to-follow steps:
2.1. Initialise Terraform Configuration
Before importing, ensure you have initialised your Terraform configuration. If you haven’t done so, navigate to your Terraform directory and run.
terraform init \
-backend-config="resource_group_name=rg-terraform-ae" \
-backend-config="storage_account_name=stterraformstatefileae" \
-backend-config="container_name=tfstate" \
-backend-config="key=terraform.tfstate"
2.2. Import Resources
Identify which Azure resources you want to manage with Terraform. Make a list of these resources, including their types and names. In our case is it just the resource group, storage account and container. For each resource you want to import, use the terraform import command followed by the resource type and name, and the Azure resource identifier. Here’s a general syntax:
terraform import azurerm_resource_type.resource_name resource_id
Replace azurerm_resource_type.resource_name with the Terraform resource type and name, and resource_id with the Azure resource identifier. Here is what it will look like for our three resources. These commands will need to be run one by one.
Tip: You can grab the Resource ID from the JSON view of the resource
# Resource Group
terraform import azurerm_resource_group.rg /subscriptions/<subscription_id>/resourceGroups/rg-terraform-ae
# Storage Account
terraform import azurerm_storage_account.sa /subscriptions/<subscription_id>/resourceGroups/rg-terraform-ae/providers/Microsoft.Storage/storageAccounts/stterraformstatefileae
# Container
terraform import azurerm_storage_container.sc https://stterraformstatefileae.blob.core.windows.net/tfstate
3. Prepare Your Terraform Configuration
Before we proceed with importing resources into the Terraform state file, let's understand the concept. When you import existing resources, Terraform records the resource information in its state file, allowing you to manage these resources using Terraform going forward. However, it's important to note that importing resources alone doesn't create a Terraform configuration file (*.tf) with the resource configuration. The *.tf files serve as the blueprint for your infrastructure, defining how resources should be provisioned, configured, and managed by Terraform. Therefore, alongside importing resources into the state file, you also need to create or update the appropriate Terraform configuration files with the desired resource configurations. This ensures that Terraform can effectively manage the resources according to your infrastructure specifications. Remember the names you provided during the import stage - we need to use them in our configuration.
terraform {
required_version = "~>1.6.4"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.83.0"
}
}
backend "azurerm" {
resource_group_name = "rg-terraform-ae"
storage_account_name = "stterraformstatefileae"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
provider "azurerm" {
features {}
}
variable "tags" {
type = map(string)
default = {
CreatedBy = "info@datainsightnest.com"
Environment = "dev"
Owner = "datainsightnest"
Region = "australiaeast"
Workload = "statefile"
}
description = "Tags for the resources."
}
resource "azurerm_resource_group" "rg" {
name = "rg-terraform-ae"
location = "australiaeast"
tags = var.tags
}
resource "azurerm_storage_account" "sa" {
name = "stterraformstatefileae"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
allow_nested_items_to_be_public = false
cross_tenant_replication_enabled = false
infrastructure_encryption_enabled = true
tags = var.tags
}
resource "azurerm_storage_container" "sc" {
name = "tfstate"
storage_account_name = azurerm_storage_account.sa.name
container_access_type = "private"
}
Validate Import
After importing each resource, it’s a good practice to run terraform plan to validate the import and ensure Terraform recognises the imported resources. This will show you the planned changes, indicating that Terraform has successfully imported the resources into the state file. To do this, run the following command.
terraform plan
This should result in your plan showing no additional changes will occur. You should see a message:
No changes. Your infrastructure matches the configuration.
Congratulations! You've successfully imported your existing Azure infrastructure into the Terraform state file and updated the Terraform configuration files. You're now ready to manage your infrastructure using Terraform's powerful automation capabilities. Keep exploring, keep automating, and remember, with Terraform, the sky's the limit!
Comments