I am using this cloudformation template to create spot instances and it is working as expected.
https://github.com/shantanuo/cloudformation/blob/master/updated/linux_training.tpl.txt
The only change I would like is to remove "Fleet" part from the type here...
Type: 'AWS::EC2::SpotFleet
The reason: When I try to stop an instance, I get a message that says "Fleet instances can not be stopped".
How do I buy spot instances using "normal" or default option?
The (AWS User interface) wizard allows me to generate spot instances those can be stopped and started as and when required. Looking for the same functionality from cloudformation template.
As suggested in the comments, I have modified the template to look like this. It works as expected. But it will create only a "template". I will still need to login to console to initiate a new instance using the template. I need to automate end-to-end process.
Parameters:
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-arm64-ebs
OksoftSG:
Type: 'AWS::EC2::SecurityGroup::Id'
KeyName:
Type: 'AWS::EC2::KeyPair::KeyName'
MyInstanceType:
Type: String
Default: r6g.medium
AllowedValues:
- r6g.medium
- r6g.4xlarge
- r6g.12xlarge
MyIpAddress:
Type: String
Resources:
MySpotInstance:
Type: 'AWS::EC2::LaunchTemplate'
Properties:
LaunchTemplateData:
ImageId: !Ref LatestAmiId
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref OksoftSG
InstanceType: !Ref MyInstanceType
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
DeleteOnTermination: true
VolumeType: standard
VolumeSize: 400
InstanceMarketOptions:
MarketType: spot
SpotOptions:
InstanceInterruptionBehavior: stop
SpotInstanceType: persistent
MyInstance:
Type: 'AWS::EC2::Instance'
Properties:
"LaunchTemplate" :
LaunchTemplateId: !Ref MySpotInstance
Version: !GetAtt MySpotInstance.LatestVersionNumber
When I delete the cloudformation template, it does not remove the spot request that it has created.
update:
The code mentioned in the answer works only for linux server. When I try to launch windows server, I get an error:
Property validation failure: [Value of property {/LaunchTemplateData} does not match type {Object}]
I used this template:
Parameters:
1InstanceType:
Type: String
Default: t2.small
AllowedValues:
- t2.small
- m3.medium
- m3.xlarge
- i3.xlarge
2SecurityGroup:
Type: 'AWS::EC2::SecurityGroup::Id'
3KeyName:
Type: 'AWS::EC2::KeyPair::KeyName'
4LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: /aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base
Resources:
Ec2LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: WindowsDesktop
LaunchTemplateData:
- ImageId: !Ref 4LatestAmiId
InstanceType: !Ref 1InstanceType
SecurityGroups:
- GroupId: !Ref 2SecurityGroup
KeyName: !Ref 3KeyName
InstanceMarketOptions:
MarketType: spot
SpotOptions:
SpotInstanceType: persistent
InstanceInterruptionBehavior: stop
Here is working example of creating LaunchTemplate with persistent spot request which creates an instance based on the template. The instances running on persistent spot request can be stopped, but not terminated (a replacement will be launch as soon as there is a spot place):
Parameters:
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: /aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-ebs
OksoftSG:
Type: 'AWS::EC2::SecurityGroup::Id'
KeyName:
Type: 'AWS::EC2::KeyPair::KeyName'
MyInstanceType:
Type: String
Default: m3.medium
AllowedValues:
- t2.small
- m3.medium
- m3.xlarge
- m3.2xlarge
- i3.xlarge
MyIpAddress:
Type: String
Resources:
SpotPersistantLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateData:
InstanceType: !Ref MyInstanceType
ImageId: !Ref LatestAmiId
SecurityGroupIds:
- !Ref OksoftSG
KeyName: !Ref KeyName
InstanceMarketOptions:
MarketType: spot
SpotOptions:
InstanceInterruptionBehavior: stop
SpotInstanceType: persistent
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
DeleteOnTermination: true
VolumeType: standard
VolumeSize: 400
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash -xe
- >
yum install -y docker mysql git python-pip >
/tmp/line1_succ.txt 2> /tmp/line1_err.txt
- >
service docker start > /tmp/line2_succ.txt 2>
/tmp/line2_err.txt
- >
echo 'india' | passwd ec2-user --stdin >
/tmp/line4a_succ.txt 2> /tmp/line4a_err.txt
- >
sed -i 's|[#]*PasswordAuthentication
no|PasswordAuthentication yes|g' /etc/ssh/sshd_config >
/tmp/line4b_succ.txt 2> /tmp/line4b_err.txt
- >
/etc/init.d/sshd restart > /tmp/line4c_succ.txt 2>
/tmp/line4c_err.txt
- >
docker run -d -p 8887:8888 -v /tmp:/tmp shantanuo/notebook >
/tmp/line3_succ.txt 2> /tmp/line3_err.txt
- >-
pip install aws-ec2-assign-elastic-ip > /tmp/line4_succ.txt
2> /tmp/line4_err.txt
- 'sudo sh -c "echo '
- !ImportValue secretKey
- |2
>> /home/ec2-user/mysecret.txt"
- 'sudo sh -c "echo '
- !ImportValue accessKey
- |2
>> /home/ec2-user/myaccesskey.txt"
- >-
/usr/local/bin/aws-ec2-assign-elastic-ip --access-key ''`cat
/home/ec2-user/myaccesskey.txt`'' --secret-key ''`cat
/home/ec2-user/mysecret.txt`'' --valid-ips '
- !Ref MyIpAddress
- |
'
MyPersistantSpotInstance:
Type: AWS::EC2::Instance
Properties:
LaunchTemplate:
LaunchTemplateId: !Ref SpotPersistantLaunchTemplate
Version: 1
A Spot Fleet is a way of requesting a certain amount of compute resources (RAM, CPU) that will "keep running" even if some Spot Instances are removed. This is why you cannot request to stop an instance -- because it will be automatically replaced.
Normally, a request for Spot Instance can be specified in a RunInstances() command. However, I was unable to find this option in AWS::EC2::Instance.
The closest I could find was using AWS::EC2::Instance and specifying a AWS::EC2::LaunchTemplate, which contains SpotOptions for specifying Spot Instances.
Frankly, I think that it is quite unusual to use a CloudFormation template to launch Spot Instances. This is because CloudFormation is normally used to launch resources in a reliable, consistent manner. In contrast, Spot Instances can disappear with very little notice. Therefore, Spot Instances are normally launched via specific API requests rather than via CloudFormation templates.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With