AWS Spot instance with AIM Role and Security Group
If you temporarily need an instance on AWS, you may opt for a spot instance to minimise your costs. Here is a ruby script to request a spot instance, assign AIM Role granting an S3 bucket read access and Security Group to allow SSH on the instance.
require 'aws-sdk'
require 'base64'
def request_spot_instance
ec2 = AWS::EC2.new(:ec2_endpoint => "ec2.ap-southeast-2.amazonaws.com")
iam = AWS::IAM.new
sg = create_security_group(ec2)
ip_arn = create_instance_profile(iam)
spot_request = {
spot_price: "0.0101",
instance_count: 1,
launch_specification: {
image_id: 'ami-3b4bd301',
key_name: 'my-keypair',
instance_type: 'm3.medium',
security_groups: [sg.name],
user_data: Base64.encode64('#!/bin/bash\necho "Initialising instance"'),
placement: {
availability_zone: "ap-southeast-2a"
},
iam_instance_profile: {
arn: ip_arn
},
block_device_mappings: [{
device_name: "/dev/sda1",
ebs: {
volume_size: 30
}
}]
}
}
response = ec2.client.request_spot_instances(spot_request)
end
Find or create the security group
def create_security_group(ec2)
sg_name = "MySecurityGroup"
ec2.security_groups.each do |sg|
return sg if sg.name.eql?(sg_name)
end
sg = ec2.security_groups.create(sg_name)
sg.authorize_ingress(:tcp, 22, '0.0.0.0/0')
sg
end
Find or create the instance profile and AIM role
def create_instance_profile(iam)
role_name = "S3Role"
instance_profile_name = "S3InstanceProfile"
iam.client.list_instance_profiles[:instance_profiles].each do |ip|
return ip[:arn] if ip[:instance_profile_name].eql? instance_profile_name
end
policy = AWS::IAM::Policy.new
policy.allow(:actions => ["s3:Get*","s3:List*"], :resources => 'arn:aws:s3:::myBucket*')
assume_role_policy_document = '{"Version":"2008-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},"Action":["sts:AssumeRole"]}]}'
iam.client.create_role(
:role_name => role_name,
:assume_role_policy_document => assume_role_policy_document)
iam.client.put_role_policy(
:role_name => role_name,
:policy_name => "AccessMyBucket",
:policy_document => policy.to_json)
resp = iam.client.create_instance_profile(
:instance_profile_name => instance_profile_name)
profile_arn = resp[:instance_profile][:arn]
iam.client.add_role_to_instance_profile(
:instance_profile_name => instance_profile_name,
:role_name => role_name)
profile_arn
end
Written by Bruno
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Ruby
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#