The top level designator for AWS is the region. Each region implements its own namespace. Thus names of cloud objects in one region are not valid in the others. Alternatively, objects that are replicated among regions (e.g. images) have different names.
The current set of regions are:
Perhaps the most straight forward way to access AWS, however, is through the CLI. AWS consists of many simple primitives rather than a few complex ones. This design choice promotes both performance and robustness in a distributed setting since the coordinated functionality of each primitive is minimized. It makes using AWS tedious, at times, however because many different primitives may be necessary to accomplish a single task. Put another way, the AWS API is designed for scalability more than it is designed for convenience and/or ease-of-use.
The CLI can be accessed, essentially, in two ways that are (more or less) differentiated by the way in which AWS security credentials are checked. Amazon makes available CLI tools that are written in Java and use SOAP. These tools use X.509 certificates to authenticate each request. AWS also supports a number of SDKs (for different languages) that use a secret key to sign REST requests. Euca2ools is a set of wrappers around the Boto SDK for Python that mimics the AWS CLI commands. I'll use euca2ools in what follows but the syntax should be the same for Amazon's ec2 tools.
euca2ools requires access to your AWS credentials which are
WARNING: You must protect your credentials. If they are stolen or made visible, they provide access to your AWS account.
Here is a sample set of exports for bash that set some of the relevant environment variable. You can source this file in bash and that shell will be able to run euca2ools against AWS.
export REGION=us-west-2 EUCA_KEY_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd -P) export EC2_URL=http://ec2.$REGION.amazonaws.com export S3_URL=http://s3.amazonaws.com export TOKEN_URL=http://storagegateway.$REGION.amazonaws.com export AWS_AUTO_SCALING_URL=http://autoscaling.$REGION.amazonaws.com export AWS_CLOUDWATCH_URL=http://monitoring.$REGION.amazonaws.com export AWS_ELB_URL=http://elasticloadbalancing.$REGION.amazonaws.com export EC2_PRIVATE_KEY=${EUCA_KEY_DIR}/XXXXXXXX.pem.txt export EC2_CERT=${EUCA_KEY_DIR}/YYYYYYYY.pem.txt export EC2_ACCOUNT_NUMBER='NNNNNNNN' export EC2_ACCESS_KEY='PPPPPPPP' export EC2_SECRET_KEY='SSSSSSSS' export AWS_ACCESS_KEY='PPPPPPPP' export AWS_SECRET_KEY='SSSSSSSS' export AWS_CREDENTIAL_FILE=${EUCA_KEY_DIR}/iamrc export EC2_USER_ID='UUUUUUUU'You'll need to fill in the strings that are repeated capital letters with the various keys and key files, and cert files, user ID and account number for your account. This information can be obtained from the AWS Management console.
Typically, the functionality that is associated with the virtual machine (VM) is defined by the image. For Linux, the image contains a single root file system which usually holds a specific version of a specific distribution (e.g. CentOS 6.4.1, Ubuntu 12.04, etc.) The kernel and ramdisk that are loaded with the image into the instance must be compatible with the image, and the boot record is one that the hypervisor must understand. Amazon installs the kernels, ramdisks, and boot records for the images it makes available publicly. It is also possible for users to upload their own images, and (using a paravirtualized boot loader) their own kernels and ramdisks.
To see what images are available on AWS, set the REGION variable in the file shown above (I'm using us-west-2 in this example) and type
euca-describe-images -aIt will take a while but you'll get back a lengthy listing of the images that are installed and publicly available. Now try
euca-describe-images -a | grep ami-f33fa9c3You should see something that looks like
IMAGE ami-f33fa9c3 ubuntu-us-west-2/images/ubuntu-precise-12.04-amd64-server-20130516.manifest.xml 099720109477 available public x86_64 machine aki-fc37bacc instance-store paravirtual xenFrom the name, this image (identified by its AMI ID ami-f33fa9c3) is an Ubuntu 12.04 image compiled for 64 bit. Notice that it specifies a kernel ID: aki-fc37bacc. Checking the image catalog with
euca-describe-images -a | grep aki-fc37bacc | grep -v ami-the kernel is a custom kernel (contained in the image's /boot directory) that is accessed vi PV_GRUB.
IMAGE aki-fc37bacc ec2-public-images-us-west-2/pv-grub-hd0_1.03-x86_64.gz.manifest.xml amazon available public x86_64 kernel instance-store paravirtual xen
To get the instance running, you first need to ask AWS to create an ssh keypair, the public end of which it will inject for you into the instance should you so choose. The command to create a key pair is
euca-create-keypair -f keyfile keynameWhere keyfile is the name of a file you want to use to hold the private key and keyname is the name of the key pair. AWS associated the name "keyname" with the public key so that you can refer to it in the launch command as a way of instructing it to inject the public key into the instance. For example, the command
euca-create-keypair -f testkey testkeycreates the keypair called "testkey" in AWS and writes the private key into the file testkey in the local directory.
To launch an instance, you must specify (at a minimum) the ami ID and the key name. In addition, you should specify the instance type (there is a default but it may be more expensive than you'd like).
euca-run-instances ami-f33fa9c3 -k testkey -t m1.smallLaunches the Ubuntu image described previously with the testkey keypair as an m1.small instance. When the instance boots, your account will be charged $0.10$ for each hour (or fraction of an hour) it uses.
It takes some time to start an instance. Before the instance is ready, it will show up as having a status of "pending"
INSTANCE i-75ade57d ami-f33fa9c3 ip-172-31-1-172.us-west-2.compute.internal pending testkey 0 m1.small 2014-04-23T20:11:35.000Z us-west-2c aki-fc37bacc monitoring-disabled 172.31.1.172 vpc-94ad41f1 subnet-d5467793 instance-store paravirtual xen sg-b07fb3d5 default falseTo check its status you must poll the system:
euca-describe-instancesand wait for the status to become running. When it shows as running the instance is booted and the ssh key has been inserted so that you can log in.
Also notice that the instance has been give an instance ID that begins "i-": i-75ade57d. You'll need this ID to reference the instance in other commands. It is always available from describe instances.
However you first need to open the ssh port in the firewall. In this example, because I didn't specify otherwise, AWS chose the default security group for the instance. Each security group corresponds to a separate, isolated private network with its own firewall and NAT. It is possible to create different security groups (and to give them names) with the euca-create-group command. If you don't specify a name to the run instance command, however, it will choose the security group with the name "default."
To open the ssh port in the default security group, run
euca-authorize default -P tcp -p 22 -s 0.0.0.0/0At this point you should be able to ssh into the instance using the private key returned by AWS when you created the keypair.
ssh -i ./testkey ubuntu@ec2-54-187-86-32.us-west-2.compute.amazonaws.comNotice in the display from describe instances show above that the instance has both an external DNS name (ec2-54-187-86-32.us-west-2.compute.amazonaws.com) and an internal DNA name (ip-172-31-1-172.us-west-2.compute.internal). Only the external one is accessible from outside the firewall (it is NATted to the internal address and name). Also notice that I had to log in as the user "ubuntu." The key insertion mechanism for this image enables the user ubuntu rather than the user "root" by default. The ubuntu user is sudo enabled, however, so you have root access to this instance.
To terminate the instance (thereby causing AWS to cease charging you) run
euca-terminate-instances "i-75ade57d"You may need the quotes to avoid the shell parsing the "-" in the ID.
Instances are different in that they are temporary running versions of images (at least, they were in their first incarnation -- see below). The designers of AWS believed
This property (which is actually quite a useful property when operating at scale) is the biggest source of confusion for most cloud users, especially those familiar with VMs and virtualization. When an "regular" instance is terminated, everything in the instance is deleted permanently. It feel strange because when he instance boots, there is a root file system that is readable and writable and also "ephemeral" disks that are empty but formatted as file systems that appear ready for use. Anything written to the root file system or the other ephemeral partitions while the instance is running is simply lost.
For example, logging into an Ubuntu 12.04 instance run as an m1.small instance type, a df shows
ubuntu@ip-172-31-7-74:~$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/xvda1 10321208 796228 9000704 9% / udev 838184 12 838172 1% /dev tmpfs 338516 168 338348 1% /run none 5120 0 5120 0% /run/lock none 846284 0 846284 0% /run/shm /dev/xvda2 153899044 192068 145889352 1% /mntThe instance type claims that, for an m1.small, the instance gets 1 disk of 160 GB. The Ubuntu distribution is on the 10 GB root file system and the 153 GB partition mounted on /mnt is formatted as an ext4 file system. Any file written to the root file system or the file system mounted on /mnt will be lost when the VM terminates.
It is still possible to use S3 as an explicit storage facility for instance persistent data, but Amazon now includes a persistent storage volume facility called the Elastic Block Store (EBS).
EBS volumes are essentially persistent disk partitions that can be created and destroyed dynamically under user control. Because they are logically not part of the instance, they must be attached to an instance before they are used and detached when they are no longer needed. terminating an instance automatically forces a detach.
To create a volume, you must specify the volume size (in GB) and an availability zone for the volume. EBS volumes can only be attached to instances running in the same availability zone.
Returning to the example, I started another instance let Amazon choose an availability zone for my instance start. It chose us-west-2c.
INSTANCE i-c4c68ecc ami-f33fa9c3 ec2-54-187-111-144.us-west-2.compute.amazonaws.com ip-172-31-7-74.us-west-2.compute.internal running testkey 0 m1.small 2014-04-23T23:00:42.000Z us-west-2c aki-fc37bacc monitoring-disabled 54.187.111.144 172.31.7.74 vpc-94ad41f1 subnet-d5467793 instance-store paravirtual xen sg-b07fb3d5 default falseTo create a 10 GB volume that this instance can access, then
euca-create-volume -s 10 -z us-west-2cThe return message has the status of the volume as creating. Before the volume can be attached its status must go to available.
euca-describe-volumespolls the status.
VOLUME vol-7443fb78 10 us-west-2c available 2014-04-23T23:13:41.660Z standardNow it is possible (using the instance ID) to attach the volume. You need to specify the device name in the instance to use (/dev/xvdb in this example -- note that in the df AWS has used xvda for its root and ephemeral).
euca-attach-volume -i i-c4c68ecc -d /dev/xvdb vol-7443fb78Now poll again to wait until the attachment completes
VOLUME vol-7443fb78 10 us-west-2c in-use 2014-04-23T23:13:41.660Z standard ATTACHMENT vol-7443fb78 i-c4c68ecc /dev/xvdb attached 2014-04-24T00:10:13.000ZAt this point it is possible to log into the instance, mount the volume (it will appear in the instance as /dev/xvdb) and to format it as a file system. Once formatted (you only need to do this the first time after the volume has been created) the volume can be mounted as if it were a formatted disk partition.
Before terminating, it is best to unmount the volume. Linux will try and flush the buffer cache and do an unmount as part of the terminate but there is no guarantee that the flush will be complete before the detach forced by AWS takes place. Detaching a mounted volume can cause data corruption so you should unmount before detaching and/or terminating to be safe.
Having done that, however, data in that volume will persist past the termination of a an instance. If you were to write some data into the volume, unmount it, detach it, and terminate the instance. Then start another instance (it can even be from a different image as long as it recognizes the file system you put on the volume when you formatted it) attach the volume and mount it and the data will still be there. The EBS volume behaves like a portable disk that you can "plug" into an instance once it is running.
Note that each EBS volume can be plugged into at most one instance at a time. It is not a file sharing protocol (which is another point of some confusion).
Why?
Returning to the figure, the volume itself is housed in some storage facility within AWS (it is not part of the instance). To access it, disk block requests are encapsulated in network packets and sent across a network link to the network-attached device that is serving the volume. Amazon does not say much about how EBS is implemented. For example, it is not clear whether the EBS block traffic goes over the same network interface that the instance traffic uses. It also isn't clear whether the packet format is IP. Logically, though, the architecture is analogous to using iSCSI to encapsulate disk block traffic in IP packets.
Thus, the protocol is between a single disk block device and a storage device -- EBS is not a file system. In the same way that two machines cannot have the same disk plugged into them, two instance cannot both attach an EBS volume.
However, it is possible to format an EBS volume as a file system and then to use a network file system (within the instances) to share it. One common set up that is used to share an EBS volume is to mount it in an instance and then have the file system exported as a NFS share to other instances.
The advantage of an EBS-backed instance is that the root file system can be made to persist across instance terminate, but in kind of a funny way. First, for EBS-backed instances it is possible to issue a STOP command. Stopping such an instance also stops AWS's charging for it but it does tell AWS to reclaim the root file system space. Thus, creating an EBS-backed instance and then stopping it, is like terminating but without the loss of the contents. To get it back, you issue a START command.
If you terminate an EBS-backed volume, the default action is to delete the root volume. You can override this behavior. If you do, the volume will be detached but it will remain available (and you will be charged for its storage). You can mount the volume in another instance (like any other volume) but you can't restart an instance from it directly.
Instead, to restart from a volume that has persisted past the termination of an instance, you need to take a snapshot of it and register the snapshot as a new image. In effect the snapshot-register operations reconstitute the root file system with the exact contents it has when the instance detached it.
euca-create-group cs290b -d rich-test-groupNote that the "-d" flag which allows you to add a description of what the group is for is not optional. AWS will assign an internal name to the security group that begins "sg-" but you can use the name you've given the group instead to launch an instance. So a describe groups
euca-describe-groups cs290btakes your name and returns
GROUP sg-f64f9a93 932234911131 cs290b rich-test-group vpc-94ad41f1 PERMISSION 932234911131 cs290b ALLOWS -1 TO CIDR 0.0.0.0/0 egressEach security group is logically a firewall behind which the instances that are in the group are placed in terms of networking. Thus launching an instance in this group:
euca-run-instances ami-f33fa9c3 -k testkey -t m1.small -g cs290bwith the "-g" option tells AWS that an instance should be started and the firewall rules for the instance should be those associated with the security group "cs290b."
In the default configuration (without the use of the AWS VPC facility) each instance gets one network interface on a private network that the security group controls. All instances in the same security group are on the same private network and, thus, can communicate without regard for the security group rules. Instances in other security groups or network connections outside of AWS are subject to the security group's filewall rules.
To enable ssh (as we did for the default group in the previous example)
euca-authorize cs290b -P tcp -p 22 -s 0.0.0.0/0After which, the decribe for the group shows
GROUP sg-f64f9a93 932234911131 cs290b rich-test-group vpc-94ad41f1 PERMISSION 932234911131 cs290b ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0 ingress PERMISSION 932234911131 cs290b ALLOWS -1 TO CIDR 0.0.0.0/0 egressEach instance gets an internal IP address on the private network and an internal DNS name. It also gets an external IP address and external name installed on the firewall/gateway associated with the security group.
When two instances communicate, they should use their internal addresses. If they do not, the traffic will need to traverse some gateway within AWS and doing so affects network performance. For this reason, the DNS that Amazon operates inside AWS uses a split-horizon model in which DNS names resole to their internal addresses from within AWS but the external name will resolve to the external IP address from outside AWS.
Also notice that an instance doesn't have a way to discover its external IP address or DNS name using normal Linux tools. For example, a call to ifconfig returns the private IP address associated with the instances interface and a DNS lookup on the external name (as described in the previous paragraph) also returns the private IP.
For example, an instance described as
INSTANCE i-bfaa7eb7 ami-f33fa9c3 ec2-54-187-63-154.us-west-2.compute.amazonaws.com ip-172-31-24-67.us-west-2.compute.internal running testkey 0 m1.small 2014-04-25T16:56:45.000Z us-west-2b aki-fc37bacc monitoring-disabled 54.187.63.154 172.31.24.67 vpc-94ad41f1 subnet-062a3c72 instance-store paravirtual xen sg-b07fb3d5 default falseyields
eth0 Link encap:Ethernet HWaddr 06:95:3e:09:4b:4a inet addr:172.31.24.67 Bcast:172.31.31.255 Mask:255.255.240.0 inet6 addr: fe80::495:3eff:fe09:4b4a/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:281 errors:0 dropped:0 overruns:0 frame:0 TX packets:252 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:32703 (32.7 KB) TX bytes:27826 (27.8 KB) Interrupt:27from ifconfig. Notice that the public IP address is not listed.
To resolve this problem, Amazon operates a web service at an unroutable IP address called the metadata service. Its address is 169.254.169.254 and a wget from this service will return "metadata" for the instance making the call. One of the entries in the metadata service (among many) is the public IPv4 address that is visible externally.
For example,
wget 169.254.169.254/latest/meta-data/public-ipv4for the instance described above yields 54.187.63.154.