14

I cannot figure out from documentation and source code how to define size of the root device.

You can specify N additional block devices using BlockDeviceMappings section where you can declare their sizes. But there is no way to set size of the root volume. So it always create an instance with root volume of size 8GB which is the default value.

lisak
  • 21,611
  • 40
  • 152
  • 243
  • AWS documentation: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html#change-root-volume-initial-size – AlexK Sep 20 '21 at 05:08

4 Answers4

18

Ran into this issue myself today, probably to late for the original poster, but in case anyone else stumbles across this question later I did the following:

import boto3
ec2 = boto3.resource('ec2',
                     region_name='eu-west-1',
                     aws_access_key_id='my-key',
                     aws_secret_access_key='my-secret')
instance = ec2.create_instances(ImageId='my-image-id',
                                BlockDeviceMappings=[{"DeviceName": "/dev/xvda","Ebs" : { "VolumeSize" : 50 }}])

The above has been truncated (you'll need to pass more arguments to create_instances for other values, InstanceType etc.) but essentially pass the root device (/dev/xvda in this case) in as part of the BlockDeviceMappings value with the desired volume size (50GB in the above example).

Steve Jefferies
  • 589
  • 5
  • 13
  • 1
    For my instances, the root device is called `/dev/sda1`, which I had to use instead of `/dev/xvda`, but this is otherwise correct for me in EC2. OpsWorks users should note that OpsWorks' `create_instance()` API, while similar to EC2's `create_instances` described in this answer, has a few differences; you need to specify `"ROOT_DEVICE"` as the `DeviceName` instead of the actual name, and a `VolumeType` is required for every volume (set it to `"gp2"` to get the default general purpose SSD volume type). Yes, these inconsistencies are silly on Amazon's part. – Mark Amery Aug 08 '16 at 19:01
  • To get the device name consistently with boto3: ```imgs = list(ec2.images.filter(ImageIds=['my-image-id'])); device_name = imgs[0].root_device_name ``` – Aaron V Oct 12 '18 at 21:27
  • When I do the above it works but `lsblk` shows /dev/svda still at 8Gb so it does not take the supplied value. – Paul Whipp Mar 31 '20 at 00:33
  • Further research shows me that this creates an additional 40gb volume which lacks a partition. The root volume remains present at 8Gb. – Paul Whipp Mar 31 '20 at 01:19
  • It seems strange I cannot set this with create_instances. I've found that the answer here just adds another EBS rather than changing the root. For me, the workaround is to generate an AMI with the required initial root size (this sticks as the default so is good when creating the new instances). Then the instances can be resized subsequently using boto3 volume size modification plus subsequent partitiion expansion. Something of a pain but doable. – Paul Whipp Mar 31 '20 at 01:42
8

Same as Steve Jeffereies has mentioned, naming the DeviceName is the key. I was able to use /dev/sda1 which you would usually see on AWS console. The following is a working example using magnetic,

BlockDeviceMappings=[
    {
        'DeviceName': '/dev/sda1',
        'Ebs': {
            'VolumeSize': 30,
            'VolumeType': 'standard'
        }
    }
]
barryku
  • 2,496
  • 25
  • 16
  • Are you running this in a specific order within the `create_instance`? Because I end up having two EBSs one with the default size and the second with the size specified. Also, because they have both `/dev/sda1` the instance stops itself straight away... Any idea? Edit - formatting – 0r4cl3 Sep 12 '18 at 14:08
0

Follow is minimal required fields that have to be set the size of the root device:

import boto3
ec2_resource = boto3.resource('ec2')
    reservations = ec2_resource.create_instances(

        ImageId= "ami-xyz",
        MinCount=1,
        MaxCount=1,
        InstanceType='xyz',
        KeyName='key-pair',
        TagSpecifications=[
            {
                'ResourceType': 'instance',
                'Tags': [{
                     'Key': 'Name',
                    'Value': 'xyz-machine'
                }]
            }
        ],
        IamInstanceProfile={
        'Name':'xyz-role'
        },
        BlockDeviceMappings=[
            {
                'DeviceName': '/dev/sda1',
                'Ebs': {
                    'VolumeSize': 30,
                    'VolumeType': 'standard'
                }
            }
        ]
    )
Sheece Gardazi
  • 480
  • 6
  • 14
-1

See Stackoverflow: How to launch EC2 instance with Boto, specifying size of EBS?

Also, here's a way to do it from the AWS Command-Line Interface (CLI):

aws ec2 run-instances --image-id ami-xxxxxxxx --instance-type m1.xlarge --block-device-mappings '{"DeviceName": "/dev/sda1","Ebs" : { "VolumeSize" : 50 }}'
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • -1; neither your link (which is about Boto) nor your command-line incantation (which is for the command line client) answers the question, which was about *Boto 3*. – Mark Amery Aug 08 '16 at 19:04