2

I can initiate a spot EC2 instance using the AWS command line tool.

aws ec2 request-spot-instances \
--spot-price 0.01 \
--instance-count 1 \
--launch-specification \
    "{ \
        \"ImageId\":\"ami-009d6802948d06e52\", \
        \"InstanceType\":\"t2.small\", \
        \"KeyName\":\"dec15a\", \
        \"UserData\":\"`base64 -w 0 userdata.sh`\" \
    }"

But how do I change the Volume size? I know the following code needs to be added to launch-specification. But I am not sure exactly where to add it.

"BlockDeviceMappings": [
    {
      "Ebs": {
        "VolumeSize": 107374182400,
        "VolumeType": "standard"
      }
    }
  ],

Update:

Why does the same command does not work using "file" like this?

# cat specification.json
{
"ImageId":"ami-009d6802948d06e52",
"InstanceType":"t2.small",
"KeyName":"dec15a",
"UserData":"`base64 -w 0 userdata.sh`",
"BlockDeviceMappings": [ {
"DeviceName":"/dev/xvda",
"Ebs": {
"VolumeSize": 100,
"VolumeType": "standard"
        }
    } ]
}

# aws ec2 request-spot-instances --spot-price "1.050" --instance-count 1 --type "one-time" --launch-specification file://specification.json
An error occurred (InvalidParameterValue) when calling the RequestSpotInstances operation: Invalid BASE64 encoding of user data
shantanuo
  • 3,579
  • 8
  • 49
  • 66

1 Answers1

3

That BlockDeviceMappings should be part of the --launch-specification JSON structure:

aws ec2 request-spot-instances --spot-price 0.01 --instance-count 1 \
  --launch-specification "{ \
    \"ImageId\":\"ami-009d6802948d06e52\", \
    \"InstanceType\":\"t2.small\", \
    \"KeyName\":\"dec15a\", \
    \"UserData\":\"`base64 -w 0 userdata.sh`\", \
    \"BlockDeviceMappings\": [ { \
       \"DeviceName\":\"/dev/xvda\", \         << DeviceName must be set
       \"Ebs\": { \
          \"VolumeSize\": 100, \                << VolumeSize is in GB
          \"VolumeType\": \"gp2\" \             << gp2 = SSD -> much faster
        } \
    } ] \
}"

If you want to resize the root volume set the DeviceName to /dev/xvda, if you want additional disk set it to /dev/xvdf.

Also note that the VolumeSize is in GB - your proposed 107374182400 would be a fairly huge volume! Use "VolumeSize": 100 to make it 100 GB.

And finally I suggest you use "VolumeType": "gp2" rather than "standard". While standard is a little cheaper it is way slower as it's a magnetic disk, gp2 is SSD and is much faster.

Hope that helps :)


Answer to the question update: If you save the JSON into a file you must include the output of base64 -w 0 userdata.sh. It won't be executed during runtime. So you'll need something like:

# cat specification.json
{
  "ImageId":"ami-009d6802948d06e52",
  "InstanceType":"t2.small",
  "KeyName":"dec15a",
  "UserData":"Iy9iaW4vYmFzaAoKCg...",     <<< Here paste the output of base64 -w0 userdata.sh as one long line
  "BlockDeviceMappings": [ {
    ...
  } ]
}
MLu
  • 24,849
  • 5
  • 59
  • 86
  • Executed the exact same command (without comments) and got this error: Error parsing parameter '--launch-specification': Invalid JSON: Expecting property name enclosed in double quotes: line 1 column 948 (char 947) – shantanuo Dec 04 '18 at 02:00
  • 1
    Did you remove all the spaces behind the trailing `\` on each line (esp where my comments were)? That `\` must be the last character on each line. – MLu Dec 04 '18 at 02:06
  • Is it possible to save JSON in a file? Updated my question. – shantanuo Dec 04 '18 at 02:22
  • @shantanuo Updated my answer, hope that helps :) – MLu Dec 04 '18 at 02:32
  • Thanks. It worked. AWS documentation is very confusion :( – shantanuo Dec 04 '18 at 03:29
  • Not related to this, but can I use the same JSON file as cloudformation template? – shantanuo Dec 04 '18 at 04:06
  • @shantanuo Yes, should be very close. Although I tend to use YAML instead of JSON for CloudFormation. Also you don't have to base64-encode the UserData, the CFN template can have it as a string. Refer to [AWS::EC2::Instance documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html) for details. – MLu Dec 04 '18 at 04:11