aws-cfn-dsl 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTRkZGM3ZjljMDFlZDk5NjFkNGNmNjRlYzYwM2ExNTNlNGRhMjM2NQ==
4
+ OTVjY2UxNTJiYmQyZjgzYmQ2M2NhYzljZDE2NGRkMWU3ZGY3YzBjZA==
5
5
  data.tar.gz: !binary |-
6
- MDhjZTc2YzRhMmRhMTU2ODg3OGQxZDhmMDU0ZmM4Yzc2MzAzYWRhNA==
6
+ NTdkNGVhNWQ5NzRhMTVmNjA3ZTA4Y2QzOGZhOWM3N2IxYTc3ODk1OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDIyMmZkNDQ1ZDFjNWNmZjI0NzEzNTI0MDJhZjIwOTcwZDMyMTkwNjU3MWU2
10
- MzBlNDAwNjUxZjg0ZjlhODhjMGI2ZGI3NzA2ODAzZjkyYmExZjc2ODFiZTM0
11
- ZjRjOGRkYTcwYjBjNzY5NjRjYmUyNWIzOTg2NjExOGM4ZjhhNzI=
9
+ OTYzNDdmODQ2ODNkZTUxMjMzZDExYzU0ZTM4M2UwM2VjZjQ5YzVkNGM3NDk2
10
+ ZTc2ZTBhZjc4MTU3OGY3ODlkYzMzOWMzYmMwM2U1Yjc1MGZlZmVhYTVmN2Vm
11
+ MTMxYTI3MWM3MDMzYWVkYjllNTRkZWEyOGQ4MjRjMGQ5MWEzYTk=
12
12
  data.tar.gz: !binary |-
13
- ZTI1MmVkZWQzODgwZWVjMTUzMDJmMTcwMmVhZGZiOTRmY2Y0OWEwOWVlYzk0
14
- ZWJhNzQxYWIxMDkwNDAzMGEzYTU2YzBlMDU1ODhiYzk4YmU2OGYwNzdhMzA3
15
- MzVkNWQzYTYxZDlkNWVlOGEyMzNiOGU2MDE4Y2ZkMjE4YmRhOTc=
13
+ NzFjZjgyNmJlNzcxOTMwNzUwZTk4NmMyZTg3NDRiM2JiNjQ3ZmQzNDM3MmEz
14
+ NGJmNWYyZWI0NDhiYjBmZGJiOGY5NDMyMTE0YTNlNmQ1MjNlODZmMTU0YTBm
15
+ NWMxMDMwYTQ3MmQ5NGY0ZmViOGUwZDZjODdhMTJiMDcwMzYwYTY=
data/Gemfile CHANGED
@@ -7,7 +7,6 @@ gem 'cloudformation-ruby-dsl', :path => '../cloudformation-ruby-dsl', :group =>
7
7
 
8
8
  gem 'dldinternet-mixlib-logging', :path => '../dldinternet-mixlib-logging', :group => :development
9
9
  gem 'dldinternet-mixlib-cli', :path => '../dldinternet-mixlib-cli', :group => :development
10
- gem 'aws-cfn-dsl', :path => '../aws-cfn-dsl', :group => :development
11
10
  gem 'aws-cfn-decompiler', :path => '../aws-cfn-decompiler', :group => :development
12
11
  gem 'aws-cfn-compiler', :path => '../aws-cfn-compiler', :group => :development
13
12
  gem 'aws-cfn-yats', :path => '../aws-cfn-yats', :group => :development
@@ -10,23 +10,7 @@
10
10
  <orderEntry type="sourceFolder" forTests="false" />
11
11
  <orderEntry type="module" module-name="aws-cfn-compiler" />
12
12
  <orderEntry type="module" module-name="aws-cfn-decompiler" />
13
- <orderEntry type="module-library">
14
- <library name="aws-cfn-stacker (v[path], /Users/cdelange/Dropbox/DLDInternet/ws/gems-ws/aws-cfn-stacker) [path][gem]">
15
- <CLASSES>
16
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/bin" />
17
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/lib" />
18
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/pkg" />
19
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/.idea" />
20
- </CLASSES>
21
- <JAVADOC />
22
- <SOURCES>
23
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/bin" />
24
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/lib" />
25
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/pkg" />
26
- <root url="file://$MODULE_DIR$/../aws-cfn-stacker/.idea" />
27
- </SOURCES>
28
- </library>
29
- </orderEntry>
13
+ <orderEntry type="module" module-name="aws-cfn-stacker" />
30
14
  <orderEntry type="module" module-name="aws-cfn-yats" />
31
15
  <orderEntry type="module" module-name="cloudformation-ruby-dsl" />
32
16
  <orderEntry type="module-library">
@@ -1,4 +1,3 @@
1
- require "aws/cfn/decompiler"
2
1
  require "aws/cfn/dsl/fncall"
3
2
 
4
3
  require 'ap'
@@ -44,11 +43,41 @@ module Aws
44
43
 
45
44
  end
46
45
 
47
- def save(path=nil,parts=@items)
48
- pprint(simplify(parts))
46
+ def save_dsl(path=nil,parts=@items)
47
+ pprint(simplify(parts,true))
48
+ @logger.step "*** DSL generated ***"
49
49
  end
50
50
 
51
- def simplify(val)
51
+ def load_template(file=nil)
52
+ if file
53
+ logStep "Loading #{file}"
54
+ begin
55
+ abs = File.absolute_path(File.expand_path(file))
56
+ unless File.exists?(abs) or @opts[:output].nil?
57
+ abs = File.absolute_path(File.expand_path(File.join(@opts[:output],file)))
58
+ end
59
+ rescue
60
+ # pass
61
+ end
62
+ if File.exists?(abs)
63
+ case File.extname(File.basename(abs)).downcase
64
+ when /json|js/
65
+ @items = JSON.parse(File.read(abs))
66
+ when /yaml|yml/
67
+ @items = YAML.load(File.read(abs))
68
+ else
69
+ abort! "Unsupported file type for specification: #{file}"
70
+ end
71
+ else
72
+ abort! "Unable to open template: #{abs}"
73
+ end
74
+ end
75
+ end
76
+
77
+ protected
78
+
79
+ def simplify(val,start=false)
80
+ logStep "Simplify a block ..." if start
52
81
  if val.is_a?(Hash)
53
82
  val = Hash[val.map { |k,v| [k, simplify(v)] }]
54
83
  if val.length != 1
@@ -93,6 +122,7 @@ module Aws
93
122
  end
94
123
 
95
124
  def pprint(val)
125
+ logStep "Pretty print ..."
96
126
  case detect_type(val)
97
127
  when :template
98
128
  pprint_cfn_template(val)
@@ -109,7 +139,10 @@ module Aws
109
139
  end
110
140
  end
111
141
 
112
- protected
142
+ def module_name(parts=-1)
143
+ name = self.class.to_s.split("::")
144
+ name[0..parts-1].join('::')
145
+ end
113
146
 
114
147
  def abort!(msg=nil,rc=1)
115
148
  @logger.error msg if msg
@@ -153,59 +186,72 @@ module Aws
153
186
  end
154
187
 
155
188
  def pprint_cfn_template(tpl)
156
- open_output('',File.basename(@opts[:template].gsub(%r'\.(json|yaml|rb)'i,'')))
157
- writeln "#!/usr/bin/env ruby"
158
- writeln
159
- if @opts[:output]
160
- writeln "$:.unshift(File.dirname(__FILE__))"
161
- # noinspection RubyExpressionInStringInspection
162
- writeln '$:.unshift File.absolute_path("#{File.dirname(__FILE__)}/../lib")'
163
- end
164
- writeln "require 'bundler/setup'"
165
- writeln "require 'aws/cfn/dsl/template'"
166
- #writeln "require 'cloudformation-ruby-dsl/spotprice'"
167
- # writeln "require 'cloudformation-ruby-dsl/table'"
168
- writeln
169
- writeln "template do"
170
- writeln
171
- tpl.each do |section, v|
172
- case section
173
- when 'Parameters'
174
- when 'Mappings'
175
- when 'Resources'
176
- when 'Outputs'
177
- else
178
- write " value #{fmt_key(section)} => "
179
- pprint_value v, ' '
180
- writeln
181
- writeln
189
+ file = File.basename(@opts[:template]).gsub(%r'\.(json|yaml|js|yaml)$'i, '.rb')
190
+ # noinspection RubyParenthesesAroundConditionInspection
191
+ if (iam = open_output('', file.gsub(%r'\.(json|yaml|js|yml|rb)'i, '')))
192
+ logStep "Saving #{file}"
193
+ writeln "#!/usr/bin/env ruby"
194
+ print_maintainer('')
195
+ writeln
196
+ if @opts[:output]
197
+ writeln "$:.unshift(File.dirname(__FILE__))"
198
+ # noinspection RubyExpressionInStringInspection
199
+ writeln '$:.unshift File.absolute_path("#{File.dirname(__FILE__)}/../lib")'
182
200
  end
201
+ writeln "require 'bundler/setup'"
202
+ writeln "require 'aws/cfn/dsl/template'"
203
+ #writeln "require 'cloudformation-ruby-dsl/spotprice'"
204
+ #writeln "require 'cloudformation-ruby-dsl/table'"
205
+ writeln
206
+ writeln "template do"
207
+ writeln
208
+ tpl.each do |section, v|
209
+ case section
210
+ when 'Parameters'
211
+ when 'Mappings'
212
+ when 'Resources'
213
+ when 'Outputs'
214
+ else
215
+ write " value #{fmt_key(section)} => "
216
+ pprint_value v, ' '
217
+ writeln
218
+ writeln
219
+ end
220
+ end
221
+ else
222
+ @logger.warn "Not overwriting template: '#{file}'"
183
223
  end
184
224
  %w(Mappings Parameters Resources Outputs).each do |section|
185
- writeln " # #{section}"
225
+ writeln " # #{section}" if iam
186
226
  v = tpl[section]
187
227
  case section
188
228
  when 'Parameters'
189
- v.each { |name, options| pprint_cfn_section 'parameter', name, options, 'Parameters' }
229
+ v.each { |name, options| pprint_cfn_section 'parameter', name, options, 'Parameters', iam }
190
230
  when 'Mappings'
191
- v.each { |name, options| pprint_cfn_section 'mapping', name, options, 'Mappings' }
231
+ v.each { |name, options| pprint_cfn_section 'mapping', name, options, 'Mappings', iam }
192
232
  when 'Resources'
193
- v.each { |name, options| pprint_cfn_resource name, options }
233
+ v.each { |name, options| pprint_cfn_resource name, options, iam }
194
234
  when 'Outputs'
195
- v.each { |name, options| pprint_cfn_section 'output', name, options, 'Outputs' }
235
+ v.each { |name, options| pprint_cfn_section 'output', name, options, 'Outputs', iam }
196
236
  else
197
- raise "Internal Error: Unexpected section '#{section}'"
237
+ abort! "Internal Error: Unexpected section '#{section}'"
198
238
  end
199
- writeln
239
+ writeln if iam
200
240
  end
201
- writeln "end.exec!"
241
+ writeln "end.exec!" if iam
202
242
  end
203
243
 
204
244
  def open_output(subdir,name)
205
245
  if @opts[:output]
206
246
  file = rb_file(subdir, name)
207
-
208
- @output.unshift File.open(file, 'w')
247
+ if i_am_maintainer(file)
248
+ @output.unshift File.open(file, 'w')
249
+ true
250
+ else
251
+ false
252
+ end
253
+ else
254
+ true
209
255
  end
210
256
  end
211
257
 
@@ -233,43 +279,104 @@ module Aws
233
279
  end
234
280
  end
235
281
 
236
- def pprint_cfn_section(section, name, options, subdir)
237
- open_output(subdir,name)
238
- write " #{section} #{fmt_string(name)}"
239
- indent = ' ' + (' ' * section.length) + ' '
240
- options.each do |k, v|
241
- writeln ","
242
- write indent, fmt_key(k), " => "
243
- pprint_value v, indent
282
+ def maintainer(parts=-1)
283
+ "maintainer: #{module_name parts}"
284
+ end
285
+
286
+ def maintainer_comment(indent=' ')
287
+ "#{indent}# WARNING: This code is generated. Your changes may be overwritten!\n" +
288
+ "#{indent}# Remove this message and/or set the 'maintainer: <author name>' when you need your changes to survive.\n" +
289
+ "#{indent}# Abscence of the 'maintainer: ' will be considered conscent to overwrite.\n" +
290
+ "#{indent}# #{maintainer 3}\n" +
291
+ "#\n"
292
+ end
293
+
294
+ def print_maintainer(indent=' ')
295
+ writeln maintainer_comment(indent)
296
+ end
297
+
298
+ def i_am_maintainer(file)
299
+ # mod = module_name 2
300
+ if File.exists?(file)
301
+ src = IO.read(file)
302
+ mtc = src.match(%r'#{maintainer 2}')
303
+ iam = (not mtc.nil? or src.match(%r'#\s*maintainer:').nil?)
304
+ ovr = @config[:overwrite]
305
+ iam or ovr
306
+ else
307
+ true
244
308
  end
245
- writeln
246
- writeln
247
- close_output
248
- add_brick(subdir,name)
249
309
  end
250
310
 
251
- def pprint_cfn_resource(name, options)
252
- subdir = 'Resources'
253
- open_output(subdir,name)
254
- writeln '# noinspection RubyStringKeysInHashInspection'
255
- writeln "resource #{fmt_string(name)},"
256
- indent = ' '
257
- options.each do |k, v|
258
- case k
259
- when /^(Metadata|Properties)$/
260
- write "#{indent}#{fmt_key(k)} => "
261
- pprint_value options[k], indent
262
- writeln ','
263
- else
264
- write "#{indent}#{fmt_key(k)} => "
265
- writeln "#{fmt(v)},"
311
+ def prelude_code(indent=' ')
312
+ "scope = Aws::Cfn::Compiler.binding[File.basename(File.dirname(__FILE__))][File.basename(__FILE__, '.rb')]\n"+
313
+ "template = scope[:template]\n"+
314
+ "\n"+
315
+ "# noinspection RubyStringKeysInHashInspection\n"+
316
+ "template." +
317
+ ""
318
+ end
319
+
320
+ def print_with_wrapper(code,indent=' ')
321
+ write prelude_code(indent)+code.gsub(%r'^\s+','')
322
+ end
323
+
324
+ def pprint_cfn_section(section, name, options, subdir, brick=true)
325
+ if open_output(subdir,name)
326
+ @logger.info "Pretty print #{section} '#{name}' to '#{rb_file(subdir, name)}'"
327
+ print_maintainer ''
328
+ print_with_wrapper "#{section} #{fmt_string(name)}"
329
+ indent = ' ' + (' ' * section.length) + ' '
330
+ hang = true
331
+ options.each do |k, v|
332
+ if hang
333
+ writeln ','
334
+ hang = false
335
+ end
336
+ write indent, fmt_key(k), " => "
337
+ pprint_value v, indent
338
+ hang = true
266
339
  end
267
- unless k == 'Properties'
340
+ writeln
341
+ writeln
342
+ close_output
343
+ add_brick(subdir,name) if brick
344
+ else
345
+ @logger.warn "NOT overwriting existing source file '#{rb_file(subdir, name)}'"
346
+ end
347
+ end
348
+
349
+ def pprint_cfn_resource(name, options, brick=true)
350
+ subdir = 'Resources'
351
+ if open_output(subdir,name)
352
+ @logger.info "Pretty print resource '#{name}' to '#{rb_file(subdir, name)}'"
353
+ print_maintainer ''
354
+ print_with_wrapper "resource #{fmt_string(name)}"
355
+ indent = ' '
356
+ hang = true
357
+ options.each do |k, v|
358
+ if hang
359
+ writeln ','
360
+ hang = false
361
+ end
362
+
363
+ case k
364
+ when /^(Metadata|Properties)$/
365
+ write "#{indent}#{fmt_key(k)} => "
366
+ pprint_value options[k], indent
367
+ hang = true
368
+ else
369
+ write "#{indent}#{fmt_key(k)} => "
370
+ write "#{fmt(v)}"
371
+ hang = true
372
+ end
268
373
  end
374
+ writeln
375
+ close_output
376
+ add_brick(subdir,name) if brick
377
+ else
378
+ @logger.warn "NOT overwriting existing source file '#{rb_file(subdir, name)}'"
269
379
  end
270
- writeln
271
- close_output
272
- add_brick(subdir,name)
273
380
  end
274
381
 
275
382
  def pprint_value(val, indent)
@@ -1,4 +1,3 @@
1
- require "aws/cfn/decompiler"
2
1
 
3
2
  module Aws
4
3
  module Cfn
@@ -9,17 +9,24 @@ module Aws
9
9
  def run
10
10
 
11
11
  @opts = Slop.parse(help: true) do
12
- on :j, :template=, 'The template to convert', as: String
13
- on :o, :output=, 'The directory to output the DSL to.', as: String
12
+ on :j, :template=, 'The template to convert', as: String, argument: true
13
+ on :o, :output=, 'The directory to output the DSL to.', as: String, argument: true
14
+ on :O, :overwrite, 'Overwrite existing generated source files. (HINT: Think twice ...)', { as: String, optional_argument: true, default: 'off', match: %r/0|1|yes|no|on|off|enable|disable|set|unset|true|false|raw/i }
14
15
  end
15
16
 
17
+ @config[:overwrite] = if @opts[:overwrite].downcase.match %r'^(1|true|on|yes|enable|set)$'
18
+ true
19
+ else
20
+ false
21
+ end
22
+
16
23
  unless @opts[:template]
17
24
  abort! @opts
18
25
  end
19
26
 
20
- load(@opts[:template])
27
+ load_template(@opts[:template])
21
28
 
22
- save(@opts[:output])
29
+ save_dsl(@opts[:output])
23
30
 
24
31
  end
25
32
  end
@@ -70,7 +70,7 @@ module Aws
70
70
  end
71
71
  end
72
72
 
73
- def hash_refs(line)
73
+ def hash_refs(line,scope)
74
74
  match = line.match %r/^(.*?)(\{\s*:\S+\s*=>.*?\}|\{\s*\S+:\s*.*?\})(.*)$/
75
75
  if match
76
76
  h = nil
@@ -84,8 +84,8 @@ module Aws
84
84
  end
85
85
 
86
86
  h[k.to_s] = v
87
- VARS[:logger].debug h
88
- [match[1], h, hash_refs(match[3]) ]
87
+ scope[:logger].debug h
88
+ [match[1], h, hash_refs(match[3],scope) ]
89
89
  else
90
90
  "#{line}\n"
91
91
  end
@@ -1,7 +1,7 @@
1
1
  module Aws
2
2
  module Cfn
3
3
  module Dsl
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-cfn-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christo DeLange
@@ -95,26 +95,6 @@ files:
95
95
  - lib/aws/cfn/dsl/main.rb
96
96
  - lib/aws/cfn/dsl/template.rb
97
97
  - lib/aws/cfn/dsl/version.rb
98
- - test/Mappings/AWSRegion2AMI.rb
99
- - test/Outputs/ChefSecurityGroup.rb
100
- - test/Outputs/ServerURL.rb
101
- - test/Outputs/ValidationKeyBucket.rb
102
- - test/Parameters/CookbookLocation.rb
103
- - test/Parameters/InstanceType.rb
104
- - test/Parameters/KeyName.rb
105
- - test/Parameters/RoleLocation.rb
106
- - test/Parameters/SSHLocation.rb
107
- - test/Resources/BucketPolicy.rb
108
- - test/Resources/ChefClientSecurityGroup.rb
109
- - test/Resources/ChefServer.rb
110
- - test/Resources/ChefServerSecurityGroup.rb
111
- - test/Resources/ChefServerUser.rb
112
- - test/Resources/ChefServerWaitCondition.rb
113
- - test/Resources/ChefServerWaitHandle.rb
114
- - test/Resources/HostKeys.rb
115
- - test/Resources/PrivateKeyBucket.rb
116
- - test/chef-server.json
117
- - test/chef-server.rb
118
98
  homepage: ''
119
99
  licenses:
120
100
  - MIT
@@ -139,24 +119,4 @@ rubygems_version: 2.2.2
139
119
  signing_key:
140
120
  specification_version: 4
141
121
  summary: Ruby DSL for creating Cloudformation templates
142
- test_files:
143
- - test/Mappings/AWSRegion2AMI.rb
144
- - test/Outputs/ChefSecurityGroup.rb
145
- - test/Outputs/ServerURL.rb
146
- - test/Outputs/ValidationKeyBucket.rb
147
- - test/Parameters/CookbookLocation.rb
148
- - test/Parameters/InstanceType.rb
149
- - test/Parameters/KeyName.rb
150
- - test/Parameters/RoleLocation.rb
151
- - test/Parameters/SSHLocation.rb
152
- - test/Resources/BucketPolicy.rb
153
- - test/Resources/ChefClientSecurityGroup.rb
154
- - test/Resources/ChefServer.rb
155
- - test/Resources/ChefServerSecurityGroup.rb
156
- - test/Resources/ChefServerUser.rb
157
- - test/Resources/ChefServerWaitCondition.rb
158
- - test/Resources/ChefServerWaitHandle.rb
159
- - test/Resources/HostKeys.rb
160
- - test/Resources/PrivateKeyBucket.rb
161
- - test/chef-server.json
162
- - test/chef-server.rb
122
+ test_files: []
@@ -1,10 +0,0 @@
1
- mapping 'AWSRegion2AMI',
2
- :'us-east-1' => { :id => 'ami-83dee0ea' },
3
- :'us-west-1' => { :id => 'ami-c45f6281' },
4
- :'us-west-2' => { :id => 'ami-d0d8b8e0' },
5
- :'eu-west-1' => { :id => 'ami-aa56a1dd' },
6
- :'sa-east-1' => { :id => 'ami-d55bfbc8' },
7
- :'ap-southeast-1' => { :id => 'ami-bc7325ee' },
8
- :'ap-southeast-2' => { :id => 'ami-e577e9df' },
9
- :'ap-northeast-1' => { :id => 'ami-f72e45f6' }
10
-
@@ -1,4 +0,0 @@
1
- output 'ChefSecurityGroup',
2
- :Description => 'EC2 Security Group with access to Opscode chef server',
3
- :Value => { :Ref => 'ChefClientSecurityGroup' }
4
-
@@ -1,13 +0,0 @@
1
- output 'ServerURL',
2
- :Description => 'URL of newly created Opscode chef server',
3
- :Value => {
4
- :'Fn::Join' => [
5
- '',
6
- [
7
- 'https://',
8
- { :'Fn::GetAtt' => [ 'ChefServer', 'PublicDnsName' ] },
9
- ':443',
10
- ],
11
- ],
12
- }
13
-
@@ -1,4 +0,0 @@
1
- output 'ValidationKeyBucket',
2
- :Description => 'Location of validation key',
3
- :Value => { :Ref => 'PrivateKeyBucket' }
4
-
@@ -1,5 +0,0 @@
1
- parameter 'CookbookLocation',
2
- :Type => 'String',
3
- :Default => 'https://github.com/opscode-cookbooks/aws/tarball/master',
4
- :Description => 'Location of chef cookbooks to upload to server'
5
-
@@ -1,7 +0,0 @@
1
- parameter 'InstanceType',
2
- :Description => 'WebServer EC2 instance type',
3
- :Type => 'String',
4
- :Default => 'm1.small',
5
- :AllowedValues => %w(t1.micro m1.small m1.medium m1.large m1.xlarge m2.xlarge m2.2xlarge m2.4xlarge m3.xlarge m3.2xlarge c1.medium c1.xlarge cc1.4xlarge cc2.8xlarge cg1.4xlarge),
6
- :ConstraintDescription => 'must be a valid EC2 instance type.'
7
-
@@ -1,8 +0,0 @@
1
- parameter 'KeyName',
2
- :Description => 'Name of an existing EC2 KeyPair to enable SSH access to the web server',
3
- :Type => 'String',
4
- :MinLength => '1',
5
- :MaxLength => '255',
6
- :AllowedPattern => '[\\x20-\\x7E]*',
7
- :ConstraintDescription => 'can contain only ASCII characters.'
8
-
@@ -1,5 +0,0 @@
1
- parameter 'RoleLocation',
2
- :Type => 'String',
3
- :Default => 'https://s3.amazonaws.com/cloudformation-examples/example_chef_roles.tar.gz',
4
- :Description => 'Location of client roles to upload to server'
5
-
@@ -1,9 +0,0 @@
1
- parameter 'SSHLocation',
2
- :Description => 'The IP address range that can be used to SSH to the EC2 instances',
3
- :Type => 'String',
4
- :MinLength => '9',
5
- :MaxLength => '18',
6
- :Default => '0.0.0.0/0',
7
- :AllowedPattern => '(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})',
8
- :ConstraintDescription => 'must be a valid IP CIDR range of the form x.x.x.x/x.'
9
-
@@ -1,28 +0,0 @@
1
- resource 'BucketPolicy', :Type => 'AWS::S3::BucketPolicy', :Properties => {
2
- :PolicyDocument => {
3
- :Version => '2008-10-17',
4
- :Id => 'WritePolicy',
5
- :Statement => [
6
- {
7
- :Sid => 'WriteAccess',
8
- :Action => [ 's3:PutObject' ],
9
- :Effect => 'Allow',
10
- :Resource => {
11
- :'Fn::Join' => [
12
- '',
13
- [
14
- 'arn:aws:s3:::',
15
- { :Ref => 'PrivateKeyBucket' },
16
- '/*',
17
- ],
18
- ],
19
- },
20
- :Principal => {
21
- :AWS => { :'Fn::GetAtt' => [ 'ChefServerUser', 'Arn' ] },
22
- },
23
- },
24
- ],
25
- },
26
- :Bucket => { :Ref => 'PrivateKeyBucket' },
27
- }
28
-
@@ -1,2 +0,0 @@
1
- resource 'ChefClientSecurityGroup', :Type => 'AWS::EC2::SecurityGroup', :Properties => { :GroupDescription => 'Group with access to Chef Server' }
2
-
@@ -1,57 +0,0 @@
1
- resource 'ChefServer', :Type => 'AWS::EC2::Instance', :Metadata => { :'AWS::CloudFormation::Init' => { :config => { :packages => { :apt => { :s3cmd => [] } }, :sources => { :'/home/ubuntu/chef-repo' => 'https://github.com/opscode/chef-repo/tarball/master', :'/home/ubuntu/chef-repo/cookbooks' => { :Ref => 'CookbookLocation' }, :'/home/ubuntu/chef-repo/roles' => { :Ref => 'RoleLocation' } }, :files => { :'/home/ubuntu/setup_environment' => { :source => 'https://s3.amazonaws.com/cloudformation-examples/setup-chef-server-with-knife', :mode => '000755', :owner => 'ubuntu', :group => 'ubuntu' }, :'/home/ubuntu/.s3cfg' => { :content => { :'Fn::Join' => [ '', [ "[default]\n", 'access_key = ', { :Ref => 'HostKeys' }, "\n", 'secret_key = ', { :'Fn::GetAtt' => [ 'HostKeys', 'SecretAccessKey' ] }, "\n", "use_https = True\n" ] ] }, :mode => '000644', :owner => 'ubuntu', :group => 'ubuntu' }, :'/home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb' => { :source => 'https://s3.amazonaws.com/cloudformation-examples/chef_11.10.0-1.ubuntu.12.04_amd64.deb', :mode => '000664', :owner => 'ubuntu', :group => 'ubuntu' }, :'/home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb' => { :source => 'https://s3.amazonaws.com/cloudformation-examples/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb', :mode => '000664', :owner => 'ubuntu', :group => 'ubuntu' } } } } }, :Properties => {
2
- :SecurityGroups => [
3
- { :Ref => 'ChefServerSecurityGroup' },
4
- ],
5
- :ImageId => {
6
- :'Fn::FindInMap' => [
7
- 'AWSRegion2AMI',
8
- { :Ref => 'AWS::Region' },
9
- 'id',
10
- ],
11
- },
12
- :UserData => {
13
- :'Fn::Base64' => {
14
- :'Fn::Join' => [
15
- '',
16
- [
17
- "#!/bin/bash\n",
18
- "function error_exit\n",
19
- "{\n",
20
- ' cfn-signal -e 1 -r "$1" \'',
21
- { :Ref => 'ChefServerWaitHandle' },
22
- "'\n",
23
- " exit 1\n",
24
- "}\n",
25
- "apt-get -y install python-setuptools\n",
26
- "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
27
- 'cfn-init --region ',
28
- { :Ref => 'AWS::Region' },
29
- ' -s ',
30
- { :Ref => 'AWS::StackId' },
31
- ' -r ChefServer ',
32
- "|| error_exit 'Failed to run cfn-init'\n",
33
- "# Bootstrap chef\n",
34
- "dpkg -i /home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb > /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef client tools'\n",
35
- "dpkg -i /home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb >> /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef server'\n",
36
- "sleep 5\n",
37
- "sudo /usr/bin/chef-server-ctl reconfigure > /tmp/chef_configure.log 2>&1 || error_exit 'Failed to configure chef server'\n",
38
- "sleep 5\n",
39
- "sudo chef-server-ctl start\n",
40
- "# Setup development environment in ubuntu user\n",
41
- "sudo -u ubuntu /home/ubuntu/setup_environment > /tmp/setup_environment.log 2>&1 || error_exit 'Failed to bootstrap chef server'\n",
42
- "# copy validation key to S3 bucket\n",
43
- 's3cmd -c /home/ubuntu/.s3cfg put /etc/chef-server/validation.pem s3://',
44
- { :Ref => 'PrivateKeyBucket' },
45
- "/validation.pem > /tmp/put_validation_key.log 2>&1 || error_exit 'Failed to put Chef Server validation key'\n",
46
- "# If all went well, signal success\n",
47
- 'cfn-signal -e $? -r \'Chef Server configuration\' \'',
48
- { :Ref => 'ChefServerWaitHandle' },
49
- "'\n",
50
- ],
51
- ],
52
- },
53
- },
54
- :KeyName => { :Ref => 'KeyName' },
55
- :InstanceType => { :Ref => 'InstanceType' },
56
- }
57
-
@@ -1,19 +0,0 @@
1
- resource 'ChefServerSecurityGroup', :Type => 'AWS::EC2::SecurityGroup', :Properties => {
2
- :GroupDescription => 'Open up SSH access plus Chef Server required ports',
3
- :SecurityGroupIngress => [
4
- {
5
- :IpProtocol => 'tcp',
6
- :FromPort => '22',
7
- :ToPort => '22',
8
- :CidrIp => { :Ref => 'SSHLocation' },
9
- },
10
- {
11
- :IpProtocol => 'tcp',
12
- :FromPort => '443',
13
- :ToPort => '443',
14
- :SourceSecurityGroupName => { :Ref => 'ChefClientSecurityGroup' },
15
- },
16
- { :IpProtocol => 'tcp', :FromPort => '443', :ToPort => '443', :CidrIp => '0.0.0.0/0' },
17
- ],
18
- }
19
-
@@ -1,18 +0,0 @@
1
- resource 'ChefServerUser', :Type => 'AWS::IAM::User', :Properties => {
2
- :Path => '/',
3
- :Policies => [
4
- {
5
- :PolicyName => 'root',
6
- :PolicyDocument => {
7
- :Statement => [
8
- {
9
- :Effect => 'Allow',
10
- :Action => [ 'cloudformation:DescribeStackResource', 's3:Put' ],
11
- :Resource => '*',
12
- },
13
- ],
14
- },
15
- },
16
- ],
17
- }
18
-
@@ -1,5 +0,0 @@
1
- resource 'ChefServerWaitCondition', :Type => 'AWS::CloudFormation::WaitCondition', :DependsOn => 'ChefServer', :Properties => {
2
- :Handle => { :Ref => 'ChefServerWaitHandle' },
3
- :Timeout => '1200',
4
- }
5
-
@@ -1,2 +0,0 @@
1
- resource 'ChefServerWaitHandle', :Type => 'AWS::CloudFormation::WaitConditionHandle'
2
-
@@ -1,4 +0,0 @@
1
- resource 'HostKeys', :Type => 'AWS::IAM::AccessKey', :Properties => {
2
- :UserName => { :Ref => 'ChefServerUser' },
3
- }
4
-
@@ -1,2 +0,0 @@
1
- resource 'PrivateKeyBucket', :Type => 'AWS::S3::Bucket', :DeletionPolicy => 'Delete', :Properties => { :AccessControl => 'Private' }
2
-
@@ -1,392 +0,0 @@
1
- {
2
- "AWSTemplateFormatVersion": "2010-09-09",
3
- "Description": "Sample template to bring up an Opscode Chef Server using the Opscode debian files for installation. This configuration creates and starts the Chef Server with the WebUI enabled, initializes knife and uploads specified cookbooks and roles to the chef server. A WaitCondition is used to hold up the stack creation until the application is deployed. **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",
4
- "Mappings": {
5
- "AWSRegion2AMI": {
6
- "us-east-1": {
7
- "id": "ami-83dee0ea"
8
- },
9
- "us-west-1": {
10
- "id": "ami-c45f6281"
11
- },
12
- "us-west-2": {
13
- "id": "ami-d0d8b8e0"
14
- },
15
- "eu-west-1": {
16
- "id": "ami-aa56a1dd"
17
- },
18
- "sa-east-1": {
19
- "id": "ami-d55bfbc8"
20
- },
21
- "ap-southeast-1": {
22
- "id": "ami-bc7325ee"
23
- },
24
- "ap-southeast-2": {
25
- "id": "ami-e577e9df"
26
- },
27
- "ap-northeast-1": {
28
- "id": "ami-f72e45f6"
29
- }
30
- }
31
- },
32
- "Parameters": {
33
- "KeyName": {
34
- "Description": "Name of an existing EC2 KeyPair to enable SSH access to the web server",
35
- "Type": "String",
36
- "MinLength": "1",
37
- "MaxLength": "255",
38
- "AllowedPattern": "[\\x20-\\x7E]*",
39
- "ConstraintDescription": "can contain only ASCII characters."
40
- },
41
- "CookbookLocation": {
42
- "Type": "String",
43
- "Default": "https://github.com/opscode-cookbooks/aws/tarball/master",
44
- "Description": "Location of chef cookbooks to upload to server"
45
- },
46
- "RoleLocation": {
47
- "Type": "String",
48
- "Default": "https://s3.amazonaws.com/cloudformation-examples/example_chef_roles.tar.gz",
49
- "Description": "Location of client roles to upload to server"
50
- },
51
- "InstanceType": {
52
- "Description": "WebServer EC2 instance type",
53
- "Type": "String",
54
- "Default": "m1.small",
55
- "AllowedValues": [
56
- "t1.micro",
57
- "m1.small",
58
- "m1.medium",
59
- "m1.large",
60
- "m1.xlarge",
61
- "m2.xlarge",
62
- "m2.2xlarge",
63
- "m2.4xlarge",
64
- "m3.xlarge",
65
- "m3.2xlarge",
66
- "c1.medium",
67
- "c1.xlarge",
68
- "cc1.4xlarge",
69
- "cc2.8xlarge",
70
- "cg1.4xlarge"
71
- ],
72
- "ConstraintDescription": "must be a valid EC2 instance type."
73
- },
74
- "SSHLocation": {
75
- "Description": "The IP address range that can be used to SSH to the EC2 instances",
76
- "Type": "String",
77
- "MinLength": "9",
78
- "MaxLength": "18",
79
- "Default": "0.0.0.0/0",
80
- "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
81
- "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
82
- }
83
- },
84
- "Resources": {
85
- "ChefServerUser": {
86
- "Type": "AWS::IAM::User",
87
- "Properties": {
88
- "Path": "/",
89
- "Policies": [
90
- {
91
- "PolicyName": "root",
92
- "PolicyDocument": {
93
- "Statement": [
94
- {
95
- "Effect": "Allow",
96
- "Action": [
97
- "cloudformation:DescribeStackResource",
98
- "s3:Put"
99
- ],
100
- "Resource": "*"
101
- }
102
- ]
103
- }
104
- }
105
- ]
106
- }
107
- },
108
- "HostKeys": {
109
- "Type": "AWS::IAM::AccessKey",
110
- "Properties": {
111
- "UserName": {
112
- "Ref": "ChefServerUser"
113
- }
114
- }
115
- },
116
- "ChefServer": {
117
- "Type": "AWS::EC2::Instance",
118
- "Metadata": {
119
- "AWS::CloudFormation::Init": {
120
- "config": {
121
- "packages": {
122
- "apt": {
123
- "s3cmd": [
124
-
125
- ]
126
- }
127
- },
128
- "sources": {
129
- "/home/ubuntu/chef-repo": "https://github.com/opscode/chef-repo/tarball/master",
130
- "/home/ubuntu/chef-repo/cookbooks": {
131
- "Ref": "CookbookLocation"
132
- },
133
- "/home/ubuntu/chef-repo/roles": {
134
- "Ref": "RoleLocation"
135
- }
136
- },
137
- "files": {
138
- "/home/ubuntu/setup_environment": {
139
- "source": "https://s3.amazonaws.com/cloudformation-examples/setup-chef-server-with-knife",
140
- "mode": "000755",
141
- "owner": "ubuntu",
142
- "group": "ubuntu"
143
- },
144
- "/home/ubuntu/.s3cfg": {
145
- "content": {
146
- "Fn::Join": [
147
- "",
148
- [
149
- "[default]\n",
150
- "access_key = ",
151
- {
152
- "Ref": "HostKeys"
153
- },
154
- "\n",
155
- "secret_key = ",
156
- {
157
- "Fn::GetAtt": [
158
- "HostKeys",
159
- "SecretAccessKey"
160
- ]
161
- },
162
- "\n",
163
- "use_https = True\n"
164
- ]
165
- ]
166
- },
167
- "mode": "000644",
168
- "owner": "ubuntu",
169
- "group": "ubuntu"
170
- },
171
- "/home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb": {
172
- "source": "https://s3.amazonaws.com/cloudformation-examples/chef_11.10.0-1.ubuntu.12.04_amd64.deb",
173
- "mode": "000664",
174
- "owner": "ubuntu",
175
- "group": "ubuntu"
176
- },
177
- "/home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb": {
178
- "source": "https://s3.amazonaws.com/cloudformation-examples/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb",
179
- "mode": "000664",
180
- "owner": "ubuntu",
181
- "group": "ubuntu"
182
- }
183
- }
184
- }
185
- }
186
- },
187
- "Properties": {
188
- "SecurityGroups": [
189
- {
190
- "Ref": "ChefServerSecurityGroup"
191
- }
192
- ],
193
- "ImageId": {
194
- "Fn::FindInMap": [
195
- "AWSRegion2AMI",
196
- {
197
- "Ref": "AWS::Region"
198
- },
199
- "id"
200
- ]
201
- },
202
- "UserData": {
203
- "Fn::Base64": {
204
- "Fn::Join": [
205
- "",
206
- [
207
- "#!/bin/bash\n",
208
- "function error_exit\n",
209
- "{\n",
210
- " cfn-signal -e 1 -r \"$1\" '",
211
- {
212
- "Ref": "ChefServerWaitHandle"
213
- },
214
- "'\n",
215
- " exit 1\n",
216
- "}\n",
217
- "apt-get -y install python-setuptools\n",
218
- "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
219
- "cfn-init --region ",
220
- {
221
- "Ref": "AWS::Region"
222
- },
223
- " -s ",
224
- {
225
- "Ref": "AWS::StackId"
226
- },
227
- " -r ChefServer ",
228
- "|| error_exit 'Failed to run cfn-init'\n",
229
- "# Bootstrap chef\n",
230
- "dpkg -i /home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb > /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef client tools'\n",
231
- "dpkg -i /home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb >> /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef server'\n",
232
- "sleep 5\n",
233
- "sudo /usr/bin/chef-server-ctl reconfigure > /tmp/chef_configure.log 2>&1 || error_exit 'Failed to configure chef server'\n",
234
- "sleep 5\n",
235
- "sudo chef-server-ctl start\n",
236
- "# Setup development environment in ubuntu user\n",
237
- "sudo -u ubuntu /home/ubuntu/setup_environment > /tmp/setup_environment.log 2>&1 || error_exit 'Failed to bootstrap chef server'\n",
238
- "# copy validation key to S3 bucket\n",
239
- "s3cmd -c /home/ubuntu/.s3cfg put /etc/chef-server/validation.pem s3://",
240
- {
241
- "Ref": "PrivateKeyBucket"
242
- },
243
- "/validation.pem > /tmp/put_validation_key.log 2>&1 || error_exit 'Failed to put Chef Server validation key'\n",
244
- "# If all went well, signal success\n",
245
- "cfn-signal -e $? -r 'Chef Server configuration' '",
246
- {
247
- "Ref": "ChefServerWaitHandle"
248
- },
249
- "'\n"
250
- ]
251
- ]
252
- }
253
- },
254
- "KeyName": {
255
- "Ref": "KeyName"
256
- },
257
- "InstanceType": {
258
- "Ref": "InstanceType"
259
- }
260
- }
261
- },
262
- "ChefServerSecurityGroup": {
263
- "Type": "AWS::EC2::SecurityGroup",
264
- "Properties": {
265
- "GroupDescription": "Open up SSH access plus Chef Server required ports",
266
- "SecurityGroupIngress": [
267
- {
268
- "IpProtocol": "tcp",
269
- "FromPort": "22",
270
- "ToPort": "22",
271
- "CidrIp": {
272
- "Ref": "SSHLocation"
273
- }
274
- },
275
- {
276
- "IpProtocol": "tcp",
277
- "FromPort": "443",
278
- "ToPort": "443",
279
- "SourceSecurityGroupName": {
280
- "Ref": "ChefClientSecurityGroup"
281
- }
282
- },
283
- {
284
- "IpProtocol": "tcp",
285
- "FromPort": "443",
286
- "ToPort": "443",
287
- "CidrIp": "0.0.0.0/0"
288
- }
289
- ]
290
- }
291
- },
292
- "ChefClientSecurityGroup": {
293
- "Type": "AWS::EC2::SecurityGroup",
294
- "Properties": {
295
- "GroupDescription": "Group with access to Chef Server"
296
- }
297
- },
298
- "PrivateKeyBucket": {
299
- "Type": "AWS::S3::Bucket",
300
- "DeletionPolicy": "Delete",
301
- "Properties": {
302
- "AccessControl": "Private"
303
- }
304
- },
305
- "BucketPolicy": {
306
- "Type": "AWS::S3::BucketPolicy",
307
- "Properties": {
308
- "PolicyDocument": {
309
- "Version": "2008-10-17",
310
- "Id": "WritePolicy",
311
- "Statement": [
312
- {
313
- "Sid": "WriteAccess",
314
- "Action": [
315
- "s3:PutObject"
316
- ],
317
- "Effect": "Allow",
318
- "Resource": {
319
- "Fn::Join": [
320
- "",
321
- [
322
- "arn:aws:s3:::",
323
- {
324
- "Ref": "PrivateKeyBucket"
325
- },
326
- "/*"
327
- ]
328
- ]
329
- },
330
- "Principal": {
331
- "AWS": {
332
- "Fn::GetAtt": [
333
- "ChefServerUser",
334
- "Arn"
335
- ]
336
- }
337
- }
338
- }
339
- ]
340
- },
341
- "Bucket": {
342
- "Ref": "PrivateKeyBucket"
343
- }
344
- }
345
- },
346
- "ChefServerWaitHandle": {
347
- "Type": "AWS::CloudFormation::WaitConditionHandle"
348
- },
349
- "ChefServerWaitCondition": {
350
- "Type": "AWS::CloudFormation::WaitCondition",
351
- "DependsOn": "ChefServer",
352
- "Properties": {
353
- "Handle": {
354
- "Ref": "ChefServerWaitHandle"
355
- },
356
- "Timeout": "1200"
357
- }
358
- }
359
- },
360
- "Outputs": {
361
- "ServerURL": {
362
- "Description": "URL of newly created Opscode chef server",
363
- "Value": {
364
- "Fn::Join": [
365
- "",
366
- [
367
- "https://",
368
- {
369
- "Fn::GetAtt": [
370
- "ChefServer",
371
- "PublicDnsName"
372
- ]
373
- },
374
- ":443"
375
- ]
376
- ]
377
- }
378
- },
379
- "ChefSecurityGroup": {
380
- "Description": "EC2 Security Group with access to Opscode chef server",
381
- "Value": {
382
- "Ref": "ChefClientSecurityGroup"
383
- }
384
- },
385
- "ValidationKeyBucket": {
386
- "Description": "Location of validation key",
387
- "Value": {
388
- "Ref": "PrivateKeyBucket"
389
- }
390
- }
391
- }
392
- }
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift(File.dirname(__FILE__))
4
- $:.unshift File.absolute_path("#{File.dirname(__FILE__)}/../lib")
5
- require 'bundler/setup'
6
- require 'aws/cfn/dsl/template'
7
-
8
- template do
9
-
10
- value :AWSTemplateFormatVersion => '2010-09-09'
11
-
12
- value :Description => 'Sample template to bring up an Opscode Chef Server using the Opscode debian files for installation. This configuration creates and starts the Chef Server with the WebUI enabled, initializes knife and uploads specified cookbooks and roles to the chef server. A WaitCondition is used to hold up the stack creation until the application is deployed. **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.'
13
-
14
- # Mappings
15
- mapping 'AWSRegion2AMI'
16
-
17
- # Parameters
18
- parameter 'KeyName'
19
- parameter 'CookbookLocation'
20
- parameter 'RoleLocation'
21
- parameter 'InstanceType'
22
- parameter 'SSHLocation'
23
-
24
- # Resources
25
- resource 'ChefServerUser'
26
- resource 'HostKeys'
27
- resource 'ChefServer'
28
- resource 'ChefServerSecurityGroup'
29
- resource 'ChefClientSecurityGroup'
30
- resource 'PrivateKeyBucket'
31
- resource 'BucketPolicy'
32
- resource 'ChefServerWaitHandle'
33
- resource 'ChefServerWaitCondition'
34
-
35
- # Outputs
36
- output 'ServerURL'
37
- output 'ChefSecurityGroup'
38
- output 'ValidationKeyBucket'
39
-
40
- end.exec!