Clone EC2 instance using Terraform - How to | Devops Junction

This is a familiar requirement for everyone I believe.  How to clone an EC2 instance and create a new instance with the same configuration.

While we want to launch multiple EC2 instances of the same configuration there are multiple ways we follow.

  1. Creating Auto Scaling Group or Launch Template
  2. Create AMI Snapshot and Launch an instance from it.
  3. Create an EBS Volume Snapshot and attach it to a new instance etc

While the Autoscaling group and Launch template are to have a single copy and create multiple instances. The second and third ways are what we usually do.

So in this article, we are going to show you how to clone an EC2 instance by creating an AMI Snapshot and launching a new instance

When you create an AMI and launch a new instance except for the EBS Volume all other important configurations would be gone

  • VPC
  • Subnets
  • SecurityGroup
  • InstanceType

We are trying to solve that problem in this terraform manifest by retaining this information from the source instance

So we are basically going to create an Apple to Apple kind of a clone with the same instance type and security group and VPC including the same subnet.

If you are new to Terraform and trying to do your first integration or Infra as code setup.  Please refer to this Terraform AWS introduction article and come back.

clone ec2 instance

Terraform source code to clone EC2 instance

Here is the Terraform source code, which clones the AWS EC2 instance and creates a new one.

You can copy the following terraform files to your newly created directory(workspace) or simply git clone  from this repository

git clone https://github.com/AKSarav/terraform-ec2-clone.git

Here are the source code files

Starting with a file where we declare the necessary variables/inputs for our terraform manifest

In a workspace ( newly created directory) create a new file named vars.tf and copy the below file content

vars.tf

variable "source_instance_id" {
  default = "i-0bb**********b3ba"
}%

In this file, we are defining the source_instance_id  The EC2 instance ID, which we are going to clone and create a new EC2 instance

 

main.tf

Here is the main.tf file where we define the logic and provider configuration.

We are going to start with defining the required providers for our configuration. we need only the AWS provider and the version above 3.0

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

Next we need to define some additional info for the AWS provider such as

provider "aws" {
  region = "us-east-1"
  profile = "dev"
}

If no profile is given the default AWS CLI profile would be chosen by Terraform for authentication

Once we have established the connection to the AWS. let us get the source instance information. this would help us to retain the configurations like Subnet, VPC ID etc

That's what we are going to do with the following block

//Get aws instance details
data "aws_instance" "source_instance" {
  instance_id = var.source_instance_id
}

Saving the data we have collected using data block into output block

When you have more number of outputs, its ideally recommended to keep them isolated in a file named outputs.tf

Since ours is simple, I have put it on a single file

output "source_instance" {
  value       = "${data.aws_instance.source_instance}"
  description = "Source Instance Details"
}

Now, Once the data has been collected from the source instance.

We can use the collected information to create an AMI from the Source Ec2 instance using the following block

resource "aws_ami_from_instance" "sourceami" {
  name               = "source-instance"
  source_instance_id = var.source_instance_id
}

we are using the variable var.source_instance_id  we have declared earlier on the vars.tf file

Now, let us assume that the AMI is created ( Ideally terraform waits for the AMI to be created) using above block.

This aws_ami_from_instance block would return the AMI id once the creation is done, which we can use while creating the new EC2 instance

Now let us create a new EC2 instance using aws_instance block

resource "aws_instance" "newinstance" {
    ami           = aws_ami_from_instance.sourceami.id
    instance_type = data.aws_instance.source_instance.instance_type
    vpc_security_group_ids = data.aws_instance.source_instance.vpc_security_group_ids
    subnet_id = data.aws_instance.source_instance.subnet_id
    tags = {
        Name = "${data.aws_instance.source_instance.tags.Name}-cloned"
    }
}

If you look at this block. You can see we are defining the following parameters for the EC2 configuration

  • ami - created with aws_ami_from_instance on the previous block
  • instance_type - retain the same instance type using the collected data
  • vpc_security_group_ids - retain the same VPC security group from the data block
  • subnet_id - retain it from the data block of source instance
  • tags - we will try to copy the source instance name and add a word -cloned

Thats all.

Here is the full main.tf file

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
  profile = "prod"
}

//Get aws instance details
data "aws_instance" "source_instance" {
  instance_id = var.source_instance_id
}

output "source_instance" {
  value       = "${data.aws_instance.source_instance}"
  description = "Source Instance Details"
}

resource "aws_ami_from_instance" "sourceami" {
  name               = "source-instance"
  source_instance_id = var.source_instance_id
}

resource "aws_instance" "newinstance" {
    ami           = aws_ami_from_instance.sourceami.id
    instance_type = data.aws_instance.source_instance.instance_type
    vpc_security_group_ids = data.aws_instance.source_instance.vpc_security_group_ids
    subnet_id = data.aws_instance.source_instance.subnet_id
    tags = {
        Name = "${data.aws_instance.source_instance.tags.Name}-cloned"
    }
}

 

Execution and Validation

Once you have created the tf files. you can initialize the terraform by executing the following command

Note*: We presume you have terraformcommand installed already. otherwise refer our beginner article  and complete the pre-requisites and come back

terraform init

Once the initialization complete. you can do the planning and save the output .out file like this

terraform plan -out tfplan.out

It is always recommended to create an out file to make sure no unintended changes are accidentally applied

After validating the output of terraform plan. If you find it satisfactory, Now apply plan output  using the following command

terraform apply tfplan.out

If everything is done well.  Now sit back and relax for few minutes a new AMI would be created from the source instance which would be used to create a new EC2 instance

The new EC2 instance (clone EC2 instance) would have the same instance type , VPC ID and security group configuration.

 

Conclusion

In this article, we have learnt how to clone or copy EC2 instances using terraform and create a new EC2 instance.

We also have retained the VPC, Subnet, and Security group configuration of the source instance during the cloning.

Hope this helps you.

If you have any questions or suggestions to make this even better. Please do let us know in the comments section.

For any DevOps/Cloud requirements for you or your company. Please reach out to our professional support team at [email protected]

 

Cheers
Sarav AK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading