AWS EBS Volumes using Terraform

Raghav D
9 min readNov 2, 2020

Terraform: Terraform is an open-source infrastructure as code software tool created by HashiCorp

AWS EBS Volumes: EBS Volumes are elastic block storage devices that you can attach to your Instance, These are scalable

Here we are Going to discuss below scenarios:

  1. Create EBS Volumes
  2. List out all EBS Volumes
  3. Attach existing EBS Volume to an EC2 Instance
  4. Create a EBS Volume and attach to an EC2 Instance

To implement above tasks I have create a IAM user called “terraformuser” in my AWS account, and configured with my CLI

  1. Create EBS Volumes using terraform:

We are creating EBS volume-type “gp-2”

provider "aws" {
region = "us-west-2"
profile = "terraformuser"
}
resource "aws_ebs_volume" "ebsvolume" {
availability_zone = "us-west-2a"
size = 10
encrypted = false
tags = {
name = "raghavendar"
}

}

provider will be aws

Region: where we want to create the EBS volumes

Profile: aws IAM user

resource: Here we are using aws_ebs_volume registry

encryption : We are not encrypting the volume so mentioned as false

tags: Giving a name to the volume

Now we will execute the terraform commads as mentioned below

terraform init

terraform plan -out raghavendar

output:

terraform plan -out raghavendar
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:# aws_ebs_volume.ebsvolume will be created
+ resource "aws_ebs_volume" "ebsvolume" {
+ arn = (known after apply)
+ availability_zone = "us-west-2a"
+ encrypted = false
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 10
+ snapshot_id = (known after apply)
+ tags = {
+ "name" = "raghavendar"
}
+ type = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.------------------------------------------------------------------------This plan was saved to: raghavendarTo perform exactly these actions, run the following command to apply:
terraform apply "raghavendar"

terraform apply “raghavendar”

output:

terraform apply "raghavendar"
aws_ebs_volume.ebsvolume: Creating...
aws_ebs_volume.ebsvolume: Still creating... [10s elapsed]
aws_ebs_volume.ebsvolume: Creation complete after 14s [id=vol-0e84b62885c40d78c]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.
State path: terraform.tfstate
10GB Volume created

Now we are creating other EBS volume with the 20GB

provider "aws" {
region = "us-west-2"
profile = "terraformuser"
}
resource "aws_ebs_volume" "ebsvolume" {
availability_zone = "us-west-2a"
size = 20
encrypted = false
tags = {
name = "raghavendar_new_Volume"
}

}

Note: before running terraform commands, take the backup of the terraform state file, and remove the terraform state file

terraform init

terraform plan -out raghavendar_20GB

output:

terraform plan -out raghavendar_20GB
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:# aws_ebs_volume.ebsvolume will be created
+ resource "aws_ebs_volume" "ebsvolume" {
+ arn = (known after apply)
+ availability_zone = "us-west-2a"
+ encrypted = false
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 20
+ snapshot_id = (known after apply)
+ tags = {
+ "name" = "raghavendar_new_Volume"
}
+ type = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.------------------------------------------------------------------------This plan was saved to: raghavendar_20GBTo perform exactly these actions, run the following command to apply:
terraform apply "raghavendar_20GB"

terraform apply “raghavendar_20GB”

output:

terraform apply "raghavendar_20GB"
aws_ebs_volume.ebsvolume: Creating...
aws_ebs_volume.ebsvolume: Still creating... [10s elapsed]
aws_ebs_volume.ebsvolume: Creation complete after 15s [id=vol-0e32e4534b355c092]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.
State path: terraform.tfstate
20GB Volume created

2. List out the EBS Volumes:

provider "aws" {
profile = "terraformuser"
region = "us-west-2"

}
data "aws_ebs_volumes" "ebsvolume" {

filter {
name = "volume-type"
values = [
"gp2"]
}
}

Here we are filtering the volumes with type “gp2”

run the terraform commands

terraform init, terraform plan

terraform apply

terraform show terraform.tfstate

output:

terraform show terraform.tfstate
# data.aws_ebs_volumes.ebsvolume:
data "aws_ebs_volumes" "ebsvolume" {
id = "terraform-20201102040520341300000001"
ids = [
"vol-02eab314a1a8c2855",
"vol-04a219b840d861675",
"vol-06d5a91abe294bcdf",
"vol-0e32e4534b355c092",
"vol-0e84b62885c40d78c",
]
filter {
name = "volume-type"
values = [
"gp2",
]
}
}

3. Attach existing EBS volume to EC2 Instance

I have EC2 Instance, which is already mounted one more EBS, now we are Mounting a new EBS Volume

provider "aws" {
profile = "terraformuser"
region = "us-west-2"
}


resource "aws_volume_attachment" "mountvolumetoec2" {
device_name = "/dev/sdb"
instance_id = "i-083aad7eac1faa3c5"
volume_id = "vol-0e32e4534b355c092"
}

Run the terraform commands

terraform init

terraform plan

output:

terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:# aws_volume_attachment.mountvolumetoec2 will be created
+ resource "aws_volume_attachment" "mountvolumetoec2" {
+ device_name = "/dev/sdb"
+ id = (known after apply)
+ instance_id = "i-083aad7eac1faa3c5"
+ volume_id = "vol-0e32e4534b355c092"
}
Plan: 1 to add, 0 to change, 0 to destroy.------------------------------------------------------------------------Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

terraform apply

terraform applyAn execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:# aws_volume_attachment.mountvolumetoec2 will be created
+ resource "aws_volume_attachment" "mountvolumetoec2" {
+ device_name = "/dev/sdb"
+ id = (known after apply)
+ instance_id = "i-083aad7eac1faa3c5"
+ volume_id = "vol-0e32e4534b355c092"
}
Plan: 1 to add, 0 to change, 0 to destroy.Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yesaws_volume_attachment.mountvolumetoec2: Creating...
aws_volume_attachment.mountvolumetoec2: Still creating... [10s elapsed]
aws_volume_attachment.mountvolumetoec2: Still creating... [20s elapsed]
aws_volume_attachment.mountvolumetoec2: Creation complete after 27s [id=vai-242313316]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Existing EBS Volume attached to EC2 Instance

We have attached EBS Volume successfully, log into the server and execute the mount commands

4. Create a EBS Volume and attach to an EC2 Instance:

Here we are going to create a new EBS volume and attaching it to EC2 Instance

provider "aws" {
profile = "terraformuser"
region = "us-west-2"
}
resource "aws_ebs_volume" "awsvolume" {
availability_zone = "us-west-2a"
size = 30
encrypted = "false"

tags = {
name = "new_volume_mounttoec2"
}
}
resource "aws_volume_attachment" "mountvolumetoec2" {
device_name = "/dev/sdd"
instance_id = "i-083aad7eac1faa3c5"
volume_id = "${aws_ebs_volume.awsvolume.id}"
}

In above code, we are creating a new volume of size 30GB, attaching it to a running instance

Run the terraform commands

terraform init

terraform paln -out newvolume

output:


terraform plan -out newvolume
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:# aws_ebs_volume.awsvolume will be created
+ resource "aws_ebs_volume" "awsvolume" {
+ arn = (known after apply)
+ availability_zone = "us-west-2a"
+ encrypted = false
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 30
+ snapshot_id = (known after apply)
+ tags = {
+ "name" = "new_volume_mounttoec2"
}
+ type = (known after apply)
}
# aws_volume_attachment.mountvolumetoec2 will be created
+ resource "aws_volume_attachment" "mountvolumetoec2" {
+ device_name = "/dev/sdd"
+ id = (known after apply)
+ instance_id = "i-083aad7eac1faa3c5"
+ volume_id = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.Warning: Interpolation-only expressions are deprecatedon ebsec2.tf line 17, in resource "aws_volume_attachment" "mountvolumetoec2":
17: volume_id = "${aws_ebs_volume.awsvolume.id}"
Terraform 0.11 and earlier required all non-constant expressions to be
provided via interpolation syntax, but this pattern is now deprecated. To
silence this warning, remove the "${ sequence from the start and the }"
sequence from the end of this expression, leaving just the inner expression.
Template interpolation syntax is still used to construct strings from
expressions when the template includes multiple interpolation sequences or a
mixture of literal strings and interpolations. This deprecation applies only
to templates that consist entirely of a single interpolation sequence.
------------------------------------------------------------------------This plan was saved to: newvolumeTo perform exactly these actions, run the following command to apply:
terraform apply "newvolume"

terraform show newvolume

output:

terraform show newvolumeAn execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:# aws_ebs_volume.awsvolume will be created
+ resource "aws_ebs_volume" "awsvolume" {
+ arn = (known after apply)
+ availability_zone = "us-west-2a"
+ encrypted = false
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 30
+ snapshot_id = (known after apply)
+ tags = {
+ "name" = "new_volume_mounttoec2"
}
+ type = (known after apply)
}
# aws_volume_attachment.mountvolumetoec2 will be created
+ resource "aws_volume_attachment" "mountvolumetoec2" {
+ device_name = "/dev/sdd"
+ id = (known after apply)
+ instance_id = "i-083aad7eac1faa3c5"
+ volume_id = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.

terraform apply “newvolume”

output:

terraform apply "newvolume"
aws_ebs_volume.awsvolume: Creating...
aws_ebs_volume.awsvolume: Still creating... [10s elapsed]
aws_ebs_volume.awsvolume: Creation complete after 15s [id=vol-0dd9f14e6156488eb]
aws_volume_attachment.mountvolumetoec2: Creating...
aws_volume_attachment.mountvolumetoec2: Still creating... [10s elapsed]
aws_volume_attachment.mountvolumetoec2: Still creating... [20s elapsed]
aws_volume_attachment.mountvolumetoec2: Creation complete after 28s [id=vai-3523762368]
Warning: Interpolation-only expressions are deprecatedon ebsec2.tf line 17, in resource "aws_volume_attachment" "mountvolumetoec2":
17: volume_id = "${aws_ebs_volume.awsvolume.id}"
Terraform 0.11 and earlier required all non-constant expressions to be
provided via interpolation syntax, but this pattern is now deprecated. To
silence this warning, remove the "${ sequence from the start and the }"
sequence from the end of this expression, leaving just the inner expression.
Template interpolation syntax is still used to construct strings from
expressions when the template includes multiple interpolation sequences or a
mixture of literal strings and interpolations. This deprecation applies only
to templates that consist entirely of a single interpolation sequence.
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.
State path: terraform.tfstate
New EBS Volume created and attached to EC2 Instance

References:

  1. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume
  2. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/volume_attachment
  3. https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ebs_volumes

--

--