Create EBS Snapshot Using Terraform


Slowly we are moving to some complex topic, Today we are going to see how we can Create EBS Volume Snapshot.
This topic is one of the important topic and most asked question in Interviews so I request you to get some basic knowledge of EBS volume and Snapshot.
In this Blog I won’t cover explaination for EBS Volume and Snapshot but if you want me to cover the topics as well please let me know I will try to explain the topics also.
But for today lets just move forward with the todays Task we have in our bucket.
As usual we will take the scenario first :
The Nautilus DevOps team has some volumes in different regions in their AWS account. They are going to setup some automated backups so that all important data can be backed up on regular basis. For now they shared some requirements to take a snapshot of one of the volumes they have.
Create a snapshot of an existing volume named nautilus-vol in us-east-1 region using terraform.
1) The name of the snapshot must be nautilus-vol-ss.
2) The description must be Nautilus Snapshot.
3) Make sure the snapshot status is completed.
We are going to create a Terraform configuration to snapshot an existing EBS volume.
Let’s first see the requirement we have
We need to specify the AWS provider for the us-east-1 region.
We need to get the existing volume by its name (nautilus-vol) to retrieve its ID.
We will create an AWS EBS snapshot resource with the required name and description.
We will ensure that the snapshot is completed by using a data source to wait for the snapshot to be completed
However, note that Terraform does not wait for the snapshot to be completed by default.
We can use a data source with a filter to wait until the snapshot is completed, but note that the snapshot creation is asynchronous.
Alternatively, we can use a null_resource with a local-exec provisioner to wait using AWS CLI, but we have to use Terraform.
Since we are required to make sure the snapshot status is completed we can do:
a. Create the snapshot resource.
b. Then, use a data source that depends on the snapshot resource and uses the snapshot id to wait until the state is 'completed'.
But note: the data source for snapshot might not wait by itself. We can use the aws_ebs_snapshot data source and use a depends_on to the snapshot resource, but then we must wait until it is completed.
Actually, there is a resource aws_ebs_snapshot and when we run terraform apply, it will create the snapshot and then move on. However, the snapshot creation is quick to start but takes time to complete. The resource itself in Terraform does not wait until the snapshot is completed (it only waits until the snapshot creation command is accepted).
So, we need to explicitly wait. We can use a null_resource that runs after the snapshot and uses a local-exec to wait for the snapshot to be completed.
But note: the volume might not have a tag? The problem says "existing volume named nautilus-vol".
So we assume that the volume has a tag "Name" with value "nautilus-vol".
Alternatively, we can use the volume ID if we know it? But we don't.
So we use the tag. However, the data source for ebs volume requires at least one filter. We will filter by the tag
So Now Let’s write the main.tf file configuration :
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "6.6.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
# Retrieve the volume ID of 'nautilus-vol' using its Name tag
data "aws_ebs_volume" "nautilus_vol" {
filter {
name = "tag:Name"
values = ["nautilus-vol"]
}
}
# Create the snapshot
resource "aws_ebs_snapshot" "nautilus_vol_ss" {
volume_id = data.aws_ebs_volume.nautilus_vol.id
description = "Nautilus Snapshot"
tags = {
Name = "nautilus-vol-ss"
}
}
# Wait for the snapshot to reach "completed" status
resource "null_resource" "wait_for_snapshot" {
triggers = {
snapshot_id = aws_ebs_snapshot.nautilus_vol_ss.id
}
provisioner "local-exec" {
command = "aws ec2 wait snapshot-completed --snapshot-ids ${aws_ebs_snapshot.nautilus_vol_ss.id} --region us-east-1"
}
depends_on = [aws_ebs_snapshot.nautilus_vol_ss]
}
Initialize Terraform:
terraform init
Apply the Configuration:
terraform plan
terraform apply
Before you use Terraform apply command always prefer using Terraform Plan command just in case you have any error its a best practice to use Plan command.
So this was it we have completed one more topic. Do let me know your suggestions if any.
Subscribe to my newsletter
Read articles from Kunal Kumar Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Kunal Kumar Singh
Kunal Kumar Singh
I am a DevOps Engineer working in MNC. Where I automate Infrastructure using various DevOps tools and AWS Cloud.