aws-ec2 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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