3. Practical Example: AWS EC2 Import
Hands-on example of importing AWS EC2 resources into Terraform.
πΉοΈ Terraform Import: Bringing Resources Under Control
In the previous post π° Getting Started with Terraform Import, we explored how ABC Corp tackled the challenges of managing cloud infrastructure by leveraging Terraform Import. We discussed the importance of bringing unmanaged resources under Infrastructure-as-Code (IaC) control and refactoring Terraform configurations for scalability. The post outlined ABC Corpβs environment, the challenges they faced (like configuration drift and manual operations), and the prerequisites for getting started with Terraform Import.
We also introduced a systematic workflow for importing resources, integrating automation, and aligning infrastructure with GitOps principles. This sets the stage for this post, where weβll dive into a hands-on example of importing AWS EC2 instances into Terraform. By following this guide, youβll learn how to transition manually provisioned resources into Terraform-managed infrastructure, enabling better control, scalability, and collaboration.
Before diving into the example, ensure you have reviewed the prerequisites outlined in the previous blog post. If not, refer to for detailed guidance. π° Getting Started with Terraform Import
π― Objective
This guide demonstrates how to transition manually provisioned AWS resources into Terraform-managed infrastructure. It provides a step-by-step process to help you integrate existing resources into Terraform and manage them effectively using Infrastructure as Code (IaC) practices.
π Scenario
Imagine you are managing an application say codifyme that was initially deployed with manually provisioned AWS resources. Your infrastructure team has recently adopted DevOps practices and IaC for managing infrastructure. Each application now has a dedicated Terraform workspace, folder, and state file. However, some resources, like your EC2 instance, were created before this transition and are still managed manually.
To align with the new DevOps workflow, you decide to bring these manually managed resources under Terraformβs control. This involves importing the resources into Terraform state and converting their configuration into .tf files for future management.
π‘ Considerations
- βοΈ Cloud Provider: AWS is the cloud platform used in this example.
- π Terraform Enterprise (TFE): A workspace and repository are already set up to manage the imported EC2 resources.
- π₯οΈ Existing Terraform-Managed VM: The state of the existing VM is managed by the TFE workspace, with its configuration hosted in an Azure DevOps (ADO) repository. This example mimics a scenario where you already have Terraform-managed resources and want to integrate newly discovered or imported resources into the same state management.
β Expected Outcomes
By following this guide, you will achieve the following:
- β Import an AWS EC2 instance into Terraform state.
- β
Generate a clean and reusable
.tfconfiguration file (flat.tf) for the imported instance. - β Store the EC2 instanceβs state in a centralized TFE workspace for better collaboration and management.
- β Enable lifecycle management of the EC2 instance using Terraform, ensuring it aligns with your organizationβs IaC practices.
π οΈ Key Tools and Codebase
- π·οΈ Tagging Script: A custom PowerShell script is used to add tags to existing EC2 instances. These tags help identify and filter the instances to be imported.
- π¦ Import Script: A custom Python script or the Terraformer tool is utilized to import AWS resources into Terraform. This script generates Terraform import blocks, cleans up unnecessary parameters, and ensures the configuration is ready for use.
You can access the codebase and scripts from the following GitHub repository:
π terraform-import-and-refactor
This setup ensures a streamlined process for importing resources and managing them effectively using Terraform.
π§βπ» Hands-On Process
1. π Create a New Folder for the Example EC2 VMs
on your local machine, create a new folder for the example EC2 VM. This folder will contain all the necessary files and scripts for the import process.
1
2
mkdir terraform-import-and-refactor
cd terraform-import-and-refactor
2. π Clone the Tagging Script Repository
Download or clone the GitHub repository containing the tagging script. This script helps add tags to the instances you want to import.
1
2
git clone https://github.com/ravijoshi1810/terraform-import-and-refactor.git
cd aws_resource_tag.v2
3. π Add Instance IDs
π Add the instance IDs to the
ec2_instances_ids.txtfile (input file) and save it.# Example file content i-00669cc8d4e53cb02 # codifyme-web-1 i-02b68140b57cbb812 # codifyme-web-2note:create the file if not already available.
4. π·οΈ Run the Tagging Script
π Paste the admin credentials for PowerShell from the AWS Console into the terminal.
π Run the following command:
cd aws_resource_tag.v2 .\aws_tag_main.ps1 -TagEC2β Verify that the tags were added by checking the
tagged_instances.csv(output file).1 2 3 4
C:\terraform-import-and-refactor\aws_resource_tag.v2> cat .\tagged_instances.csv AWS Account ID,Instance ID,Name,State,Tag 847066372451,i-00669cc8d4e53cb02,codifyme-web-1,running,IACImported=No 847066372451,i-02b68140b57cbb812,codifyme-web-2,running,IACImported=No
This will assure even if your organization is not managing the required tags, you can still import the resources using the tagging script.
If you get an error while running the script, make sure you have the required permissions to run the script. You can check the permissions by running the following command:
# π This will show you the current execution policy for each scope. Get-ExecutionPolicy -List ## π οΈ If the execution policy is set to "Restricted" for the current user or process, you can change it to "Bypass" or "RemoteSigned" temporarily for the current session. ## π‘ This will allow you to run scripts in the current session without changing the execution policy permanently. Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
5. π Download the Python Script
β¬οΈ Download the Python script into the example folder and open it in VS Code.
6. π Run the Custom Python Script
π Run the script using the following command:
1
python3 main.py --resource ec2 --local-repo-path ../terraform-import-example/imported-ec2 --region us-east-1 --hosted-zone-name 2334356634.eu-west-1.abc.corp --tag IACImported no
π‘ What Happens Behind the Scenes When You Run the Script?
π The script generates a file named
import_codifyme-web-1in the specified directory. This file contains the import blocks for the resources.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import { to = aws_instance.codifyme-web-1 id = "i-028015c8ff2e485f1" } import { to = aws_ebs_volume.vol-0765af5e7f98e4ff2 id = "vol-0765af5e7f98e4ff2" } import { to = aws_instance.codifyme-web-2 id = "i-0a1b2c3d4e5f6g7h8" } import { to = aws_ebs_volume.vol-1234567890abcdef0 id = "vol-1234567890abcdef0" }
π It also generates a file named
generated-plan-import-ec2Name.tf, which contains the Terraform configuration for the resources.1 2 3 4 5 6 7
resource "aws_instance" "codifyme-web-1" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t2.micro" tags = { Name = "codifyme-web-1" } }
- π§Ή The script cleans up unnecessary resources and parameters from the configuration file.
- π§Ή Removes global patterns.
- π§Ή Processes resource-specific blocks.
- π§Ή Removes multiline patterns.
- π§Ή Cleans up tags, CPU options, credit specifications, and Kerberos attributes.
- π§Ή Removes unnecessary blocks like
ebs_block_device.
- π It runs
terraform initandterraform planto initialize the Terraform working directory and generate an execution plan for the import.
After successfully running the script, you will see the following directory structure:
7. π Verify the Plan Output
After running the script, review the Terraform plan output and the generated files in the import directory.
β οΈ Important:
β Ensure that only the import count has changed in the plan output and no other changes are present.
π οΈ If there are changes, review and update the Terraform code accordingly before proceeding.
8. π Apply the Terraform Configuration
Once you confirm that only the import count has changed during plan, run the following command to apply the changes:
1
terraform apply -auto-approve
This will import the resources into the Terraform state file locally.
ππ Great job done, folks!
You have successfully imported the EC2 instances into Terraform. But the work is not done yet.
This is the stage where local testing considered as completed and the real state has to be created on TFE workspace or on remote blob state. You can delete the local state file created in above stages.
The main goal is to have the Terraform code in the TFE workspace or in remote state management systme if using opensource cli and manage the state file there.
9. π Clone the TFE or Git Repository
π Login to Azure DevOps (ADO) or the Git tool of your choice, and navigate to the TFE or CLI code repository where you plan to import the resources. Clone the repository into VS Code for further modifications.
10. π Copy the Generated Files to the Cloned Repository
π Copy the import_codifyme-web-1, generated-plan-import-codifyme-web-1 files from the local folder to the cloned repository.
Note: β οΈ Make sure the existing code repository must already have the provider block defined in the backend.tf file.
- π·οΈ Rename the
generated-plan-import-codifyme-web-1file to align with your organizationβs naming standards. For example, rename it tocodifyme-web-1.tf. - β‘οΈ Move the
import_codifyme-web-1file to a subfolder namedimported-files. This step is optional and can be useful when re-importing multiple resources. Alternatively, you can delete this file after a successful import.
Up to this point, if you have VCS integration enabled in TFE or a GitOps-triggered pipeline, the changes will be automatically detected. A plan will be created in the TFE workspace, followed by an apply process, which may require approval.
- If you are using a CLI-driven workflow, proceed with the following steps.
11. βοΈ Terraform Cloud/Enterprise Init, Plan and Apply
π Login to TFE by running this command
terraform login yourtfe-urland provide the token.1
terraform login https://your-tfe-url -token your-token
- π Run the following command to initialize the Terraform working directory:
1
terraform init
- Run the following command to generate an execution plan:
1
terraform plan
Review the plan output to ensure that only the import count has changed and no other changes are present.
- If everything looks good, run the following command to apply the changes:
1
terraform apply -auto-approve
This will import the resources into the Terraform state file in the TFE workspace.
- β Verify the import by checking the TFE workspace for the imported resources.
- β
Check the state file in the TFE workspace or cli to ensure that the resources are managed by Terraform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
terraform state list # output aws_db_instance.codifyme-db aws_ebs_volume.vol-040fe5e45baeed0f1 aws_ebs_volume.vol-0b37eb5ce5321fc85 aws_ebs_volume.vol-0b7fe6a8ce9d2d8e5 aws_ebs_volume.vol-0dc83899bd3fb817c aws_instance.codifyme-web-1 aws_instance.codifyme-web-2 aws_volume_attachment.vol-040fe5e45baeed0f1 aws_volume_attachment.vol-0b37eb5ce5321fc85 aws_volume_attachment.vol-0b7fe6a8ce9d2d8e5 aws_volume_attachment.vol-0dc83899bd3fb817c aws_s3_bucket.example_bucket aws_s3_bucket_policy.example_bucket_policy aws_lb.codifyme_lb aws_lb_listener.codifyme_lb_listener aws_lb_target_group.codifyme_lb_target_group
congratulations! You have successfully imported the AWS EC2 instance into Terraform and managed it using TFE as infra as code.
- β You can now manage the EC2 instance using Terraform, including making changes, scaling, and applying updates as needed.
π‘ Tips and Best Practices
- π οΈ If there are non-impacting changes in the plan output, use the
lifecycleblock to ignore them. - π·οΈ Add specific Terraform resource attributes to mitigate unnecessary changes in the plan output.
π Conclusion
In this blog post, we successfully imported an existing AWS EC2 instance into Terraform using a custom Python script and a tagging script. We also discussed the importance of managing the state file in Terraform Enterprise (TFE) and best practices for handling plan outputs.
β‘οΈ In the next blog post, we will explore how to refactor the imported Terraform code for better organization and maintainability. Stay tuned for Refactoring Terraform Code: Why It Matters.
Catch you later, code Ninjas! Happy Codifying! βοΈπ»π











