AWS Certification: Amazon Elastic Compute Cloud (EC2)

AWS certification EC2

On this post we will continue with the preparation for the AWS CERTIFIED SOLUTIONS ARCHITECT EXAM. Remember the exercises we are solving here are from AWS Certified Solutions Architect Official Study Guide: Associate Exam by Joe Baron and others.

We have already cover the S3 exercises on the previous entry so now we will go through the EC2 exercises, which is arguably one of the most used features in AWS.
For the purpose of this post the IP address of the machine we will use to connect to the instances will be 200.1.2.3. Change this for your own IP address to allow connectivity to the instances from your IP address only.

EXERCISE 3.1


Launch and Connect to a Linux Instance
Launch an instance in the Amazon EC2 console.

We will use an Ubuntu AMI with an id of ami-09f4cd7c0b533b081, the instance type will be t2.micro which is eligible for free tier and we will need to use an already created SSH key pair (called AWSKey) to connect to the device.
To describe the SSH key pairs available run:

user@australtech.net:~$ aws ec2 describe-key-pairs

Use the value from KeyName for the –key-name switch and let’s create the instance:

user@australtech.net:~$ aws ec2 run-instances --image-id ami-09f4cd7c0b533b081 --instance-type t2.micro --key-name AWSKey 

That is all, with that command only you can create an instance.

Add a tag to the instance of Key: Name, Value: Exercise 3.1 .

aws ec2 create-tags --resources i-05750dc6c5c12a75b --tags Key=Name,Value='Exercise 3.1'

We will try to connect to it using SSH. We can get the public DNS name running this command:

aws ec2 describe-instances | grep PublicDnsName

And then we connect using SSH and the SSH key pair associated

ssh -i "AWSKey.pem" ubuntu@ec2-54-94-187-226.sa-east-1.compute.amazonaws.com

So, if you connection failed, don’t worry that is expected. By default AWS doesn’t allow inbound connectivity to the instances. In order to allow SSH connectivity (port tcp/22) we need to create a security group and assign it to the instance as shown next.

Create a new security group called Cert Book

aws ec2 create-security-group --group-name CertBook --description "Cert Book"

The id for the new created Group is sg-07803a04e87e1e0ae”

Add a rule to Cert Book allowing SSH access from the IP address of your workstation ( www.WhatsMyIP.org is a good way to determine your IP address)

aws ec2 authorize-security-group-ingress --group-id sg-07803a04e87e1e0ae --protocol tcp --port 22 --cidr 200.1.2.3/32

Now we will assign this security group to the running instance:

aws ec2 modify-instance-attribute --instance-id i-05750dc6c5c12a75b --groups sg-07803a04e87e1e0ae

Try to connect to the instance using SSH.

ssh -i "AWSKey.pem" ubuntu@ec2-54-94-187-226.sa-east-1.compute.amazonaws.com

Now, you should be able to see the usual linux prompt, if so, congratulations you have ssh’d into the instance!. From the command-line prompt, ‘run sudo apt-get update -y’

ubuntu@ip-172-31-11-32:~$ sudo apt-get update -y

Close the SSH session and terminate the instance.

ubuntu@ip-172-31-11-32:~$ exit
user@australtech.net:~$ aws ec2 terminate-instances --instance-id i-05750dc6c5c12a75b

EXERCISE 3.2


In this exercise, you will launch a Windows instance and specify a very simple bootstrap script. You will then confirm that the bootstrap script was executed on the instance.

Lets create the file for bootstrapping (Please note the spaces added for bypassing the XSS protection)


user@australtech.net:~$echo "< script > md c:\temp < /script >">bootstrap.txt

Windows AMI is: ami-0c0351c081dacd557. So we create the instance:

user@australtech.net:~$aws ec2 run-instances --image-id ami-0c0351c081dacd557 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae --user-data file://bootstrap.txt

Take note of the instance id, in this case it was i-038d8d407b613481b

Now, we will assign a tag.

user@australtech.net:~$aws ec2 create-tags --resources i-038d8d407b613481b --tags Key=Name,Value='Exercise 3.2'

Now we modify the security group so we can connect on port 3389 (RDP)

user@australtech.net:~$aws ec2 authorize-security-group-ingress --group-id sg-07803a04e87e1e0ae --protocol tcp --port 3389 --cidr 200.1.2.3/32

Get Encrypted password for Administrator User

user@australtech.net:~$aws ec2 get-password-data --instance-id i-038d8d407b613481b --priv-launch-key AWSKey.pem

With the Password decrypted and your favourite RDP client you should be able to connect now to the instance using the public DNS name that can be gathered running the command:

user@australtech.net:~$aws ec2 describe-instances | grep PublicDnsName

EXERCISE 3.4


Launch a Spot Instance

Launching a Spot instance requires a JSON file that you need to pass on to AWS CLI, you can use the template below or create the JSON file using the AWS Management Console on the Spot Request section.
The JSON file will have the following format:

{
"SpotPrice": "0.095",
"LaunchSpecification": {
"ImageId": "ami-03c6239555bb12112",
"InstanceType": "m3.medium",
"KeyName": "AWSKey",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"DeleteOnTermination": true,
"VolumeType": "gp2",
"VolumeSize": 8,
"SnapshotId": "snap-050ee94f4d096a59d"
}
}
]
},
"InstanceCount": 1,
"BlockDurationMinutes": 60
}

Note the $0.095 value which is the max we will pay per hour for running the instance. If you actually want to create the request for testing but without actually incurring any cost, change for a really low value like 0.0001

For creating the spot request instance then you run:

user@australtech.net:~$aws ec2 request-spot-instances --cli-input-json file://config.json

Remember to remove the spot request to avoid incurring charges.

EXERCISE 3.5

Access Metadata

In this exercise, you will access the instance metadata from the OS. We create a linux instance first and assign the already existing security group:

user@australtech.net:~$aws ec2 run-instances --image-id ami-09f4cd7c0b533b081 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae
user@australtech.net:~$aws ec2 describe-instances | grep PublicDnsName

“PublicDnsName”: “ec2-54-233-138-195.sa-east-1.compute.amazonaws.com”

We connect using SSH:

user@australtech.net:~$ssh -i AWSKey.pem ubuntu@ec2-54-233-138-195.sa-east-1.compute.amazonaws.com

Metadata for Amazon EC2 Instances can be accessed from the instance itself from a web server on the link-local address 169.254.169.254. In order to do this, at the Linux command prompt, retrieve a list of the available metadata by typing:

curl http://169.254.169.254/latest/meta-data/

To see a value, add the name to the end of the URL. For example, to see the security groups, type:


curl http://169.254.169.254/latest/meta-data/security-groups

To see information about the interfaces, like their MAC address type:

curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/

Close the SSH window and terminate the instance

aws ec2 terminate-instances --instance-ids i-0b358d1665c67f149

Create an Amazon EBS Volume and Show That It Remains After the Instance Is Terminated

Let’s create a 8 GB volume

user@australtech.net:~$aws ec2 create-volume --size 5 --volume-type gp2 --availability-zone sa-east-1a

The volume id is vol-001f0aec1945f57b3

You can list the volumes with the command:

aws ec2 describe-volumes

Now create an instance to attach the volume to:

user@australtech.net:~$aws ec2 run-instances --image-id ami-09f4cd7c0b533b081 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae 

Instance id is i-0b38b0d51d688ac90

user@australtech.net:~$aws ec2 attach-volume --volume-id vol-001f0aec1945f57b3 --instance-id i-0b38b0d51d688ac90 --device /dev/sdj

We can connect now to the instance using SSH and check if the volumes has been mounted:

ubuntu@ip-172-31-0-95:~$ sudo fdisk -l
…..
Disk /dev/xvdj: 5 GiB, 5368709120 bytes, 10485760 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

You can see /dev/sdj has been mapped to /dev/xvdj within the device. That is the way AWS map block devices even we specified /dev/sdj.

We will format this partition running ‘sudo fdisk /dev/xvdj’ and selecting option n for creating a new partition. Now if we run fdisk -l again we see the Volume looks like this:

Disk /dev/xvdj: 5 GiB, 5368709120 bytes, 10485760 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x50abe329
Device     Boot Start      End  Sectors Size Id Type
/dev/xvdj1 2048 10485759 10483712 5G 83 Linux

We will format it with ext4 and then mount it:

sudo mkfs.ext4 /dev/xvdj1
ubuntu@ip-172-31-0-95:~$ sudo mkdir /mnt/volume1
sudo mount /dev/xvdj1 /mnt/volume1

We check if it has been mounted successfully and that we can create a test file:

ubuntu@ip-172-31-0-95:~$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 481M 0 481M 0% /dev
tmpfs 99M 744K 98M 1% /run
/dev/xvda1 7.7G 1.1G 6.7G 14% /
tmpfs 492M 0 492M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 492M 0 492M 0% /sys/fs/cgroup
/dev/loop0 91M 91M 0 100% /snap/core/6350
/dev/loop1 18M 18M 0 100% /snap/amazon-ssm-agent/930
tmpfs 99M 0 99M 0% /run/user/1000
/dev/xvdj1 4.9G 20M 4.6G 1% /mnt/volume1
ubuntu@ip-172-31-0-95:/mnt/volume1$ sudo touch testfile
ubuntu@ip-172-31-0-95:/mnt/volume1$ ls -la
total 24
drwxr-xr-x 3 root root 4096 Mar 19 20:18 .
drwxr-xr-x 3 root root 4096 Mar 19 20:14 ..
drwx------ 2 root root 16384 Mar 19 20:13 lost+found
-rw-r--r-- 1 root root 0 Mar 19 20:18 testfile
ubuntu@ip-172-31-0-95:/mnt/volume1$

We unmount now:

ubuntu@ip-172-31-0-95:/mnt/volume1$ cd ..
ubuntu@ip-172-31-0-95:/mnt$ sudo umount volume1

Now we will kill the instance and we will create another instance to probe the data remains in the EBS volume:


user@australtech.net:~$aws ec2 terminate-instances --instance-ids i-0b38b0d51d688ac90

Lets create another instance and attach the same EBS volume:

user@australtech.net:~$aws ec2 run-instances --image-id ami-09f4cd7c0b533b081 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae 

Instance id is i-0ab0d9319cfd9d6e9

user@australtech.net:~$aws ec2 attach-volume --volume-id vol-001f0aec1945f57b3 --instance-id i-0ab0d9319cfd9d6e9 --device /dev/sdj

Connect to the instance using SSH as usual and check for the partition:

ubuntu@ip-172-31-0-31:~$ sudo fdisk -l

…..

Disk /dev/xvdj: 5 GiB, 5368709120 bytes, 10485760 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x50abe329
Device     Boot Start      End  Sectors Size Id Type
/dev/xvdj1 2048 10485759 10483712 5G 83 Linux

Now mount it and check if file we created previously is there:


ubuntu@ip-172-31-0-31:~$ sudo mkdir /mnt/volume1
ubuntu@ip-172-31-0-31:~$ sudo mount /dev/xvdj1 /mnt/volume1
ubuntu@ip-172-31-0-31:~$ ls -la /mnt/volume1
total 24
drwxr-xr-x 3 root root 4096 Mar 19 20:18 .
drwxr-xr-x 3 root root 4096 Mar 19 20:23 ..
drwx------ 2 root root 16384 Mar 19 20:13 lost+found
-rw-r--r-- 1 root root 0 Mar 19 20:18 testfile

Sucess! we can see testfile is in the volume.

EXERCISE 3.7

Take a Snapshot and Restore

Volume id is vol-001f0aec1945f57b3

aws ec2 create-snapshot --volume-id vol-001f0aec1945f57b3 --description 'Exercise 3.7'

Create a new Volume based on this snapshot:

aws ec2 create-volume --snapshot-id snap-02586a56cd04e9d4f --availability-zone sa-east-1a

Create a bigger volume (7Gb) based on the snapshot:

aws ec2 create-volume --snapshot-id snap-02586a56cd04e9d4f --availability-zone sa-east-1a --size 7

Copy the snapshot to another region

aws --region us-east-1 ec2 copy-snapshot --source-region sa-east-1 --source-snapshot-id snap-02586a56cd04e9d4f --description "This is my copied snapshot."

Create a volume from the snapshot in the new region

aws ec2 create-volume --snapshot-id snap-0058b2cf36ec5ab77 --availability-zone us-east-1a --region us-east-1

EXERCISE 3.8


Launch an Encrypted Volume (Linux version)

aws ec2 run-instances --image-id ami-09f4cd7c0b533b081 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae 

Instance id is i-035d620d18cba6445

aws ec2 create-volume --size 2 --volume-type gp2 --availability-zone sa-east-1a --encrypted

volume id is vol-0c589ca2399ad0cb8

aws ec2 attach-volume --volume-id vol-0c589ca2399ad0cb8 --instance-id i-035d620d18cba6445 --device /dev/sdj 

EXERCISE 3.9


Detach a Boot Drive and Reattach to Another Instance

Launch two Windows instances:


aws ec2 run-instances --image-id ami-0c0351c081dacd557 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae
aws ec2 modify-instance-attribute --instance-id i-0c2f2abf69247da1d --groups sg-07803a04e87e1e0ae
aws ec2 run-instances --image-id ami-0c0351c081dacd557 --instance-type t2.micro --key-name AWSKey --security-group-ids sg-07803a04e87e1e0ae 
aws ec2 modify-instance-attribute --instance-id i-0ae1c5a1bcaa56480 --groups sg-07803a04e87e1e0ae

Once both instances are running, stop the first instance (Source)


aws ec2 stop-instances --instance-id i-0c2f2abf69247da1d

Find the volume attached to the Source instance via the instance ID.


aws ec2 describe-volumes | grep i-0c2f2abf69247da1d -A1 -B1
"AttachTime": "2019-03-19T21:24:26.000Z",
"InstanceId": "i-0c2f2abf69247da1d",
"VolumeId": "vol-02f85c279513eaaf2",
Detach the instance
aws ec2 detach-volume --volume-id vol-02f85c279513eaaf2

When the volume becomes Available, attach the instance to the second instance (Destination)

aws ec2 attach-volume --volume-id vol-02f85c279513eaaf2 --instance-id i-0ae1c5a1bcaa56480 --device xvdh

Log in to the Destination instance via RDP using the administrator account.
Open a command window ( cmd.exe )
At the command prompt, type the following commands:


C:\Users\Administrator >diskpart
DISKPART>select disk 1
DISKPART>online disk
DISKPART>exit
C:\Users\Administrator>dir e:


The volume removed from the stopped source drive can now be read as the E: drive on the destination instance, so its data can be retrieved

This is all for this chapter. I think this chapter is one of the most important from the certification, so make sure you understand what your are doing. Don’t just copy and paste!. On the next post we will go through the exercises for Amazon VPC.