Friday 21 October 2016

AWS CLI - Switching to and from regional EC2 reserved instances

AWS recently announced the availability of regional reserved instances, this post explains how to switch a reservation from AZ specific to regional (and back) using the AWS CLI.

Step 1, find the reservation to modify

$ aws ec2 describe-reserved-instances --filters Name=state,Values=active
{
    "ReservedInstances": [
        {
            "ReservedInstancesId": "c416aeaf-fb64-4218-970f-7426f6f32377", 
            "OfferingType": "No Upfront", 
            "AvailabilityZone": "eu-west-1c", 
            "End": "2017-10-21T08:45:55.000Z", 
            "ProductDescription": "Linux/UNIX", 
            "Scope": "Availability Zone", 
            "UsagePrice": 0.0, 
            "RecurringCharges": [
                {
                    "Amount": 0.01, 
                    "Frequency": "Hourly"
                }
            ], 
            "OfferingClass": "standard", 
            "Start": "2016-10-21T08:45:56.708Z", 
            "State": "active", 
            "FixedPrice": 0.0, 
            "CurrencyCode": "USD", 
            "Duration": 31536000, 
            "InstanceTenancy": "default", 
            "InstanceType": "t2.micro", 
            "InstanceCount": 1
        }
    ]
}

The "Scope" field in the response shows that this reservation is currently specific to an Availability Zone, eu-west-1c in this case.

Step 2, request the modification

$ aws ec2 modify-reserved-instances --reserved-instances-ids c416aeaf-fb64-4218-970f-7426f6f32377 --target-configurations Scope=Region,InstanceCount=1
{
    "ReservedInstancesModificationId": "rimod-aaada6ed-fec9-47c7-92e2-6edf7e61f2ce"
}

The Scope=Region indicates that this reservation should be converted to a regional reservation, InstanceCount is a required parameter to indicate the number of reservations the modification should be applied to.

Step 3, monitor progress

$ aws ec2 describe-reserved-instances-modifications
{
    "ReservedInstancesModifications": [
        {
            "Status": "processing", 
            "ModificationResults": [
                {
                    "ReservedInstancesId": "35f9b908-ae36-41ca-ac0b-4c67c887135b", 
                    "TargetConfiguration": {
                        "InstanceCount": 1
                    }
                }
            ], 
            "EffectiveDate": "2016-10-21T08:45:57.000Z", 
            "CreateDate": "2016-10-21T08:50:28.585Z", 
            "UpdateDate": "2016-10-21T08:50:31.098Z", 
            "ReservedInstancesModificationId": "rimod-aaada6ed-fec9-47c7-92e2-6edf7e61f2ce", 
            "ReservedInstancesIds": [
                {
                    "ReservedInstancesId": "c416aeaf-fb64-4218-970f-7426f6f32377"
                }
            ]
        }
    ]
}

The "Status" in the response will show "processing" until the modification has completed successfully, at which time it will change to "fulfilled":

$ aws ec2 describe-reserved-instances-modifications
{
    "ReservedInstancesModifications": [
        {
            "Status": "fulfilled", 
            "ModificationResults": [
                {
                    "ReservedInstancesId": "35f9b908-ae36-41ca-ac0b-4c67c887135b", 
                    "TargetConfiguration": {
                        "InstanceCount": 1
                    }
                }
            ], 
            "EffectiveDate": "2016-10-21T08:45:57.000Z", 
            "CreateDate": "2016-10-21T08:50:28.585Z", 
            "UpdateDate": "2016-10-21T09:11:33.454Z", 
            "ReservedInstancesModificationId": "rimod-aaada6ed-fec9-47c7-92e2-6edf7e61f2ce", 
            "ReservedInstancesIds": [
                {
                    "ReservedInstancesId": "c416aeaf-fb64-4218-970f-7426f6f32377"
                }
            ]
        }
    ]
}

Step 4, success!

The new reservation is now regional (Scope=Region):

$ aws ec2 describe-reserved-instances --filters Name=state,Values=active
{
    "ReservedInstances": [
        {
            "ReservedInstancesId": "35f9b908-ae36-41ca-ac0b-4c67c887135b", 
            "OfferingType": "No Upfront", 
            "FixedPrice": 0.0, 
            "End": "2017-10-21T08:45:55.000Z", 
            "ProductDescription": "Linux/UNIX", 
            "Scope": "Region", 
            "UsagePrice": 0.0, 
            "RecurringCharges": [
                {
                    "Amount": 0.01, 
                    "Frequency": "Hourly"
                }
            ], 
            "OfferingClass": "standard", 
            "Start": "2016-10-21T08:45:57.000Z", 
            "State": "active", 
            "InstanceCount": 1, 
            "CurrencyCode": "USD", 
            "Duration": 31536000, 
            "InstanceTenancy": "default", 
            "InstanceType": "t2.micro"
        }
    ]
}

Switching back

Follows the same process with the added requirement of specifying which AZ the reservation should be linked to:

$ aws ec2 modify-reserved-instances --reserved-instances-ids 35f9b908-ae36-41ca-ac0b-4c67c887135b --target-configurations Scope="Availability Zone",InstanceCount=1,AvailabilityZone=eu-west-1b
{
    "ReservedInstancesModificationId": "rimod-9e490be9-55a3-48cf-81e9-2662b13db2f8"
}

$ aws ec2 describe-reserved-instances --filters Name=state,Values=active
{
    "ReservedInstances": [
        {
            "ReservedInstancesId": "df70d097-2f33-4962-bca6-37af15ca819e", 
            "OfferingType": "No Upfront", 
            "AvailabilityZone": "eu-west-1b", 
            "End": "2017-10-21T08:45:55.000Z", 
            "ProductDescription": "Linux/UNIX", 
            "Scope": "Availability Zone", 
            "UsagePrice": 0.0, 
            "RecurringCharges": [
                {
                    "Amount": 0.01, 
                    "Frequency": "Hourly"
                }
            ], 
            "OfferingClass": "standard", 
            "Start": "2016-10-21T08:45:58.000Z", 
            "State": "active", 
            "FixedPrice": 0.0, 
            "CurrencyCode": "USD", 
            "Duration": 31536000, 
            "InstanceTenancy": "default", 
            "InstanceType": "t2.micro", 
            "InstanceCount": 1
        }
    ]
}