stemcell 0.5.0 → 0.6.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 +15 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +18 -0
  4. data/lib/stemcell/command_line.rb +2 -2
  5. data/lib/stemcell/errors.rb +3 -2
  6. data/lib/stemcell/metadata_source/chef_repository.rb +55 -0
  7. data/lib/stemcell/metadata_source/configuration.rb +77 -0
  8. data/lib/stemcell/metadata_source.rb +51 -98
  9. data/lib/stemcell/version.rb +1 -1
  10. data/lib/stemcell.rb +0 -2
  11. data/spec/fixtures/chef_repo/roles/unit-inherit-base.rb +20 -0
  12. data/spec/fixtures/chef_repo/roles/unit-inherit-both.rb +36 -0
  13. data/spec/fixtures/chef_repo/roles/unit-inherit-default.rb +21 -0
  14. data/spec/fixtures/chef_repo/roles/unit-inherit-none.rb +6 -0
  15. data/spec/fixtures/chef_repo/roles/unit-inherit-override.rb +21 -0
  16. data/spec/fixtures/chef_repo/roles/unit-simple-both.rb +29 -0
  17. data/spec/fixtures/chef_repo/roles/unit-simple-default.rb +16 -0
  18. data/spec/fixtures/chef_repo/roles/unit-simple-none.rb +2 -0
  19. data/spec/fixtures/chef_repo/roles/unit-simple-override.rb +16 -0
  20. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-inherit-both.json +16 -0
  21. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-inherit-default.json +14 -0
  22. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-inherit-none.json +11 -0
  23. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-inherit-override.json +14 -0
  24. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-simple-both.json +13 -0
  25. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-simple-default.json +11 -0
  26. data/spec/fixtures/chef_repo/roles-expected-metadata/unit-simple-override.json +11 -0
  27. data/spec/fixtures/chef_repo/stemcell-azs-missing.json +10 -0
  28. data/spec/fixtures/chef_repo/stemcell-backing-store-empty.json +9 -0
  29. data/spec/fixtures/chef_repo/stemcell-backing-store-missing.json +8 -0
  30. data/spec/fixtures/chef_repo/stemcell-defaults-missing.json +10 -0
  31. data/spec/fixtures/chef_repo/stemcell.json +13 -0
  32. data/spec/lib/stemcell/metadata_source/chef_repository_spec.rb +107 -0
  33. data/spec/lib/stemcell/metadata_source/configuration_spec.rb +117 -0
  34. data/spec/lib/stemcell/metadata_source_spec.rb +250 -0
  35. data/spec/spec_helper.rb +13 -0
  36. data/spec/support/fixture_helper.rb +14 -0
  37. metadata +60 -24
  38. data/lib/stemcell/utility/deep_merge.rb +0 -13
  39. data/lib/stemcell/utility.rb +0 -1
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YWQxNmQ0NDdkNGMzZmRlMzVhOTMzNzJjODFlMDIyZTFkZjUyY2RiNA==
5
+ data.tar.gz: !binary |-
6
+ Y2RmNDdjNDZjNzIxNDIyNWE1MWNlMDZmZWM3ZWYxZjA2NzVjYWI0Nw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NmRjOGQwOGVhMjFiZDZiNDVhZWQ3OGE2YTczOTU5MjhhOWNmZTdkYTIzYzYw
10
+ OGJmZGExMzM2YmRhMWQ0YTVjZTAzYjJmOTA2N2U2YTEyMGE1OTBmNGM1ODUz
11
+ YjU4N2EyMzFjNmE4ZDNjYTMwYTg1NGQ5MWNiOTRlNzUwZGQ0MTA=
12
+ data.tar.gz: !binary |-
13
+ OGY3NzRhYjY0ZTc1OGI2N2RmN2FlZWEwMGUxYmY1NjU0YWZmMjc0N2YyYWRi
14
+ ZjZmZTc1NGQ2OTRkYWNmMjUxM2JiOWRmZGRkNzg2ZGNlN2JkOTg5MjAyYzA4
15
+ MDI5YzQ4NzgxYmEzNmJlNjAzN2ZmNTExMTM1N2E5ZTU5NmQ3NDc=
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in stemcell.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'rspec', '~> 2.14.1'
8
+ gem 'rspec-instafail', '~> 0.2.4'
9
+ gem 'simplecov', :require => false
10
+ end
data/Gemfile.lock CHANGED
@@ -34,6 +34,7 @@ GEM
34
34
  rest-client (>= 1.0.4, < 1.7.0)
35
35
  yajl-ruby (~> 1.1)
36
36
  colored (1.2)
37
+ diff-lcs (1.2.5)
37
38
  erubis (2.7.0)
38
39
  highline (1.6.19)
39
40
  ipaddress (0.8.0)
@@ -45,6 +46,7 @@ GEM
45
46
  mixlib-config (1.1.2)
46
47
  mixlib-log (1.6.0)
47
48
  mixlib-shellout (1.1.0)
49
+ multi_json (1.8.2)
48
50
  net-ssh (2.7.0)
49
51
  net-ssh-gateway (1.2.0)
50
52
  net-ssh (>= 2.6.5)
@@ -62,6 +64,19 @@ GEM
62
64
  yajl-ruby
63
65
  rest-client (1.6.7)
64
66
  mime-types (>= 1.16)
67
+ rspec (2.14.1)
68
+ rspec-core (~> 2.14.0)
69
+ rspec-expectations (~> 2.14.0)
70
+ rspec-mocks (~> 2.14.0)
71
+ rspec-core (2.14.7)
72
+ rspec-expectations (2.14.4)
73
+ diff-lcs (>= 1.1.3, < 2.0)
74
+ rspec-instafail (0.2.4)
75
+ rspec-mocks (2.14.4)
76
+ simplecov (0.7.1)
77
+ multi_json (~> 1.0)
78
+ simplecov-html (~> 0.7.1)
79
+ simplecov-html (0.7.1)
65
80
  systemu (2.5.2)
66
81
  trollop (2.0)
67
82
  uuidtools (2.1.4)
@@ -71,4 +86,7 @@ PLATFORMS
71
86
  ruby
72
87
 
73
88
  DEPENDENCIES
89
+ rspec (~> 2.14.1)
90
+ rspec-instafail (~> 0.2.4)
91
+ simplecov
74
92
  stemcell!
@@ -70,12 +70,12 @@ module Stemcell
70
70
 
71
71
  def initialize_launcher
72
72
  @launcher = MetadataLauncher.new(:chef_root => chef_root)
73
- rescue NoTemplateError
73
+ rescue MissingMetadataConfigError
74
74
  puts "Couldn't find `stemcell.json` in the local chef repo.".red
75
75
  puts "You must specify the root of the local checkout of your chef " \
76
76
  "respository by using the --local-chef-root options or " \
77
77
  "setting the LOCAL_CHEF_ROOT environment variable."
78
- rescue TemplateParseError => e
78
+ rescue MetadataConfigParseError => e
79
79
  error "Couldn't parse the `stemcell.json` file: #{e.message}"
80
80
  end
81
81
 
@@ -2,8 +2,9 @@ module Stemcell
2
2
  # This is the class from which all stemcell errors descend.
3
3
  class Error < StandardError; end
4
4
 
5
- class NoTemplateError < Error; end
6
- class TemplateParseError < Error; end
5
+ class MissingMetadataConfigError < Error; end
6
+ class MetadataConfigParseError < Error; end
7
+
7
8
  class RoleExpansionError < Error; end
8
9
  class EmptyRoleError < Error; end
9
10
 
@@ -0,0 +1,55 @@
1
+ require 'chef'
2
+
3
+ module Stemcell
4
+ class MetadataSource
5
+
6
+ class ChefRepository
7
+ include Chef::Mixin::DeepMerge
8
+
9
+ attr_reader :chef_root
10
+
11
+ # Search for instance metadata in the following role attributes, with
12
+ # priority given to the keys at the head.
13
+ METADATA_ATTRIBUTES = [
14
+ :instance_metadata,
15
+ :stemcell
16
+ ]
17
+
18
+ def initialize(chef_root)
19
+ @chef_root = chef_root
20
+ if chef_root.nil?
21
+ raise ArgumentError, "You must specify a chef repository"
22
+ end
23
+
24
+ configure_chef
25
+ end
26
+
27
+ # This method will return nil if the role has no stemcell metdata.
28
+ def metadata_for_role(chef_role, chef_environment)
29
+ default_attrs, override_attrs = expand_role(chef_role, chef_environment)
30
+ merged_attrs = deep_merge!(override_attrs, default_attrs)
31
+ METADATA_ATTRIBUTES.inject(nil) { |r, key| r || merged_attrs[key] }
32
+ end
33
+
34
+ private
35
+
36
+ def configure_chef
37
+ Chef::Config[:cookbook_path] = File.join(chef_root, 'cookbooks')
38
+ Chef::Config[:data_bag_path] = File.join(chef_root, 'data_bags')
39
+ Chef::Config[:role_path] = File.join(chef_root, 'roles')
40
+ end
41
+
42
+ def expand_role(chef_role, chef_environment)
43
+ run_list = Chef::RunList.new
44
+ run_list << "role[#{chef_role}]"
45
+
46
+ expansion = run_list.expand(chef_environment, 'disk')
47
+ raise RoleExpansionError if expansion.errors?
48
+
49
+ [expansion.default_attrs, expansion.override_attrs]
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,77 @@
1
+ require 'json'
2
+
3
+ module Stemcell
4
+ class MetadataSource
5
+
6
+ class Configuration
7
+ attr_reader :config_path
8
+
9
+ attr_reader :all_options
10
+ attr_reader :default_options
11
+ attr_reader :backing_store_options
12
+ attr_reader :availability_zones
13
+
14
+ def initialize(config_path)
15
+ @config_path = config_path
16
+ if config_path.nil?
17
+ raise ArgumentError, "You must specify a configuration file"
18
+ end
19
+
20
+ read_configuration
21
+ validate_configutation
22
+ end
23
+
24
+ def options_for_backing_store(backing_store)
25
+ options = backing_store_options[backing_store]
26
+ raise UnknownBackingStoreError.new(backing_store) if options.nil?
27
+ options
28
+ end
29
+
30
+ def random_az_for_region(region)
31
+ (availability_zones[region] || []).sample
32
+ end
33
+
34
+ private
35
+
36
+ def read_configuration
37
+ begin
38
+ @all_options = JSON.parse(File.read(config_path))
39
+ rescue Errno::ENOENT
40
+ raise Stemcell::MissingMetadataConfigError
41
+ rescue => e
42
+ raise Stemcell::MetadataConfigParseError, e.message
43
+ end
44
+
45
+ @default_options = @all_options['defaults']
46
+ @backing_store_options = @all_options['backing_store']
47
+ @availability_zones = @all_options['availability_zones']
48
+ end
49
+
50
+ def validate_configutation
51
+ errors = []
52
+
53
+ if default_options.nil?
54
+ errors << "missing required section 'defaults'; " \
55
+ "should be a hash containing default launch options"
56
+ end
57
+
58
+ if backing_store_options.nil? || backing_store_options.empty?
59
+ errors << "missing or empty section 'backing_store'"
60
+ errors << "'backing_store' should be a hash from " \
61
+ "store type (like 'ebs') => hash of options for that store"
62
+ end
63
+
64
+ if availability_zones.nil?
65
+ errors << "missing or empty section 'availability_zones'"
66
+ errors << "'availability_zones' should be a hash from " \
67
+ "region name => list of allowed zones in that region"
68
+ end
69
+
70
+ unless errors.empty?
71
+ raise Stemcell::MetadataConfigParseError, errors.join("; ")
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -1,10 +1,18 @@
1
- require 'chef'
2
- require 'json'
1
+ require 'stemcell/metadata_source/chef_repository'
2
+ require 'stemcell/metadata_source/configuration'
3
3
 
4
4
  module Stemcell
5
5
  class MetadataSource
6
+ include Chef::Mixin::DeepMerge
7
+
6
8
  attr_reader :chef_root
7
- attr_reader :default_options
9
+ attr_reader :config_filename
10
+
11
+ attr_reader :config
12
+ attr_reader :chef_repo
13
+
14
+ DEFAULT_CONFIG_FILENAME = 'stemcell.json'
15
+ DEFAULT_BACKING_STORE = 'instance_store'
8
16
 
9
17
  DEFAULT_OPTIONS = {
10
18
  'chef_environment' => 'production',
@@ -14,23 +22,23 @@ module Stemcell
14
22
  'instance_domain_name' => '',
15
23
  }
16
24
 
17
- # Search for instance metadata in the following role attributes, with
18
- # priority given to the keys at the head.
19
- METADATA_ATTRIBUTES = [
20
- :instance_metadata,
21
- :stemcell
22
- ]
23
-
24
- def initialize(chef_root)
25
+ def initialize(chef_root, config_filename=DEFAULT_CONFIG_FILENAME)
25
26
  @chef_root = chef_root
27
+ @config_filename = config_filename
26
28
 
27
- raise ArgumentError, "You must specify a chef root" unless chef_root
29
+ if chef_root.nil?
30
+ raise ArgumentError, "You must specify a chef repository"
31
+ end
32
+ if config_filename.nil?
33
+ raise ArgumentError, "You must specify a configuration file"
34
+ end
28
35
 
29
- template_options = read_template
30
- @default_options = DEFAULT_OPTIONS.merge(template_options['defaults'])
36
+ @config = Configuration.new(File.join(chef_root, config_filename))
37
+ @chef_repo = ChefRepository.new(chef_root)
38
+ end
31
39
 
32
- @all_backing_store_options = template_options['backing_store']
33
- @all_azs_by_region = template_options['availability_zones']
40
+ def default_options
41
+ DEFAULT_OPTIONS.merge(config.default_options)
34
42
  end
35
43
 
36
44
  def expand_role(role, environment, override_options={}, options={})
@@ -38,104 +46,49 @@ module Stemcell
38
46
  raise ArgumentError, "Missing chef environment" unless environment
39
47
  allow_empty_roles = options.fetch(:allow_empty_roles, false)
40
48
 
41
- role_options = expand_role_options(role, environment)
49
+ # Step 1: Expand the role metadata
50
+
51
+ role_options = chef_repo.metadata_for_role(role, environment)
42
52
  role_empty = role_options.nil? || role_options.empty?
43
53
 
44
54
  raise EmptyRoleError if !allow_empty_roles && role_empty
45
55
 
46
- backing_store_options =
47
- expand_backing_store_options(
48
- default_options,
49
- role_options,
50
- override_options
51
- )
52
-
53
- # Merge all the options together in priority order
54
- merged_options = default_options.dup
55
- merged_options.deep_merge!(backing_store_options)
56
- merged_options.deep_merge!(role_options) if role_options
57
- merged_options.deep_merge!(override_options)
58
-
59
- # Add the AZ if not specified
60
- if (region = merged_options['region'])
61
- merged_options['availability_zone'] ||= random_az_in_region(region)
62
- end
56
+ # Step 2: Determine the backing store from available options.
63
57
 
64
- # The chef environment and role used to expand the runlist takes
65
- # priority over all other options.
66
- merged_options['chef_environment'] = environment
67
- merged_options['chef_role'] = role
58
+ # This is determined distinctly from the merge sequence below because
59
+ # the backing store options must be available to the operation.
68
60
 
69
- merged_options
70
- end
61
+ backing_store = override_options['backing_store']
62
+ backing_store ||= role_options.to_hash['backing_store'] if role_options
63
+ backing_store ||= config.default_options['backing_store']
64
+ backing_store ||= DEFAULT_BACKING_STORE
71
65
 
72
- private
66
+ # Step 3: Retrieve the backing store options from the defaults.
73
67
 
74
- def read_template
75
- begin
76
- template_path = File.join(chef_root, 'stemcell.json')
77
- template_options = JSON.parse(IO.read(template_path))
78
- rescue Errno::ENOENT
79
- raise NoTemplateError
80
- rescue => e
81
- raise TemplateParseError, e.message
82
- end
68
+ backing_store_options = config.options_for_backing_store(backing_store)
69
+ backing_store_options['backing_store'] = backing_store
83
70
 
84
- errors = []
85
- unless template_options.include?('defaults')
86
- errors << 'missing required section "defaults"; should be a hash containing default launch options'
87
- end
71
+ # Step 4: Merge the options together in priority order.
88
72
 
89
- if template_options['availability_zones'].nil?
90
- errors << 'missing or empty section "availability zones"'
91
- errors << '"availability_zones" should be a hash from region name => list of allowed zones in that region'
92
- end
73
+ merged_options = DEFAULT_OPTIONS.dup
74
+ merged_options.merge!(config.default_options)
75
+ merged_options.merge!(backing_store_options)
76
+ merged_options.merge!(role_options.to_hash) if role_options
77
+ merged_options.merge!(override_options)
93
78
 
94
- if template_options['backing_store'].nil? or template_options['backing_store'].empty?
95
- errors << 'missing or empty section "backing_store"'
96
- errors << '"backing_store" should be a hash from store type (like "ebs") => hash of options for that store'
97
- end
79
+ # Step 5: If no availability zone was specified, select one at random.
98
80
 
99
- unless errors.empty?
100
- raise TemplateParseError, errors.join("; ")
81
+ if merged_options['availability_zone'].nil? && merged_options['region']
82
+ merged_options['availability_zone'] ||=
83
+ config.random_az_for_region(merged_options['region'])
101
84
  end
102
85
 
103
- return template_options
104
- end
105
-
106
- def expand_role_options(chef_role, chef_environment)
107
- Chef::Config[:role_path] = File.join(chef_root, 'roles')
108
- Chef::Config[:data_bag_path] = File.join(chef_root, 'data_bags')
109
-
110
- run_list = Chef::RunList.new
111
- run_list << "role[#{chef_role}]"
112
-
113
- expansion = run_list.expand(chef_environment, 'disk')
114
- raise RoleExpansionError if expansion.errors?
115
-
116
- default_attrs = expansion.default_attrs
117
- override_attrs = expansion.override_attrs
86
+ # Step 6: Mandate that the environment and role were as specified.
118
87
 
119
- merged_attrs = default_attrs.merge(override_attrs)
120
- METADATA_ATTRIBUTES.inject(nil) { |r, key| r || merged_attrs[key] }
121
- end
122
-
123
- def expand_backing_store_options(default_opts, role_opts, override_opts)
124
- backing_store = override_opts['backing_store']
125
- backing_store ||= role_opts.to_hash['backing_store'] if role_opts
126
- backing_store ||= default_opts['backing_store']
127
- backing_store ||= 'instance_store'
128
-
129
- backing_store_options = @all_backing_store_options[backing_store]
130
- if backing_store_options.nil?
131
- raise Stemcell::UnknownBackingStoreError.new(backing_store)
132
- end
133
- backing_store_options
134
- end
88
+ merged_options['chef_environment'] = environment
89
+ merged_options['chef_role'] = role
135
90
 
136
- def random_az_in_region(region)
137
- possible_azs = @all_azs_by_region[region] || []
138
- possible_azs.sample
91
+ merged_options
139
92
  end
140
93
  end
141
94
  end
@@ -1,3 +1,3 @@
1
1
  module Stemcell
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/stemcell.rb CHANGED
@@ -1,6 +1,4 @@
1
- require 'stemcell/utility'
2
1
  require 'stemcell/errors'
3
-
4
2
  require 'stemcell/command_line'
5
3
  require 'stemcell/option_parser'
6
4
  require 'stemcell/launcher'
@@ -0,0 +1,20 @@
1
+ name 'unit-inherit-base'
2
+ description 'unit-inherit-base'
3
+
4
+ default_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'm1.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'base',
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_base',
13
+ 'tag2' => 'tag2_value',
14
+ },
15
+ },
16
+ })
17
+
18
+ run_list(
19
+ "role[unit-inherit-base]",
20
+ )
@@ -0,0 +1,36 @@
1
+ name 'unit-inherit-both'
2
+ description 'unit-inherit-both'
3
+
4
+ default_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'c1.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'default',
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_default',
13
+ 'tag3' => 'tag3_value_default',
14
+ 'tag4' => 'tag4_value',
15
+ },
16
+ },
17
+ })
18
+
19
+ override_attributes({
20
+ 'instance_metadata' => {
21
+ 'instance_type' => 'm3.xlarge',
22
+ 'security_groups' => [
23
+ 'all',
24
+ 'override',
25
+ ],
26
+ 'tags' => {
27
+ 'tag1' => 'tag1_value_override',
28
+ 'tag3' => 'tag3_value_override',
29
+ 'tag5' => 'tag5_value',
30
+ },
31
+ },
32
+ })
33
+
34
+ run_list(
35
+ "role[unit-inherit-base]",
36
+ )
@@ -0,0 +1,21 @@
1
+ name 'unit-inherit-default'
2
+ description 'unit-inherit-default'
3
+
4
+ default_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'c1.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'default',
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_default',
13
+ 'tag3' => 'tag3_value_default',
14
+ 'tag4' => 'tag4_value',
15
+ },
16
+ },
17
+ })
18
+
19
+ run_list(
20
+ "role[unit-inherit-base]",
21
+ )
@@ -0,0 +1,6 @@
1
+ name 'unit-inherit-none'
2
+ description 'unit-inherit-none'
3
+
4
+ run_list(
5
+ "role[unit-inherit-base]",
6
+ )
@@ -0,0 +1,21 @@
1
+ name 'unit-inherit-override'
2
+ description 'unit-inherit-override'
3
+
4
+ override_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'm3.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'override',
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_override',
13
+ 'tag3' => 'tag3_value_override',
14
+ 'tag5' => 'tag5_value',
15
+ },
16
+ },
17
+ })
18
+
19
+ run_list(
20
+ "role[unit-inherit-base]",
21
+ )
@@ -0,0 +1,29 @@
1
+ name 'unit-simple-both'
2
+ description 'unit-simple-both'
3
+
4
+ default_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'c1.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'default'
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_default',
13
+ 'tag2' => 'tag2_value',
14
+ },
15
+ },
16
+ })
17
+
18
+ override_attributes({
19
+ 'instance_metadata' => {
20
+ 'instance_type' => 'm3.xlarge',
21
+ 'security_groups' => [
22
+ 'override'
23
+ ],
24
+ 'tags' => {
25
+ 'tag1' => 'tag1_value_override',
26
+ 'tag3' => 'tag3_value',
27
+ },
28
+ },
29
+ })
@@ -0,0 +1,16 @@
1
+ name 'unit-simple-default'
2
+ description 'unit-simple-default'
3
+
4
+ default_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'c1.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'default'
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_default',
13
+ 'tag2' => 'tag2_value',
14
+ },
15
+ },
16
+ })
@@ -0,0 +1,2 @@
1
+ name 'unit-simple-none'
2
+ description 'unit-simple-none'
@@ -0,0 +1,16 @@
1
+ name 'unit-simple-override'
2
+ description 'unit-simple-override'
3
+
4
+ override_attributes({
5
+ 'instance_metadata' => {
6
+ 'instance_type' => 'm3.xlarge',
7
+ 'security_groups' => [
8
+ 'all',
9
+ 'override'
10
+ ],
11
+ 'tags' => {
12
+ 'tag1' => 'tag1_value_override',
13
+ 'tag3' => 'tag3_value',
14
+ },
15
+ },
16
+ })
@@ -0,0 +1,16 @@
1
+ {
2
+ "instance_type": "m3.xlarge",
3
+ "security_groups": [
4
+ "all",
5
+ "base",
6
+ "default",
7
+ "override"
8
+ ],
9
+ "tags": {
10
+ "tag1": "tag1_value_override",
11
+ "tag2": "tag2_value",
12
+ "tag3": "tag3_value_override",
13
+ "tag4": "tag4_value",
14
+ "tag5": "tag5_value"
15
+ }
16
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "instance_type": "c1.xlarge",
3
+ "security_groups": [
4
+ "all",
5
+ "base",
6
+ "default"
7
+ ],
8
+ "tags": {
9
+ "tag1": "tag1_value_default",
10
+ "tag2": "tag2_value",
11
+ "tag3": "tag3_value_default",
12
+ "tag4": "tag4_value"
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "instance_type": "m1.xlarge",
3
+ "security_groups": [
4
+ "all",
5
+ "base"
6
+ ],
7
+ "tags": {
8
+ "tag1": "tag1_value_base",
9
+ "tag2": "tag2_value"
10
+ }
11
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "instance_type": "m3.xlarge",
3
+ "security_groups": [
4
+ "all",
5
+ "base",
6
+ "override"
7
+ ],
8
+ "tags": {
9
+ "tag1": "tag1_value_override",
10
+ "tag2": "tag2_value",
11
+ "tag3": "tag3_value_override",
12
+ "tag5": "tag5_value"
13
+ }
14
+ }