aws-ec2 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +10 -0
  4. data/README.md +19 -15
  5. data/docs/example/app/user-data/bootstrap.sh +0 -12
  6. data/lib/aws_ec2/cli.rb +8 -3
  7. data/lib/aws_ec2/core.rb +25 -4
  8. data/lib/aws_ec2/create.rb +19 -9
  9. data/lib/aws_ec2/help/upload.md +3 -2
  10. data/lib/aws_ec2/profile.rb +10 -1
  11. data/lib/aws_ec2/script.rb +19 -3
  12. data/lib/aws_ec2/script/compile.rb +2 -2
  13. data/lib/aws_ec2/script/compress.rb +1 -1
  14. data/lib/aws_ec2/script/templates/ami_creation.sh +12 -0
  15. data/lib/aws_ec2/script/templates/auto_terminate.sh +11 -0
  16. data/lib/aws_ec2/script/templates/auto_terminate_after_timeout.sh +5 -0
  17. data/lib/aws_ec2/script/templates/cloudwatch.sh +3 -0
  18. data/lib/aws_ec2/script/templates/extract_aws_ec2_scripts.sh +48 -0
  19. data/lib/aws_ec2/script/upload.rb +1 -1
  20. data/lib/aws_ec2/scripts/auto_terminate.sh +10 -91
  21. data/lib/aws_ec2/scripts/auto_terminate/after_timeout.sh +18 -0
  22. data/lib/aws_ec2/scripts/auto_terminate/functions.sh +128 -0
  23. data/lib/aws_ec2/scripts/auto_terminate/functions/amazonlinux2.sh +10 -0
  24. data/lib/aws_ec2/scripts/auto_terminate/functions/ubuntu.sh +11 -0
  25. data/lib/aws_ec2/scripts/auto_terminate/setup.sh +31 -0
  26. data/lib/aws_ec2/scripts/cloudwatch.sh +22 -0
  27. data/lib/aws_ec2/scripts/cloudwatch/configure.sh +74 -0
  28. data/lib/aws_ec2/scripts/cloudwatch/install.sh +4 -0
  29. data/lib/aws_ec2/scripts/cloudwatch/service.sh +19 -0
  30. data/lib/aws_ec2/scripts/shared/functions.sh +44 -0
  31. data/lib/aws_ec2/setting.rb +15 -4
  32. data/lib/aws_ec2/template/helper/core_helper.rb +46 -7
  33. data/lib/aws_ec2/template/helper/ssh_key_helper.rb +1 -1
  34. data/lib/aws_ec2/version.rb +1 -1
  35. data/spec/fixtures/demo_project/config/settings.yml +22 -0
  36. data/spec/lib/cli_spec.rb +0 -7
  37. data/spec/lib/params_spec.rb +71 -0
  38. metadata +21 -3
  39. data/lib/aws_ec2/scripts/ami_creation.sh +0 -35
@@ -18,7 +18,8 @@ module AwsEc2
18
18
  end
19
19
 
20
20
  all_envs = load_file(project_settings_path)
21
- @@data = all_envs[AwsEc2.env]
21
+ all_envs = merge_base(all_envs)
22
+ @@data = all_envs[AwsEc2.env] || all_envs["base"] || {}
22
23
  end
23
24
 
24
25
  private
@@ -27,13 +28,23 @@ module AwsEc2
27
28
 
28
29
  content = RenderMePretty.result(path)
29
30
  data = YAML.load(content)
30
- # ensure no nil values
31
- data.each do |key, value|
32
- data[key] = {} if value.nil?
31
+ # If key is is accidentally set to nil it screws up the merge_base later.
32
+ # So ensure that all keys with nil value are set to {}
33
+ data.each do |env, _setting|
34
+ data[env] ||= {}
33
35
  end
34
36
  data
35
37
  end
36
38
 
39
+ # automatically add base settings to the rest of the environments
40
+ def merge_base(all_envs)
41
+ base = all_envs["base"] || {}
42
+ all_envs.each do |env, settings|
43
+ all_envs[env] = base.merge(settings) unless env == "base"
44
+ end
45
+ all_envs
46
+ end
47
+
37
48
  def project_settings_path
38
49
  "#{AwsEc2.root}/config/settings.yml"
39
50
  end
@@ -2,6 +2,7 @@ require "base64"
2
2
  require "erb"
3
3
 
4
4
  module AwsEc2::Template::Helper::CoreHelper
5
+ # assuming user-data script is a bash script for simplicity for now
5
6
  def user_data(name, base64:true, layout:"default")
6
7
  # allow user to specify the path also
7
8
  if File.exist?(name)
@@ -12,7 +13,15 @@ module AwsEc2::Template::Helper::CoreHelper
12
13
  layout_path = layout_path(layout)
13
14
  path = "#{AwsEc2.root}/app/user-data/#{name}.sh"
14
15
  result = RenderMePretty.result(path, context: self, layout: layout_path)
15
- result = append_scripts(result)
16
+ # Must prepend and append scripts in user_data here because we need to
17
+ # encode the user_data script for valid yaml to load in the profile.
18
+ # Tried moving this logic to the params but that is too late and produces
19
+ # invalid yaml. Unless we want to encode and dedode twice.
20
+ scripts = [result]
21
+ scripts = prepend_scripts(scripts)
22
+ scripts = append_scripts(scripts)
23
+ divider = "\n############################## DIVIDER ##############################\n"
24
+ result = scripts.join(divider)
16
25
 
17
26
  # save the unencoded user-data script for easy debugging
18
27
  temp_path = "#{AwsEc2.root}/tmp/user-data.txt"
@@ -67,12 +76,42 @@ module AwsEc2::Template::Helper::CoreHelper
67
76
  end
68
77
 
69
78
  private
70
- def append_scripts(user_data)
71
- # assuming user-data script is a bash script for simplicity
72
- script = AwsEc2::Script.new(@options)
73
- user_data += script.auto_terminate if @options[:auto_terminate]
74
- user_data += script.create_ami if @options[:ami_name]
75
- user_data
79
+ # TODO: move script combining logic into class
80
+ def prepend_scripts(scripts)
81
+ scripts.unshift(script.cloudwatch) if @options[:cloudwatch]
82
+ scripts.unshift(script.auto_terminate_after_timeout) if @options[:auto_terminate]
83
+ add_setup_script(scripts, :prepend)
84
+ scripts
85
+ end
86
+
87
+ def append_scripts(scripts)
88
+ add_setup_script(scripts, :append)
89
+ scripts << script.auto_terminate if @options[:auto_terminate]
90
+ scripts << script.create_ami if @options[:ami_name]
91
+ scripts
92
+ end
93
+
94
+ def add_setup_script(scripts, how)
95
+ return if @already_setup
96
+ @already_setup = true
97
+
98
+ requires_setup = @options[:cloudwatch] ||
99
+ @options[:auto_terminate] ||
100
+ @options[:ami_name]
101
+
102
+ return unless requires_setup
103
+
104
+ if how == :prepend
105
+ scripts.unshift(script.extract_aws_ec2_scripts)
106
+ else
107
+ scripts << script.extract_aws_ec2_scripts
108
+ end
109
+
110
+ scripts
111
+ end
112
+
113
+ def script
114
+ @script ||= AwsEc2::Script.new(@options)
76
115
  end
77
116
 
78
117
  # Load custom helper methods from the project repo
@@ -13,7 +13,7 @@ chown #{user}:#{user} /home/#{user}/.ssh/authorized_keys
13
13
  SCRIPT
14
14
  else
15
15
  <<-SCRIPT
16
- # WARN: unable to find a ~/.ssh/id_rsa.pub locally on your machine. user: #{ENV}['USER']
16
+ # WARN: unable to find a ~/.ssh/id_rsa.pub locally on your machine. user: #{ENV['USER']}
17
17
  # Unable to automatically add the public key
18
18
  SCRIPT
19
19
  end
@@ -1,3 +1,3 @@
1
1
  module AwsEc2
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,22 @@
1
+ ---
2
+ # Settings control internal aws-ec2 behavior.
3
+ # Settings are different from the config files. The config files are meant to
4
+ # expose config variables that you can use in your ERB code.
5
+ # There are separate files to separate user defined variables and internal
6
+ # setting configs.
7
+ development:
8
+ # By setting s3_folder, aws-ec2 will automatically tarball and upload your scripts
9
+ # to set. You then can then use the extract_scripts helper method to download
10
+ # the scripts onto the server.
11
+ # s3_folder: mybucket/path/to/folder # simple string
12
+ # compile_clean: true # uncomment to clean
13
+ # extract_scripts:
14
+ # to: "/opt"
15
+ # as: "ec2-user"
16
+ # aws_profiles:
17
+ # - profile1
18
+
19
+ production:
20
+ # s3_folder: mybucket/folder
21
+ # aws_profiles:
22
+ # - profile2
@@ -1,10 +1,3 @@
1
- require "spec_helper"
2
-
3
- # to run specs with what"s remembered from vcr
4
- # $ rake
5
- #
6
- # to run specs with new fresh data from aws api calls
7
- # $ rake clean:vcr ; time rake
8
1
  describe AwsEc2::CLI do
9
2
  before(:all) do
10
3
  @args = "--noop"
@@ -0,0 +1,71 @@
1
+ describe AwsEc2::Create::Params do
2
+ let(:param) { AwsEc2::Create::Params.new(name: "myserver") }
3
+
4
+ context "completely empty" do
5
+ it '#upsert_name_tag!' do
6
+ params = {}
7
+ result = param.upsert_name_tag!(params)
8
+ # puts "params: #{params.inspect}" # uncomment to see and debug
9
+ expect(result).to eq(
10
+ {"tag_specifications"=>
11
+ [{"resource_type"=>"instance",
12
+ "tags"=>[{"key"=>"Name", "value"=>"myserver"}]}]}
13
+ )
14
+ end
15
+ end
16
+
17
+ context "empty tag_specifications" do
18
+ it '#upsert_name_tag!' do
19
+ params = {"tag_specifications" => []}
20
+ result = param.upsert_name_tag!(params)
21
+ # puts "params: #{params.inspect}" # uncomment to see and debug
22
+ expect(result).to eq(
23
+ {"tag_specifications"=>
24
+ [{"resource_type"=>"instance",
25
+ "tags"=>[{"key"=>"Name", "value"=>"myserver"}]}]}
26
+ )
27
+ end
28
+ end
29
+
30
+ context "contains 1 instance with name" do
31
+ it '#upsert_name_tag!' do
32
+ params = { "tag_specifications" =>
33
+ [{
34
+ "resource_type"=>"instance",
35
+ "tags"=> [{"key"=>"Name", "value"=>"override-myserver"} ]
36
+ }]
37
+ }
38
+ result = param.upsert_name_tag!(params)
39
+ # puts "params: #{params.inspect}" # uncomment to see and debug
40
+ expect(result).to eq(
41
+ {"tag_specifications"=>
42
+ [{"resource_type"=>"instance",
43
+ "tags"=>[{"key"=>"Name", "value"=>"override-myserver"}]}]}
44
+ )
45
+ end
46
+ end
47
+
48
+ context "contains 1 instance with non-name tag" do
49
+ it '#upsert_name_tag!' do
50
+ params = { "tag_specifications" =>
51
+ [{
52
+ "resource_type"=>"instance",
53
+ "tags"=> [{"key"=>"Os", "value"=>"amazonlinux"} ]
54
+ }]
55
+ }
56
+ result = param.upsert_name_tag!(params)
57
+ # puts "params: #{params.inspect}" # uncomment to see and debug
58
+ expect(result).to eq(
59
+ { "tag_specifications" =>
60
+ [{
61
+ "resource_type"=>"instance",
62
+ "tags"=> [
63
+ {"key"=>"Os", "value"=>"amazonlinux"},
64
+ {"key"=>"Name", "value"=>"myserver"},
65
+ ]
66
+ }]
67
+ }
68
+ )
69
+ end
70
+ end
71
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-ec2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-27 00:00:00.000000000 Z
11
+ date: 2018-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -262,9 +262,23 @@ files:
262
262
  - lib/aws_ec2/script.rb
263
263
  - lib/aws_ec2/script/compile.rb
264
264
  - lib/aws_ec2/script/compress.rb
265
+ - lib/aws_ec2/script/templates/ami_creation.sh
266
+ - lib/aws_ec2/script/templates/auto_terminate.sh
267
+ - lib/aws_ec2/script/templates/auto_terminate_after_timeout.sh
268
+ - lib/aws_ec2/script/templates/cloudwatch.sh
269
+ - lib/aws_ec2/script/templates/extract_aws_ec2_scripts.sh
265
270
  - lib/aws_ec2/script/upload.rb
266
- - lib/aws_ec2/scripts/ami_creation.sh
267
271
  - lib/aws_ec2/scripts/auto_terminate.sh
272
+ - lib/aws_ec2/scripts/auto_terminate/after_timeout.sh
273
+ - lib/aws_ec2/scripts/auto_terminate/functions.sh
274
+ - lib/aws_ec2/scripts/auto_terminate/functions/amazonlinux2.sh
275
+ - lib/aws_ec2/scripts/auto_terminate/functions/ubuntu.sh
276
+ - lib/aws_ec2/scripts/auto_terminate/setup.sh
277
+ - lib/aws_ec2/scripts/cloudwatch.sh
278
+ - lib/aws_ec2/scripts/cloudwatch/configure.sh
279
+ - lib/aws_ec2/scripts/cloudwatch/install.sh
280
+ - lib/aws_ec2/scripts/cloudwatch/service.sh
281
+ - lib/aws_ec2/scripts/shared/functions.sh
268
282
  - lib/aws_ec2/setting.rb
269
283
  - lib/aws_ec2/template.rb
270
284
  - lib/aws_ec2/template/context.rb
@@ -275,9 +289,11 @@ files:
275
289
  - lib/aws_ec2/template/helper/script_helper.rb
276
290
  - lib/aws_ec2/template/helper/ssh_key_helper.rb
277
291
  - lib/aws_ec2/version.rb
292
+ - spec/fixtures/demo_project/config/settings.yml
278
293
  - spec/fixtures/demo_project/config/test.yml
279
294
  - spec/fixtures/demo_project/profiles/default.yml
280
295
  - spec/lib/cli_spec.rb
296
+ - spec/lib/params_spec.rb
281
297
  - spec/spec_helper.rb
282
298
  homepage: https://github.com/tongueroo/aws-ec2
283
299
  licenses:
@@ -304,7 +320,9 @@ signing_key:
304
320
  specification_version: 4
305
321
  summary: Simple tool to create AWS ec2 instances
306
322
  test_files:
323
+ - spec/fixtures/demo_project/config/settings.yml
307
324
  - spec/fixtures/demo_project/config/test.yml
308
325
  - spec/fixtures/demo_project/profiles/default.yml
309
326
  - spec/lib/cli_spec.rb
327
+ - spec/lib/params_spec.rb
310
328
  - spec/spec_helper.rb
@@ -1,35 +0,0 @@
1
- #!/bin/bash -exu
2
- # The shebang line is here in case there's is currently an empty user-data script.
3
- # It wont hurt if already there.
4
- ######################################
5
- # ami_creation.sh: added to the end of user-data automatically.
6
- function configure_aws_cli() {
7
- local home_dir=$1
8
- # Configure aws cli in case it is not yet configured
9
- mkdir -p $home_dir/.aws
10
- if [ ! -f $home_dir/.aws/config ]; then
11
- cat >$home_dir/.aws/config <<EOL
12
- [default]
13
- region = <%= @region %>
14
- output = json
15
- EOL
16
- fi
17
- }
18
-
19
- configure_aws_cli /home/ec2-user
20
- configure_aws_cli /root
21
-
22
- echo "############################################" >> /var/log/user-data.log
23
- echo "# Logs above is from the original AMI baking at: $(date)" >> /var/log/user-data.log
24
- echo "# New logs below" >> /var/log/user-data.log
25
- echo "############################################" >> /var/log/user-data.log
26
-
27
- # Create AMI Bundle
28
- AMI_NAME="<%= @ami_name %>"
29
- INSTANCE_ID=$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)
30
- REGION=$(aws configure get region)
31
- # Note this will cause the instance to reboot. Not using the --no-reboot flag
32
- # to ensure consistent AMI creation.
33
- SOURCE_AMI_ID=$(wget -q -O - http://169.254.169.254/latest/meta-data/ami-id)
34
- echo $SOURCE_AMI_ID > /var/log/source-ami-id.txt
35
- aws ec2 create-image --name $AMI_NAME --instance-id $INSTANCE_ID --region $REGION