Created
October 21, 2019 10:57
-
-
Save ilyash-b/b32c89699cc63ede1a2e0ce572d04e66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
# The script was changed to match @ilyash-b's environment | |
# Starts new instance with same settings as given instances from backup AMI of the given instance | |
# Syntax: ec2_kamino.ngs <ENV> <ROLE> | |
# Syntax: ec2_kamino.ngs <INSTNACE_ID> | |
# If ENV and ROLE are given, finds the latest instance which has backup AMI | |
# New instance settings can be overriden by OVERRIDES. | |
# Bugs: `aws ec2 get-launch-template-data` does not return 'CreditSpecification>CpuCredits' for t3. | |
# template overrides for run-instances | |
OVERRIDES = %[--placement Tenancy=default] | |
F main(env:Str, role:Str) { | |
tags = {'env': env, 'role': role} | |
log("Cloning ${tags}") | |
log("Looking for latest instance which has AMI") | |
instances = AWS2::Instance(tags).Arr().sort('LaunchTime') | |
not(instances) throws Error("No instances found with tags ${tags}") | |
instance = instances.reverse().first(F(i) { | |
log("Checking for AMI for instance ${i.InstanceId}") | |
AWS2::Image(OwnerId="self", Tags={'instance-id': i.InstanceId}) | |
}) | |
log("Will clone instance ${instance.InstanceId} tagged ${instance.Tags}") | |
main(instance.InstanceId) | |
} | |
F main(instance_id:Str) { | |
log("Cloning ${instance_id}") | |
log("Overrides: ${OVERRIDES}") | |
section "Get latest AMI" { | |
ami = AWS2::Image(OwnerId="self", Tags={'instance-id': instance_id}).latest().the_one() | |
ami_age = Time().Int() - Time(ami.CreationDate).Int() | |
log(" Found AMI '${ami.Name}' (${ami.ImageId}), ${ami_age / 3600} hours old") | |
} | |
section "Create Template" { | |
tmpl_source = ``aws ec2 get-launch-template-data --instance-id ${instance_id}``.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 = "${instance_id}-tmp-clone" | |
output_create=``aws ec2 create-launch-template --launch-template-name "${tmpl_name}" --launch-template-data ${tmpl_fix.encode_json()}`` | |
exit_hook.delete_template = { | |
$(aws ec2 delete-launch-template --launch-template-name "${tmpl_name}") | |
} | |
} | |
section "Run Instance" { | |
F tags_to_stupid(h:Hash) h.map(F(k, v) { | |
{"Key": k, "Value": v} | |
}) | |
relevant_tags = ami.Tags.filterk(/^i:/).mapk(X[2..null]) | |
tag_specs = [ | |
{ | |
"ResourceType": "instance" | |
"Tags": relevant_tags.tags_to_stupid() | |
} | |
{ | |
"ResourceType": "volume" | |
"Tags": relevant_tags.filterk(OneOf('proj', 'env', 'role')).tags_to_stupid() | |
} | |
] | |
$(log: aws ec2 run-instances --launch-template LaunchTemplateName=${tmpl_name},Version=1 --image-id ${ami.ImageId} $*OVERRIDES --tag-specifications ${tag_specs.encode_json()}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment