Class: AwsEc2::Create

Inherits:
Base
  • Object
show all
Includes:
AwsService, ErrorMessages
Defined in:
lib/aws_ec2/create.rb,
lib/aws_ec2/create/params.rb,
lib/aws_ec2/create/error_messages.rb

Defined Under Namespace

Modules: ErrorMessages Classes: Params

Constant Summary

Constants inherited from Base

Base::BUILD_ROOT, Base::SCRIPTS_INFO_PATH

Instance Method Summary collapse

Methods included from ErrorMessages

#handle_ec2_service_error!, #invalid_group_not_found, #invalid_parameter_combination, #invalid_subnet_id_not_found, #map_exception_to_method, #print_error_message

Methods included from AwsService

#ec2

Methods inherited from Base

#derandomize, #initialize, #randomize

Constructor Details

This class inherits a constructor from AwsEc2::Base

Instance Method Details

#add_to_clipboard(text) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/aws_ec2/create.rb', line 112

def add_to_clipboard(text)
  return unless RUBY_PLATFORM =~ /darwin/
  return unless system("type pbcopy > /dev/null")

  system(%[echo "#{text}" | pbcopy])
  puts "Pro tip: The CloudWatch Console Link has been added to your copy-and-paste clipboard."
end

#display_cloudwatch_info(instance_id) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/aws_ec2/create.rb', line 90

def display_cloudwatch_info(instance_id)
  return unless @options[:cloudwatch]

  region = get_region
  stream = "#{instance_id}/var/log/cloud-init-output.log"
  url = "https://#{region}.console.aws.amazon.com/cloudwatch/home?region=#{region}#logEventViewer:group=ec2;stream=#{stream}"
  cw_init_log = "cw tail -f ec2 #{stream}"
  puts "To view instance's cloudwatch logs visit:"
  puts "  #{url}"

  puts "  #{cw_init_log}" if ENV['AWS_EC2_CW']
  if ENV['AWS_EC2_CW'] && @options[:auto_terminate]
    cw_terminate_log = "cw tail -f ec2 #{instance_id}/var/log/auto-terminate.log"
    puts "  #{cw_terminate_log}"
  end

  puts "Note: It takes a little time for the instance to launch and report logs."

  paste_command = ENV['AWS_EC2_CW'] ? cw_init_log : url
  add_to_clipboard(paste_command)
end

#display_ec2_infoObject



62
63
64
65
66
67
# File 'lib/aws_ec2/create.rb', line 62

def display_ec2_info
  puts "Using the following parameters:"
  pretty_display(params)

  display_launch_template
end

#display_launch_templateObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/aws_ec2/create.rb', line 69

def display_launch_template
  launch_template = params[:launch_template]
  return unless launch_template

  resp = ec2.describe_launch_template_versions(
    launch_template_id: launch_template[:launch_template_id],
    launch_template_name: launch_template[:launch_template_name],
  )
  versions = resp.launch_template_versions
  launch_template_data = {} # combined launch_template_data
  versions.sort_by { |v| v[:version_number] }.each do |v|
    launch_template_data.merge!(v[:launch_template_data])
  end
  puts "launch template data (versions combined):"
  pretty_display(launch_template_data)
rescue Aws::EC2::Errors::InvalidLaunchTemplateNameNotFoundException => e
  puts "ERROR: The specified launched template #{launch_template.inspect} was not found."
  puts "Please double check that it exists."
  exit
end

#display_spot_info(instance_id) ⇒ Object



54
55
56
57
58
59
60
# File 'lib/aws_ec2/create.rb', line 54

def display_spot_info(instance_id)
  resp = ec2.describe_instances(instance_ids: [instance_id])
  spot_id = resp.reservations.first.instances.first.spot_instance_request_id
  return unless spot_id

  puts "Spot instance request id: #{spot_id}"
end

#get_regionObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/aws_ec2/create.rb', line 120

def get_region
  # Highest precedence: AWS_EC2_REGION env variable. Only really used here.
  if ENV['AWS_EC2_REGION']
    return ENV['AWS_EC2_REGION']
  end

  # Pretty high in precedence: AWS_PROFILE and ~/.aws/config and
  aws_found = system("type aws > /dev/null")
  if aws_found
    region = `aws configure get region`.strip
    return region
  end

  # Assumes instance same region as the calling ec2 instance.
  # It is possible for curl not to be installed.
  curl_found = system("type curl > /dev/null")
  if curl_found
    region = `curl --connect-timeout 3  -s 169.254.169.254/latest/meta-data/placement/availability-zone | sed s'/.$//'`
    return region unless region == ''
  end

  return 'us-east-1' # fallback default
end

#paramsObject

params are main derived from profile files



50
51
52
# File 'lib/aws_ec2/create.rb', line 50

def params
  @params ||= Params.new(@options).generate
end

#pretty_display(data) ⇒ Object



144
145
146
147
148
149
150
151
152
153
# File 'lib/aws_ec2/create.rb', line 144

def pretty_display(data)
  data = data.deep_stringify_keys

  if data["user_data"]
    message = "base64-encoded: cat tmp/user-data.txt to view"
    data["user_data"] = message
  end

  puts YAML.dump(data)
end

#runObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/aws_ec2/create.rb', line 12

def run
  Profile.new(@options).check!

  Hook.run(:before_run_instances, @options)
  sync_scripts_to_s3

  puts "Creating EC2 instance #{@name.colorize(:green)}"
  display_ec2_info
  if @options[:noop]
    puts "NOOP mode enabled. EC2 instance not created."
    return
  end
  resp = run_instances(params)
  instance_id = resp.instances.first.instance_id
  display_spot_info(instance_id)
  puts "EC2 instance #{@name} created: #{instance_id} 🎉"
  puts "Visit https://console.aws.amazon.com/ec2/home to check on the status"
  display_cloudwatch_info(instance_id)
end

#run_instances(params) ⇒ Object



32
33
34
35
36
# File 'lib/aws_ec2/create.rb', line 32

def run_instances(params)
  ec2.run_instances(params)
rescue Aws::EC2::Errors::ServiceError => e
  handle_ec2_service_error!(e)
end

#sync_scripts_to_s3Object

Configured by config/settings.yml. Example: config/settings.yml:

development:
  s3_folder: my-bucket/folder


43
44
45
46
47
# File 'lib/aws_ec2/create.rb', line 43

def sync_scripts_to_s3
  if AwsEc2.settings["s3_folder"]
    Script::Upload.new(@options).run
  end
end