Launching and resizing an EC2 instance using AWS cli

In trying to answer an ex-colleague question on how to migrate/resize an instance, I tried doing things using AWS cli.

Let’s configure our aws cli 

[preyes@development ~]# aws configure
AWS Access Key ID [None]: ############
AWS Secret Access Key [None]: ###################
Default region name [None]: us-east-1
Default output format [None]:
[preyes@development ~]#

Let’s create a new instance using run-instances

[preyes@development ~]# aws ec2 run-instances --image-id ami-04681a1dbd79675a5 --count 1 --instance-type t2.micro --key-name ec2-keypair --security-group-ids sg-035ee364e7e068140 --subnet-id subnet-8a5ed3d6
{
 "Instances": [
 {
 "Monitoring": {
 "State": "disabled"
 },
 "PublicDnsName": "",
 "StateReason": {
 "Message": "pending",
 "Code": "pending"
 },
 "State": {
 "Code": 0,
 "Name": "pending"
 },
 "EbsOptimized": false,
 "LaunchTime": "2018-10-02T13:08:31.000Z",
 "PrivateIpAddress": "xxx.xx.xx.xxx",
 "ProductCodes": [],
 "VpcId": "vpc-60ab771a",
 "CpuOptions": {
 "CoreCount": 1,
 "ThreadsPerCore": 1
 },
 "StateTransitionReason": "",
 "InstanceId": "i-082500af8fb8d8487",
 "ImageId": "ami-04681a1dbd79675a5",
 "PrivateDnsName": "ip-xxx-xx-xx-xxx.ec2.internal",
 "KeyName": "ec2-keypair",
 "SecurityGroups": [
 {
 "GroupName": "ec2-securitygroup",
 "GroupId": "sg-035ee364e7e068140"
 }
 ],
 "ClientToken": "",
 "SubnetId": "subnet-8a5ed3d6",
 "InstanceType": "t2.micro",
 "NetworkInterfaces": [
 {
 "Status": "in-use",
 "MacAddress": "0e:0a:a0:87:68:a0",
 "SourceDestCheck": true,
 "VpcId": "vpc-60ab771a",
 "Description": "",
 "NetworkInterfaceId": "eni-058a75e0cd972f66a",
 "PrivateIpAddresses": [
 {
 "PrivateDnsName": "ip-xxx-xx-xx-xxx.ec2.internal",
 "Primary": true,
 "PrivateIpAddress": "xxx.xx.xx.xxx"
 }
 ],
 "PrivateDnsName": "ip-xxx-xx-xx-xxx.ec2.internal",
 "Attachment": {
 "Status": "attaching",
 "DeviceIndex": 0,
 "DeleteOnTermination": true,
 "AttachmentId": "eni-attach-0b79c1b5ed1e10d5c",
 "AttachTime": "2018-10-02T13:08:31.000Z"
 },
 "Groups": [
 {
 "GroupName": "ec2-securitygroup",
 "GroupId": "sg-035ee364e7e068140"
 }
 ],
 "Ipv6Addresses": [],
 "OwnerId": "265563422353",
 "SubnetId": "subnet-8a5ed3d6",
 "PrivateIpAddress": "xxx.xx.xx.xx"
 }
 ],
 "SourceDestCheck": true,
 "Placement": {
 "Tenancy": "default",
 "GroupName": "",
 "AvailabilityZone": "us-east-1a"
 },
 "Hypervisor": "xen",
 "BlockDeviceMappings": [],
 "Architecture": "x86_64",
 "RootDeviceType": "ebs",
 "RootDeviceName": "/dev/xvda",
 "VirtualizationType": "hvm",
 "AmiLaunchIndex": 0
 }
 ],
 "ReservationId": "r-0c54b78db90b9a2be",
 "Groups": [],
 "OwnerId": "265563422353"
}
[preyes@development ~]#

Checking the instance status using describe-instances

[preyes@development ~]# aws ec2 describe-instances
{
 "Reservations": [
 {
 "Instances": [
 {
 "Monitoring": {
 "State": "disabled"
 },
 "PublicDnsName": "ec2-xx-xxx-xxx-xx.compute-1.amazonaws.com",
 "State": {
 "Code": 16,
 "Name": "running"
 },
 "EbsOptimized": false,
 "LaunchTime": "2018-10-02T13:08:31.000Z",
 "PublicIpAddress": "xx.xxx.xxx.xx",
 "PrivateIpAddress": "xxx.xx.xx.xxx",
 "ProductCodes": [],
 "VpcId": "vpc-60ab771a",
 "CpuOptions": {
 "CoreCount": 1,
 "ThreadsPerCore": 1
 },
 "StateTransitionReason": "",
 "InstanceId": "i-082500af8fb8d8487",
 "EnaSupport": true,
 "ImageId": "ami-04681a1dbd79675a5",
 "PrivateDnsName": "ip-xxx-xx-xx-xxx.ec2.internal",
 "KeyName": "ec2-keypair",
 "SecurityGroups": [
 {
 "GroupName": "ec2-securitygroup",
 "GroupId": "sg-035ee364e7e068140"
 }
 ],
 "ClientToken": "",
 "SubnetId": "subnet-8a5ed3d6",
 "InstanceType": "t2.micro",
 "NetworkInterfaces": [
 {
 "Status": "in-use",
 "MacAddress": "0e:0a:a0:87:68:a0",
 "SourceDestCheck": true,
 "VpcId": "vpc-60ab771a",
 "Description": "",
 "NetworkInterfaceId": "eni-058a75e0cd972f66a",
 "PrivateIpAddresses": [
 {
 "PrivateDnsName": "ip-xxx-xx-xx-xxx.ec2.internal",
 "PrivateIpAddress": "xxx.xx.xx.xxx",
 "Primary": true,
 "Association": {
 "PublicIp": "xx.xxx.xxx.xx",
 "PublicDnsName": "ec2-xx-xxx-xxx-xx.compute-1.amazonaws.com",
 "IpOwnerId": "amazon"
 }
 }
 ],
 "PrivateDnsName": "ip-xxx-xx-xx-xxx.ec2.internal",
 "Attachment": {
 "Status": "attached",
 "DeviceIndex": 0,
 "DeleteOnTermination": true,
 "AttachmentId": "eni-attach-0b79c1b5ed1e10d5c",
 "AttachTime": "2018-10-02T13:08:31.000Z"
 },
 "Groups": [
 {
 "GroupName": "ec2-securitygroup",
 "GroupId": "sg-035ee364e7e068140"
 }
 ],
 "Ipv6Addresses": [],
 "OwnerId": "265563422353",
 "PrivateIpAddress": "xxx.xx.xx.xxx",
 "SubnetId": "subnet-8a5ed3d6",
 "Association": {
 "PublicIp": "xxx.xx.xx.xxx",
 "PublicDnsName": "ec2-xx-xx-xxx-xx.compute-1.amazonaws.com",
 "IpOwnerId": "amazon"
 }
 }
 ],
 "SourceDestCheck": true,
 "Placement": {
 "Tenancy": "default",
 "GroupName": "",
 "AvailabilityZone": "us-east-1a"
 },
 "Hypervisor": "xen",
 "BlockDeviceMappings": [
 {
 "DeviceName": "/dev/xvda",
 "Ebs": {
 "Status": "attached",
 "DeleteOnTermination": true,
 "VolumeId": "vol-0adcd79e3ad20f7d2",
 "AttachTime": "2018-10-02T13:08:32.000Z"
 }
 }
 ],
 "Architecture": "x86_64",
 "RootDeviceType": "ebs",
 "RootDeviceName": "/dev/xvda",
 "VirtualizationType": "hvm",
 "AmiLaunchIndex": 0
 }
 ],
 "ReservationId": "r-0c54b78db90b9a2be",
 "Groups": [],
 "OwnerId": "265563422353"
 }
 ]
}
[preyes@development ~]#

Now let’s try resizing our instance. For this, we need the instance to be in stopped state. Note that you can only stop an EBS-backed instance. You cannot stop an  Instance-store backed instance as the data will be lost when the an instance-store back instance is stopped.  For information on how to resize an instance-store backed instance, kindly check this page.

Let’s stop our instance using stop-instances action

[preyes@development ~]# aws ec2 stop-instances --instance-id i-082500af8fb8d8487
{
 "StoppingInstances": [
 {
 "InstanceId": "i-082500af8fb8d8487",
 "CurrentState": {
 "Code": 64,
 "Name": "stopping"
 },
 "PreviousState": {
 "Code": 16,
 "Name": "running"
 }
 }
 ]
}
[preyes@development ~]#

Let’s check if our instance is in stopped state

[preyes@development ~]# aws ec2 describe-instances --instance-id i-082500af8fb8d8487 --query Reservations[].Instances[].State
[
 {
 "Code": 80,
 "Name": "stopped"
 }
]
[preyes@development ~]#

Now that our instance is in stopped state, we can now change the instance type. I’m changing my instance from t2.micro to t2.nano

[preyes@development ~]# aws ec2 modify-instance-attribute --instance-type t2.nano --instance-id i-082500af8fb8d8487

Here we can now see that our instance was changed to t2.nano

[preyes@development ~]# aws ec2 describe-instances --instance-id i-082500af8fb8d8487 --query Reservations[].Instances[].InstanceType
[
 "t2.nano"
]
[preyes@development ~]#

Starting back our instance using start-instances

[preyes@development ~]# aws ec2 start-instances --instance-id i-082500af8fb8d8487
{
 "StartingInstances": [
 {
 "InstanceId": "i-082500af8fb8d8487",
 "CurrentState": {
 "Code": 0,
 "Name": "pending"
 },
 "PreviousState": {
 "Code": 80,
 "Name": "stopped"
 }
 }
 ]
}
[preyes@development ~]#

And again running describe-instances querying the state

[preyes@development ~]# aws ec2 describe-instances --instance-id i-082500af8fb8d8487 --query Reservations[].Instances[].State
[
 {
 "Code": 16,
 "Name": "running"
 }
]
[preyes@development ~]#

What approach do you take in order to minimize downtime? I’m thinking you should have a resilient system in the first place.  Instance groups?