Home » Create a Terraform file from an existing EC2 instance

Infrastructure to Code- Create Terraform File From Existing EC2 Instance in AWS Console

by admin

Automation is one of the key aspects when it comes to provisioning an infrastructure since it saves a lot of time and money. There is always a need to create an infrastructure from code and scripts (the best examples might be CloudFormation and Terraform), but what if there is a standard infrastructure already in place and one wants to replicate or convert the same infrastructure to code? Therefore, we came across two such tools, aws2tf and Terraformer that help us in doing exactly that. This blog gives a walkthrough of a basic example where we create a .tf  file from an existing EC2 instance in the AWS console.

Terraformer

Terraformer is a CLI tool to convert your existing infrastructure to tf/json and tfstate files. You can find the supported providers, including major cloud like AWS, Azure, AliCloud, and IBM Cloud. The tfstate file has the information about the provisioned infrastructure which the terraform manages.

Terraformer supports terraform 0.13. To upgrade resources with new fields, upgrade the relevant Terraform providers.

How to install Terraformer

Follow the link here to install Terraformer according to the OS you prefer. If you are using Windows, I suggest installing via Chocolatey.

Care should be taken that you have Terraform installed and added to the path variables (Windows).

Check for installation:

$ terraformer version
Terraformer v0.8.13

Terraformer Example

In this example, we will launch a simple EC2 instance in the AWS console and generate terraform files from the infrastructure. We give the Instance a “Name” tag with value “terraformer”.

Create an empty folder to store the generated files. Open cmd inside this folder, and enter the following command:

terraformer import aws –resources=ec2_instance –filter=”Name=tags.Name;Value=Terraformer” –regions=us-east-1

The above command highlights two important things, –resources parameter and the –filter parameter. The resources parameter indicates the name of the service that needs to be imported. We use –resources=”*”, and when using the “*” if there is a service that needs to be excluded, then –resources=”*” –excludes=”iam”.

With the –filter parameter, one can choose which resource Terraform imports. The filters work with resource identifiers or attributes and multiple filtering values are separated by ‘:’. If the resource identifier contains ‘:’, then it should be wrapped in “ ‘ ”. Identifier based filters will be executed before Terraformer will try to refresh the remote state.

Filtering also has a Type option; this helps in filtering several types of resources. Also, multiple filters can be combined when importing different resource types. For example:

terraformer import aws -r sg,vpc –filter Type=sg;Name=vpc_id;Value=VPC_ID –filter Type=vpc;Name=id;Value=VPC_ID

The sg Name is different for both the filtering options.

Furthermore, filtering is based on Terraform resource ID patterns. For valid ID patterns for your resources, refer Terraform documentation here. Example:

terraformer import aws –resources=vpc,subnet –filter=vpc=myvpcid –regions=us-east-1

After the brief introduction to the filtering and resources parameters, we will try to create a tf file from a simple EC2 infrastructure we created earlier with the Instance “Name” tag with value “terraformer”.

First, we go to the directory where we want all the files generated from Terraformer. Then, enter the below command:

terraformer import aws –resources=ec2_instance –filter=”Name=tags.Name;Value=terraformer” –regions=us-east-1

Upon entering the command chooses from the ec2 instance resource, filters the instance with tag terraformer from us-east-1 region.

The respective terraform files are generated in the directory where terraformer import is run. For me here, that directory is “terraformer_poc”. So, the files generated by terraformer will be inside generated/aws/ec2_instance. If terraformer import is done other resources, then the tf files are generated with their respective resource names as shown below:

We can see a new instance.tf file is created along with other files.

Reuploading The Terraformer File Created

Let us try uploading the instance.tf created by terraformer and see if we can directly create the exact same resource from the .tf file.

Below is the instance.tf file which was generated from terraformer:

resource "aws_instance" "tfer--i-002D-xxxxxxxxxxxxxxxxxxxx_terraformer" {
  ami                         = "ami-0e1d30f2c40c4c701"
  associate_public_ip_address = "true"
  availability_zone           = "us-east-1a"
  capacity_reservation_specification {
    capacity_reservation_preference = "open"
  }
  cpu_core_count       = "1"
  cpu_threads_per_core = "1"
  credit_specification {
    cpu_credits = "standard"
  }
  disable_api_termination = "false"
  ebs_optimized           = "false"
  enclave_options {
    enabled = "false"
  }
  get_password_data                    = "false"
  hibernation                          = "false"
  instance_initiated_shutdown_behavior = "stop"
  instance_type                        = "t2.micro"
  ipv6_address_count                   = "0"
  key_name                             = "xxxxxxxx"
  metadata_options {
    http_endpoint               = "enabled"
    http_put_response_hop_limit = "1"
    http_tokens                 = "optional"
    instance_metadata_tags      = "disabled"
  }
  monitoring = "false"
  private_ip = "10.10.x.xxx"
  root_block_device {
    delete_on_termination = "true"
    encrypted             = "false"
    tags = {
      Name = "aw2tfsqs"
    }
resource "aws_instance" "tfer--i-002D-xxxxxxxxxxxxxxxxxxxx_terraformer" {
  ami                         = "ami-0e1d30f2c40c4c701"
  associate_public_ip_address = "true"
  availability_zone           = "us-east-1a"
  capacity_reservation_specification {
    capacity_reservation_preference = "open"
  }
  cpu_core_count       = "1"
  cpu_threads_per_core = "1"
  credit_specification {
    cpu_credits = "standard"
  }
  disable_api_termination = "false"
  ebs_optimized           = "false"
  enclave_options {
    enabled = "false"
  }
  get_password_data                    = "false"
  hibernation                          = "false"
  instance_initiated_shutdown_behavior = "stop"
  instance_type                        = "t2.micro"
  ipv6_address_count                   = "0"
  key_name                             = "xxxxxxx"
  metadata_options {
    http_endpoint               = "enabled"
    http_put_response_hop_limit = "1"
    http_tokens                 = "optional"
    instance_metadata_tags      = "disabled"
  }
  monitoring = "false"
  private_ip = "10.10.x.xxx"
  root_block_device {
    delete_on_termination = "true"
    encrypted             = "false"
    tags = {
      Name = "aw2tfsqs"
    }
    volume_size = "8"
    volume_type = "gp2"
  }
  source_dest_check = "true"
  subnet_id         = "subnet-xxxxxxxxxxxxxxxxxxxx"
  tags = {
    Name = "terraformer"
  }
  tags_all = {
    Name = "terraformer"
  }
  tenancy                = "default"
  vpc_security_group_ids = ["sg-xxxxxxxxxxxxxxxxxxxx"]
}
    volume_size = "8"
    volume_type = "gp2"
  }
  source_dest_check = "true"
  subnet_id         = "subnet-xxxxxxxxxxxxxxxxxxxx"
  tags = {
    Name = "terraformer"
  }
  tags_all = {
    Name = "terraformer"
  }
  tenancy                = "default"
  vpc_security_group_ids = ["sg-xxxxxxxxxxxxxxxxxxxx"]
}

When you run “terraform plan” after initializing Terraform inside this directory (terraform init), there will an output saying that there are no changes in the infrastructure, this proves that there is a correct “replication” of the infrastructure to the instance.tf, as shown below:

Now, let’s delete the instance we created the Name tag “terraformer” and try to create infrastructure FROM code via the terraformer created instance.tf file.

After deleting, run “terraform plan” once again. This will detect changes and informs that there is a Plan: 1 to add, 0 to change, 0 to destroy. This indicates that there is a resource to be added.

Now run “terraform apply”. When the process is complete, it ends in an error as shown below:

So, this shows us that the instance.tf file generated by terraformer has to modify for reusability.

Conclusion

After going through a basic example of terraformer, i.e., creating a basic EC2 instance terraform file, it is evident that terraformer does indeed have the capacity to convert the infrastructure into code which is acknowledged by Terraform (“terraform plan”). However, going through a more complex architecture remains to be seen, which will be explored in further blogs based on this topic. Also, another advantage of using this CLI tool is that one can also look at some best practices about terraform file creation.