Skip to content

Instantly share code, notes, and snippets.

@ilyash-b
Created October 21, 2019 08:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilyash-b/e8e06427661e3fddb55f75a10d471452 to your computer and use it in GitHub Desktop.
Save ilyash-b/e8e06427661e3fddb55f75a10d471452 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ngs
# This script is rough translation of https://gist.github.com/shokoe/e7b4d80b63ea5931ba23bcad1c7684d4
# The translation was made as part of thinking about scripting by both parties: @shokoe, @ilyash-b
# Syntax: ec2_kamino.ngs <source instance 'Name' tag> [target new instance 'Name' tag].
# If target name is not given <source name>-clone is used.
# Description: Builds a temporary template from a given instance and runs the latest found ami from that template.
# New instance settings can be overriden by OVERRIDES.
# AMI selection is filtered by AMI_SELECT_TAGS.
# New instance in also tagged with 'clone-source' tag of source instance.
# New instance EBS volumes are tagged with the same 'Name' tag of the new instance.
# Bugs: `aws ec2 get-launch-template-data` does not return 'CreditSpecification>CpuCredits' for t3.
# If you need 'standard' add an override. Tested with awscli 1.16.138.
F ExitCode(e:Exception) 2
# template overrides for run-instances
OVERRIDES = %[--placement Tenancy=default]
# latest ami will be selected by these tags
AMI_SELECT_TAGS = {"i:role": "insta-server"}
F main(ins_name:Str, target_name:Str=null) {
target_name = target_name or ins_name + '-clone'
source = AWS2::Instance({'Name': ins_name}).the_one()
log("Cloning ${ins_name} (${source.InstanceId}) > ${target_name}")
log(" Overrides: ${OVERRIDES}")
log(" AMI filter tags: ${AMI_SELECT_TAGS}")
# get latest ami
################
output_ami = AWS2::Image(OwnerId="self", Tags=AMI_SELECT_TAGS).latest().the_one()
ami_age = Time().Int() - Time(output_ami.CreationDate).Int()
log(" Found AMI '${output_ami.Name}' (${output_ami.ImageId}), ${ami_age / 3600} hours old")
# create template
#################
tmpl_source = ``aws ec2 get-launch-template-data --instance-id ${source.InstanceId}``.LaunchTemplateData
# removals are required to launch template from an ami
tmpl_fix = tmpl_source.without('BlockDeviceMappings')
tmpl_fix.NetworkInterfaces .= map(X.without('PrivateIpAddresses'))
tmpl_fix .= without('CpuOptions')
tmpl_name = ins_name.replace(' ', '-')
output_create=``aws ec2 create-launch-template --launch-template-name "${tmpl_name}-tmp-clone" --launch-template-data ${tmpl_fix.encode_json()}``
exit_hook.delete_template = {
$(aws ec2 delete-launch-template --launch-template-name "${tmpl_name}-tmp-clone")
}
# run instance
##############
$(log: aws ec2 run-instances --launch-template LaunchTemplateName=${tmpl_name}-tmp-clone,Version=1 --image-id ${output_ami.ImageId} $*OVERRIDES --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=$target_name},{Key=clone-source,Value=$ins_name}]" "ResourceType=volume,Tags=[{Key=Name,Value=$target_name}]")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment