Migrating to Terraform
1. Discovering Existing Infrastructure
| Command | Description | Notes |
|---|---|---|
| terraform import | Imports existing resources into Terraform state | Must manually update configuration after import |
| terraform state list | Lists all resources in the current state | Useful for discovering what's managed |
| terraform state show | Shows details of a specific resource | Can be used to inspect imported resources |
Note: After importing, you must manually create the corresponding Terraform configuration to ensure future state consistency.
Workflow: Discovering and Importing Infrastructure
- Identify existing resources in your cloud provider console or CLI
- Run
terraform state listto see what's already managed - Use
terraform importto bring resources into Terraform state - Create corresponding HCL configuration files for each imported resource
- Verify that the state matches actual infrastructure with
terraform plan
2. Importing Resources
Importing existing infrastructure into Terraform state allows you to manage pre-existing resources with Terraform.
| Command | Description | Example |
|---|---|---|
| terraform import | Imports a resource into Terraform state | terraform import aws_instance.web i-1234567890abcdef0 |
Note: After importing, you must manually create the corresponding resource block in your configuration file.
Warning: Importing does not automatically generate the HCL configuration. You must define the resource in your Terraform files.
| Option | Description | Notes |
|---|---|---|
| -config | Path to the configuration directory | Defaults to current directory |
| -state | Path to the state file | Defaults to terraform.tfstate |
| -lock | Lock the state file during import | Defaults to true |
3. Generating Configuration
| Property | Description | Example |
|---|---|---|
| terraform.required_version | Specifies the minimum version of Terraform required to run the configuration. | ">= 1.0" |
| provider | Defines the provider to use for managing resources (e.g., AWS, Azure). | |
| resource | Defines a resource to be managed by Terraform. | |
| data | Retrieves external data or information from a provider. | |
| output | Exports values from the Terraform configuration for use elsewhere. | |
Example: Basic Terraform Configuration
terraform {
required_version = ">= 1.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
}
output "instance_ip" {
value = aws_instance.web.private_ip
}
4. Using Import Blocks
| Property | Description | Example |
|---|---|---|
| import | Defines how to import existing infrastructure into Terraform state | |
Example: Importing an AWS EC2 Instance
import {
to = aws_instance.example
id = "i-1234567890abcdef0"
}
Note: The
to attribute specifies the resource address in your configuration, and id is the identifier of the existing resource in the cloud provider.Warning: Importing resources does not automatically generate the configuration code. You must manually create the resource block in your Terraform files.
5. Validating Imported State
| Command | Description | Notes |
|---|---|---|
| terraform state list | Lists all resources in the state | Useful for verifying imported resources |
| terraform state show <resource_address> | Shows details of a specific resource | Validate attributes match expected values |
Note: Ensure all imported resources are correctly mapped to their respective configurations in your Terraform files.
Warning: Modifying state directly can lead to inconsistencies. Always backup before manual changes.
6. Handling Import Conflicts
Note: Import conflicts occur when Terraform cannot uniquely identify a resource in the state file after an import operation.
| Conflict Type | Description | Solution |
|---|---|---|
| Duplicate Resource IDs | Multiple resources with the same ID in state | Manually edit state file to rename or remove duplicates |
| Missing Resource References | Imported resource not found in configuration | Recreate resource block with correct attributes |
| Attribute Mismatch | Imported resource has different attributes than config | Update configuration to match imported resource |
Example: Resolving Duplicate Resource IDs
terraform state list
terraform state show <resource_address>
terraform state rm <resource_address>
Workflow: Resolving Import Conflicts
- Run
terraform planto identify conflicts - Review state file for duplicate or missing resources
- Manually edit
terraform.tfstateif needed - Re-run
terraform applyto resolve state inconsistencies
Comparison: Import vs. Refresh
- Import: Adds existing resources to state without config
- Refresh: Updates state from real infrastructure
7. Migrating from CloudFormation
| Aspect | Terraform Approach | CloudFormation Approach |
|---|---|---|
| Resource Definition | resource "aws_instance" "example" { ... } |
Resources: Example: Type: AWS::EC2::Instance |
| State Management | Uses terraform.tfstate or remote backends |
Stores state in S3 with DynamoDB locking |
| Configuration Language | HCL (HashiCorp Configuration Language) | YAML or JSON |
| Modularity | Modular with module blocks |
Stacks and nested templates |
| Versioning | Versioned via Git or VCS | Versioned via S3 or CodePipeline |
Example: Migrating a Simple EC2 Instance
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1d0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
Migration Steps Overview
- Export existing CloudFormation stack resources to HCL format
- Use
terraform importto bring existing resources under Terraform control - Refactor CloudFormation templates into reusable Terraform modules
- Validate and test the new configuration before full migration
Note: Ensure all dependencies and resource relationships are correctly mapped during migration.
Warning: Always backup your CloudFormation stack and state before starting migration.
8. Migrating from ARM Templates
| ARM Template Element | Terraform Equivalent | Notes |
|---|---|---|
| Resource Group | azurerm_resource_group |
Represents a logical container for Azure resources |
| Virtual Machine | azurerm_linux_virtual_machine or azurerm_windows_virtual_machine |
Creates a VM instance in Azure |
| Storage Account | azurerm_storage_account |
Creates a storage account for data storage |
| Virtual Network | azurerm_virtual_network |
Defines a network in Azure with subnets |
| Public IP Address | azurerm_public_ip |
Assigns a public IP to a resource |
Example: Migrating a Resource Group
{
"parameters": {
"rgName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2021-04-01",
"name": "[parameters('rgName')]",
"location": "East US"
}
]
}
resource "azurerm_resource_group" "main" {
name = "example-resource-group"
location = "East US"
}
Example: Migrating a Virtual Machine
{
"parameters": {
"vmName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "[parameters('vmName')]",
"location": "East US",
"properties": {
"hardwareProfile": {
"vmSize": "Standard_B1s"
},
"osProfile": {
"computerName": "myVM",
"adminUsername": "adminuser"
},
"storageProfile": {
"imageReference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "18.04-LTS",
"version": "latest"
}
}
}
}
]
}
resource "azurerm_linux_virtual_machine" "main" {
name = "example-vm"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = "Standard_B1s"
admin_username = "adminuser"
admin_password = "Password123!"
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
}
Note: ARM templates use JSON syntax, while Terraform uses HCL. Ensure all resource dependencies and references are properly translated.
9. Using Third-Party Import Tools
Terraform provides several third-party tools to help with importing existing infrastructure into state. These tools can simplify the process of migrating from other IaC solutions or manually provisioned resources.
| Tool | Description | Supported Providers | Notes |
|---|---|---|---|
| terraform-importer | A community-driven tool that automates importing resources from various sources into Terraform state. | AWS, GCP, Azure, Kubernetes | Supports multiple cloud providers and can be extended via plugins. |
| tfimport | CLI tool to generate Terraform configuration from existing infrastructure. | AWS, GCP, Azure | Can generate HCL code from existing resources and manage state. |
| terraform-inventory | Generates inventory of Terraform-managed resources from state files. | All | Helps in analyzing and auditing existing Terraform configurations. |
Example: Using tfimport to import AWS resources
tfimport aws_instance.my_instance \
--region us-west-2 \
--id i-1234567890abcdef0
Note: Third-party tools may not support all Terraform features or providers. Always validate the generated configuration before applying changes.
10. Documenting Migration Process
Example: Migration Documentation Structure
# Terraform Migration Documentation
## 1. Current State
- Infrastructure as code: No
- Version control: None
- Configuration management: Manual
## 2. Target State
- Infrastructure as code: Terraform
- Version control: Git
- Configuration management: Terraform
## 3. Migration Steps
1. Identify existing resources
2. Create Terraform configuration
3. Import resources into state
4. Validate and test
5. Update documentation
## 4. Risks & Mitigations
- Risk: Data loss during migration
- Mitigation: Backup all resources before import
## 5. Rollback Plan
- Revert to previous infrastructure state if needed
| Documentation Section | Description | Status |
|---|---|---|
| Current State | Details of existing infrastructure and configuration practices | Required |
| Target State | Planned infrastructure as code setup with Terraform | Required |
| Migration Steps | Sequential steps to migrate from current to target state | Required |
| Risks & Mitigations | Identified risks and their mitigation strategies | Recommended |
| Rollback Plan | Procedure to revert to previous state if migration fails | Recommended |
Note: Documentation should be version-controlled and reviewed by stakeholders before migration begins.
Warning: Incomplete or inaccurate documentation can lead to failed migrations and data loss.