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.
- Creating Auto Scaling Group or Launch Template
- Create AMI Snapshot and Launch an instance from it.
- 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.
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
- aws region
- aws profile ( if you have named profile in your AWS CLI where you invoke terraform)
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 terraform
command 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
Signup for Exclusive "Subscriber-only" Content