Launch AWS EC2 Instance Via AWS CLI 

How to launch EC2 instance using the AWS Command Line Interface (AWS CLI) and attach extra storage

In a previous post, I have written about how to create an AWS EC2 instance using the AWS Management console. In this post, I am going to do the same via the AWS CLI. You can check out the commands for launching an EC2 instance in this post.

You can easily launch an instance using the AWS command Line Interface or the AWS CLI. However, you need to have installed and configured the AWS CLI on your computer to do that. If you have it installed and configured then you can launch your instance with a run-instances command.

You will need a few things to create your instance. First, you will need to select an AMI (Amazon Machine Image) for your instance. You will also need a key pair, your security group id and a subnet.

$ run-instances

[–image-id <value>] Amazon Machine image id

[–instance-type <value>] Instance type like t2.micro

[–key-name <value>] name of the keypair (you can create one)

[–security-group-ids <value>] the default security group id to be linked to the instance

[–subnet-id <value>] id of a subnet under the default VPC (Virtual Private Cloud).

If you already have a keypair for use, you can just move on to the next step.To create a key pair, you can run the create-key-pair command from the AWS CLI. Suppose we are going to name the key pair we are about to create ExampleKeyPair. Then we will run the following command:

$ aws ec2 create-key-pair –key-name ExampleKeyPair

The output will include the KeyFingerprint, KeyMaterial, KeyName and KeyPairId.

Sample Output:

{ “KeyFingerprint”:”63:73:84:a4:bb:49:17:18:86:b9:8a:fd:e4:7e:98:39:19:42:65:c3″,   

“KeyMaterial”:

“—–BEGIN RSA PRIVATE KEY—–EXAMPLEKEYKCAQEAy7WZhaDsrA1W3mRlQtvhwyORRX8gnxgDAfRt/gx42kWXsT4rXE/b5CpSgie/vBoU7jLxx92pNHoFnByP+Dc21eyyz6CvjTmWA0JwfWiW5/akH7iO5dSrvC7dQkW2duV5QuUdE0QWZ/aNxMniGQE6XAgfwlnXVBwrerrQo+ZWQeqiUwwMkuEbLeJFLhMCvYURpUMSC1oehm449ilx9X1FG50TCFeOzfl8dqqCP6GzbPaIjiU19xX/azOR9V+tpUOzEL+wmXnZt3/nHPQ5xvD2OJH67nb2km6SuPWoPzev/D8V+x4+bHthfSjR9Y7DvQFjfBVwHXigBdtZcU2/wei8D/HYwIDAQABAoIBAGZ1kaEvnrqu/uler7vgIn5m7lN5LKw4hJLAIW6tUT/fzvtcHK0SkbQCQXuriHmQ2MQyJX/0kn2NfjLV/ufGxbL1mb5qwMGUnEpJaZD6QSSs3kICLwWUYUiGfc0uiSbmJoap/GTLU0W5Mfcv36PaBUNy5p53V6G7hXb2bahyWyJNfjLe4M86yd2YK3V2CmK+X456/BOsShnJ36+hjrXPPWmV3N9zEmCdJjA+K15DYmhm/tJWSD981oGk9TopEp7CkIfatEAT123yyZiVqoRq6k64iuM9JkA3OzdXzMQexXVJ1TLZVEH0E7bhlY9d8O1ozRoQs/FiZNAx2iijCWyv0lpjE73+kCgYEA9mZtyhkHkFDpwrSM1APaL8oNAbbjwEy7Z5Mqfql+lIp1YkriL0DbLXlvRAH+yHPRit2hHOjtUNZh4Axv+cpg09qbUI3+43eEy24B7G/Uh+GTfbjsXsOxQx/xp9otyVwc7hsQ5TA5PZb+mvkJ5OBEKzet9XcKwONBYELGhnEPe7cCgYEA06Vgov6YHleHui9kHuwsayav0elc5zkxjF9nfHFJRry21R1trw2Vdpn+9g481URrpzWVOEihvm+xTtmaZlSp//lkq75XDwnUWA8gkn6O3QE3fq2yN98BURsAKdJfJ5RL1HvGQvTe10HLYYXpJnEkHv+Unl2ajLivWUt5pbBrKbUCgYBjbO+OZk0sCcpZ29sbzjYjpIddErySIyRX5gV2uNQwAjLdp9PfN295yQ+BxMBXiIycWVQiw0bHoMo7yykABY7Ozd5wQewBQ4AdSlWSX4nGDtsiFxWiI5sKuAAeOCbTosy1s8w8fxoJ5Tz1sdoxNeGsArq6Wv/G16zQuAE9zK9vvwKBgF+09VI/1wJBirsDGz9whVWfFPrTkJNvJZzYt69qezxlsjgFKshyWBhd4xHZtmCqpBPlAymEjr/TOlbxyARmXMnIOWIAnNXMGB4KGSyl1mzSVAoQ+fqR+cJ3d0dyPl1jjjb0Ed/NY8frlNDxAVHE8BSkdsx2f6ELEyBKJSRr9snRAoGAMrTwYneXzvTskF/S5Fyu0iOegLDaNWUH38v/nDCgEpIXD5Hn3qAEcju1IjmbwlvtW+nY2jVhv7UGd8MjwUTNGItdb6nsYqM2asrnF3qSVRkAKKKYeGjkpUfVTrW0YFjXkfcrR/V+QFL5OndHAKJXjW7a4ejJLncTzmZSpYzwApc=

—–END RSA PRIVATE KEY—–“,

“KeyName”: “ExampleKeyPair”,   

“KeyPairId”: “key-09e5c134eef4a9876”}

You need to save the private key to a file. If you want to directly download the file, you can run the following command instead in the AwS CLI:

$ aws ec2 create-key-pair –key-name ExampleKeyPair –query ‘KeyMaterial’ –output text > ExampleKeyPair.pem

The resulting output file will include the RSA Private key that looks like the key above.

To find the subnet id for launching an instance, you can use a subnet from the default VPC created by the system. Go to the VPC dashboard to find the subnet id or just run the following command from the AWS CLI:

$ aws ec2 describe-subnets

The output will include subnet ids and will look like the following for each subnet:

  “Subnets”: [

     {

         “AvailabilityZone”: “us-east-1f”,

         “AvailabilityZoneId”: “use1-az5”,

         “AvailableIpAddressCount”: 4091,

         “CidrBlock”: “172.31.60.0/20”,

         “DefaultForAz”: true,

         “MapPublicIpOnLaunch”: true,

         “MapCustomerOwnedIpOnLaunch”: false,

         “State”: “available”,

         “SubnetId”: “subnet-d42332daexample”,

         “VpcId”: “vpc-12345abc”,

         “OwnerId”: “1234567890”,

         “AssignIpv6AddressOnCreation”: false,

         “Ipv6CidrBlockAssociationSet”: [],

         “SubnetArn”: “arn:aws:ec2:us-east-1:12345678901122:subnet/subnet-d51452da79dexample”,

        “EnableDns64”: false,

         “Ipv6Native”: false,

         “PrivateDnsNameOptionsOnLaunch”: {

             “HostnameType”: “ip-name”,

             “EnableResourceNameDnsARecord”: false,

             “EnableResourceNameDnsAAAARecord”: false

         }

Next, run the following command to find image ids:

$ aws ec2 describe-images –owners self amazon

The resulting output will show you the description of various AMIs. For example, here is the description for an AMI:

  {

         “Architecture”: “x86_64”,

         “CreationDate”: “2021-10-01T06:17:04.000Z”,

         “ImageId”: “ami-05b5badc2f7ddd88d “,  <— (The Image ID)

         “ImageLocation”: “amzn-ami-us-east-1/dfab17d9e8f6c8f6de13c5c1f76ea37e2b0a9027b6b47430dafe7fe59ed7555c/137112412989/amzn-ami-minimal-hvm-2018.03.0.20211001.0-x86_64.ext4.gpt.10g.manifest.xml”,

         “ImageType”: “machine”,

         “Public”: true,

         “OwnerId”: “137112412989”,

         “PlatformDetails”: “Linux/UNIX”,

         “UsageOperation”: “RunInstances”,

         “State”: “available”,

         “BlockDeviceMappings”: [],

         “Description”: “Amazon Linux AMI 2018.03.0.20211001.0 x86_64 Minimal HVM s3”,

            “EnaSupport”: true,

         “Hypervisor”: “xen”,

         “ImageOwnerAlias”: “amazon”,

         “Name”: “amzn-ami-minimal-hvm-2018.03.0.20211001.0-x86_64-s3”,

         “RootDeviceType”: “instance-store”,

         “SriovNetSupport”: “simple”,

         “VirtualizationType”: “hvm”,

         “DeprecationTime”: “2023-10-01T06:17:04.000Z”

     },

Here are the AMI ids of leading operating systems

– Amazon Linux 2: ami-006dcf34c09e50022
– Ubuntu:  ami-0557a15b87f6559cf
– MacOS: ami-00805552fa999b1a0
– Windows: ami-0c2b0d3fb02824d92
– Red Hat: ami-0c9978668f8d55984
– SUSE Linux:  ami-0c544bda9765444c2

– Debian: ami-0fec2c2e2017f4e7b

Now, we have everything required to run the command except the security groups ids.

Image id : ami-05b5badc2f7ddd88d

Instance type:- t2.micro

Key name :- ExampleKeyPair

Subnet id:- subnet-6e7f829e

Security groups ids: ?

I have written in detail in another post about working with security groups in EC2. You can read about creating security groups and adding rules in the post.

You only need to have the default VPC id (search VPCs in the console) for creating the security group and it can be done with :-

$ aws ec2 create-security-group –group-name myfirst-sg –description “My first security group” –vpc-id vpc-xxxxxxx

Once you have the security group ready, you can run the command to create the EC2 instance. If you want to create two or more such instances, just change the count in the command to 2 or more.

$ aws ec2 run-instances –image-id ami-0357699c20453f1ab –count 1 –instance-type t2.large –key-name ExampleKeyPair –security-group-ids sg-903004f8 –subnet-id subnet-6e7f829e

When an EC2 instance is launched, it remains in the pending stage initially before it changes to initializing and running. If your EC2 instance was launched successfully, you would receive an output that looks like the following (example output):

{

“Groups”: [],

“Instances”: [

     {

         “AmiLaunchIndex”: 0,

         “ImageId”: “ami-05b5badc2f7ddd88d”,

         “InstanceId”: “i-0xa3x64x9d66c3111”,  <– (Instance Id)

         “InstanceType”: “t2.large”,

         “KeyName”: “ExampleKeyPair”,

         “LaunchTime”: “2023-03-04T04:25:20+00:00”,

         “Monitoring”: {

             “State”: “disabled”

         },

         “Placement”: {

             “AvailabilityZone”: “us-east-1f”,  <– ( Instance Availability Zone)

             “GroupName”: “”,

             “Tenancy”: “default”

         },

         “PrivateDnsName”: “ip-172-xx-xx-xx.ec2.internal”,

         “PrivateIpAddress”: “172.33.66.55”,

         “ProductCodes”: [],

         “PublicDnsName”: “”,

         “State”: {

             “Code”: 0,

             “Name”: “pending”

         },

         “StateTransitionReason”: “”,

         “SubnetId”: “subnet-6e7f829e “,

         “VpcId”: “vpc-33e8844c”,

         “Architecture”: “x86_64”,

“BlockDeviceMappings”: [],

         “ClientToken”: “44ac1a22-5d12-4567-b789-050555a771f1”,

         “EbsOptimized”: false,

         “EnaSupport”: true,

         “Hypervisor”: “xen”,

         “NetworkInterfaces”: [

             {

                 “Attachment”: {

                     “AttachTime”: “2023-03-04T04:25:20+00:00”,

                     “AttachmentId”: “eni-attach-05777e67d6655e5d5”,

                     “DeleteOnTermination”: true,

                     “DeviceIndex”: 0,

                     “Status”: “attaching”,

                     “NetworkCardIndex”: 0

                 },

                 “Description”: “”,

                 “Groups”: [

                     {

                         “GroupName”: “allowtraffic”,  <– (Security group name)

                         “GroupId”: “sg-903004f8”         <– (Security group id)

                     }

                 ],

                 “Ipv6Addresses”: [],

                 “MacAddress”: “16:xx:7b:xx:02:xx”,

                 “NetworkInterfaceId”: “eni-0x7cx9a0cxxxxxcc9”,

                 “OwnerId”: “302288833888”,

                 “PrivateDnsName”: “ip-172-xx-xx-xx.ec2.internal”,

                 “PrivateIpAddress”: “172.xx.xx.xx”,

                “PrivateIpAddresses”: [

                     {

   “Primary”: true,

                         “PrivateDnsName”: “ip-172-31-69-52.ec2.internal”,

                         “PrivateIpAddress”: “172.xx.66.xx”  <– (Private IP Address)

                     }

                 ],

                 “SourceDestCheck”: true,

                 “Status”: “in-use”,

                 “SubnetId”: “subnet-6e7f829e”,

                 “VpcId”: “vpc-22e7777c”,

                 “InterfaceType”: “interface”

             }

         ],

         “RootDeviceName”: “/dev/xvda”,

         “RootDeviceType”: “ebs”,      <– (EBS backed Instance)

         “SecurityGroups”: [

             {

                 “GroupName”: “allowtraffic”,

                 “GroupId”: “sg-903004f8”

             }

         ],

         “SourceDestCheck”: true,

         “StateReason”: {

             “Code”: “pending”,

             “Message”: “pending”

         },

         “VirtualizationType”: “hvm”,

         “CpuOptions”: {

             “CoreCount”: 2,       <– (CORE COUNT)

“ThreadsPerCore”: 1

         },

         “CapacityReservationSpecification”: {

             “CapacityReservationPreference”: “open”

         },

         “MetadataOptions”: {

             “State”: “pending”,

             “HttpTokens”: “optional”,

             “HttpPutResponseHopLimit”: 1,

             “HttpEndpoint”: “enabled”,

             “HttpProtocolIpv6”: “disabled”,

             “InstanceMetadataTags”: “disabled”

         },

         “EnclaveOptions”: {

             “Enabled”: false

         },

         “PrivateDnsNameOptions”: {

             “HostnameType”: “ip-name”,

             “EnableResourceNameDnsARecord”: false,

             “EnableResourceNameDnsAAAARecord”: false

         },

         “MaintenanceOptions”: {

             “AutoRecovery”: “default”

         }

     }

],

“OwnerId”: “30228849933344”,

“ReservationId”: “r-0d2b32fecd21aab14”

}

Finally, Your instance has been created with the following instance id:

“InstanceId”: “i-0xa3x64x9d66c3111”. 

If you want to attach extra volume (ssd storage) to your instance, you can do that by creating and then attaching a volume in the same availability zone as our instance.

To create an instance, we use the create-instances command and to attach a volume attach-volume command. Now, we are going to attach 100 gb extra storage to our instance. You can change the size of the volume with the size parameter in the create-volume command.

If I want to create a volume in the availability zone us-east-1a, I can do that with the following command:-

$ aws ec2 create-volume –volume-type gp2 –size 100 –availability-zone us-east-1a

The resulting output will be something like this: –
{

“AvailabilityZone”: “us-east-1a”,

“CreateTime”: “2023-03-04T14:05:09+00:00”,

“Encrypted”: false,

“Size”: 100,

“SnapshotId”: “”,

“State”: “creating”,

“VolumeId”: “vol-06e550abbdb899fba”,

“Iops”: 300,

“Tags”: [],

“VolumeType”: “gp2”,

“MultiAttachEnabled”: false

}

Note the volume id in the above output because we will need it and the instance id to which we are going to attach the volume. To attach the just created volume as /dev/sdf to the instance we created, you can run the following command:

$ aws ec2 attach-volume –volume-id vol-06e550abbdb899fba –instance-id i-0xa3x64x9d66c3111 –device /dev/sdf

The resulting output will look like the following showing that the volume is being attached:

{

“AttachTime”: “2023-03-04T14:10:14.496000+00:00”,

“Device”: “/dev/sdf”,

“InstanceId”: “i-0xa3x64x9d66c3111“,

“State”: “attaching”,

“VolumeId”: “vol-06e550abbdb899fba”

}

If you want to verify, just go to the EC2 dashboard and click on the instance you have just created and attached the volume to. On the instance summary page, click on storage. You will be able to see the Volume id, volume size and device name of the attached volume there.  Or SSH connect to your instance and type lsblk to see the attached disks and their sizes. 

Launch an AWS EC2 instance with Ubuntu 22.04

Suppose you want to launch an instance with Ubuntu 22.04, you will only need to change the machien image and run the same run instances command:

$aws ec2 run-instances –image-id <ami-0557a15b87f6559cf> –count 1 –instance-type t2.small –key-name ExampleKeyPair –security-group-ids sg-071808a961b19ca04  

Image id for Ubuntu: ami-0557a15b87f6559cf

Now, go to your console and check out the newly created instance. Once you ssh into your instance, run:

$ sudo apt update -y

Thanks for reading!

Suggested Reading: Install SSL on your AWS EC2 hosted website in 3 steps