Launch AWS instance and attach volume using AWS CLI & script
By: Adarsh Saxena
Tags: AWS, Automation, Aws Cli, Cloud, Scripting

For getting the instance-id, you can create a command for getting the instance id using the query and filters. Though you can also use the simple command, but that won’t help us in automation, that we’ll do in the latter part of this article.

aws ec2 attach-volume --device /dev/xvdb --instance-id i-0159851f2556c1a04 --volume-id vol-0536d4b73a5937242

Part II — Automating the things using scripting

Tip: To read the full code at once, go to the end of the article

For automating the above things, means for creating those resources with a faster pace and no manual involvement, you just need to do a few more things.

First thing, you need to notice that the above commands that we have discussed above are for the Windows Command or PowerShell, and if you try to run those commands in Linux, some of those will give some error. For automating, we are going to write the bash script, and for that, you need a bash shell, which you can get either from any Linux Distro or even Git Bash.

So, Let’s start the scripting part

The first thing, you need to do is to declare the variables for the tags or the name of resources.

#!/bin/bash #Declaring Variables keyname=testingclikey

instancename=testinginstance

sgname=testingsg

ebsname=testingebs

Now, let’s say you want to create the key-pair from the bash. But, here, you need to note that if you are going to give tag to the key-pair, as we have done in the command at the start, it will give an error. This is because we have used the curly braces in that command, {}, which are intended for other things in Bash. So, to tackle this error, you can use double quote “” as done in command below:

#creating the key pair aws ec2 create-key-pair --key-name $keyname --tag-specification "ResourceType=key-pair,Tags=[{Key=Name,Value=$keyname}]" --query "KeyMaterial" --output text > $keyname.pem

Similarly, you can create the security group:

#Creating the security group aws ec2 create-security-group --group-name $sgname --description "created from CLI" --vpc-id vpc-50f0e456

Now, the heart of Scripting

Till now, everything was really fine, but when you are going to create the inbound rule for the security group, you need to retrieve the group-id of the security group that you have created and then pass that group-id to another command.

So, for getting the security group info, we can use the aws ec2 describe-security-groups command. But that will show you the info about all the SGs and in json format. So, we need to format that output, then, pass to other commands. For that you can use the following command:

aws ec2 describe-security-groups --query "SecurityGroups[].GroupId" --filters Name=group-name,Values=$sgname

If you have noticed, that the above command is in windows and the output is not what we require, so, now switch to Linux, and let’s do some change in the output.

Now, the output is in the shape of what we require, so, instead of printing that in Console, let’s store that in variable sgid. Here, for formatting the output we are using the sed and tr. See command below:

sgid=`aws ec2 describe-security-groups --query "SecurityGroups[].GroupId" --filters "Name=group-name,Values=$sgname" | sed -n 2p | tr -d \"`

Now, we have the security group id stored in sgid variable. So, let’s use this and create inbound rules.

#Adding the inbound rules to the security group created aws ec2 authorize-security-group-ingress --group-id $sgid --protocol tcp --port 22 --cidr 0.0.0.0/0

For launching the instance, the command is the same as discussed previously except that we are now using the variables inside the command:

#Launching the instance aws ec2 run-instances --image-id ami-0e306788ff2473ccb --count 1 --instance-type t2.micro --key-name $keyname --security-group-ids $sgid --tag-specification "ResourceType=instance,Tags=[{Key=Name,Value=$instancename}]"

For Creating the volume, not much difference except using double quotes and variable in place of the name of the volume.

#Creating the Volume

aws ec2 create-volume --availability-zone ap-south-1a --size 1 --tag-specification "ResourceType=volume,Tags=[{Key=Name,Value=$ebsname}]"

Now, for attaching the instance volume, you need the volume id and the instance id and then, pass the values to another command. To achieve, we have used the following commands:

#storing the value of Volume ID in variable volumeID

volumeID=`aws ec2 describe-volumes --query "Volumes[*].VolumeId" --filters "Name=tag:Name,Values=$ebsname" | sed -n 2p | tr -d \"` #Storing the value of instance ID in the Variable instanceid

instanceID=`aws ec2 describe-instances --query "Reservations[*].Instances[].InstanceId" --filter "Name=key-name,Values=$keyname" | sed -n 2p | tr -d \"` #Attaching the volume to the instance

aws ec2 attach-volume --device /dev/xvdb --instance-id $instanceID --volume-id $volumeID

So, Let’s sum up everything into one script file:

GitHub Repo: https://github.com/theadarshsaxena/AWS-CLI-Scripting/