rubycfn 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/CHANGELOG.md +5 -1
- data/CloudFormationResourceSpecification.json +45573 -0
- data/Gemfile.lock +1 -1
- data/README.md +93 -1
- data/lib/rubycfn.rb +21 -0
- data/lib/rubycfn/version.rb +1 -1
- metadata +3 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -61,7 +61,7 @@ __________ ____ __________________.___._________ _____________________
|
|
61
61
|
| _/ | /| | _// | |/ \ \/ | __) | | _/
|
62
62
|
| | \ | / | | \\____ |\ \____| \ | | \
|
63
63
|
|____|_ /______/ |______ // ______| \______ /\___ / |______ /
|
64
|
-
\/ \/ \/ \/ \/ \/ [v0.4.
|
64
|
+
\/ \/ \/ \/ \/ \/ [v0.4.2]
|
65
65
|
Project name? example
|
66
66
|
Account ID? 1234567890
|
67
67
|
Select region EU (Frankfurt)
|
@@ -338,6 +338,98 @@ convert it to YAML format ;)
|
|
338
338
|
To allow for SAM transformation use the 'transform' method inside your template.
|
339
339
|
The transform method takes an optional argument, and defaults to "AWS::Serverless-2016-10-31"
|
340
340
|
|
341
|
+
## Resource attributes
|
342
|
+
|
343
|
+
When creating a resource there are a couple of arguments that can be passed
|
344
|
+
along with it. In its most simple form a resource looks like this:
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
resource :my_resource,
|
348
|
+
type: "AWS::Some::Resource"
|
349
|
+
```
|
350
|
+
|
351
|
+
The following arguments are supported:
|
352
|
+
|
353
|
+
* condition
|
354
|
+
* creation_policy
|
355
|
+
* deletion_policy
|
356
|
+
* depends_on
|
357
|
+
* metadata
|
358
|
+
* type
|
359
|
+
* update_policy
|
360
|
+
* update_replace_policy
|
361
|
+
|
362
|
+
To make a resource depend on another resource you can use the `depends_on`
|
363
|
+
argument as follows:
|
364
|
+
|
365
|
+
```ruby
|
366
|
+
resource :my_resource,
|
367
|
+
depends_on: :some_other_resource,
|
368
|
+
type: "AWS::Some::Resource"
|
369
|
+
```
|
370
|
+
|
371
|
+
or... if you want to make it dependant on multiple resources:
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
resource :my_resource,
|
375
|
+
depends_on: %i(some_other_resource yet_another_resource),
|
376
|
+
type: "AWS::Some::Resource"
|
377
|
+
```
|
378
|
+
|
379
|
+
If you want to dynamically generate DependsOn, you can do that in this way:
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
resource :my_resource,
|
383
|
+
amount: 2,
|
384
|
+
type: "AWS::Some::Resource" do |r, index|
|
385
|
+
r.depends_on "SomeResource#{index}"
|
386
|
+
end
|
387
|
+
```
|
388
|
+
|
389
|
+
The `depends_on` attribute and `r.depends_on` method can be used together.
|
390
|
+
The `r.depends_on` specified resources get appended to the `depends_on`
|
391
|
+
specified resources.
|
392
|
+
|
393
|
+
## Manipulating the resource name
|
394
|
+
|
395
|
+
Common practice is to use a symbol as argument to the `resource` method. The
|
396
|
+
passed symbol is camel cased in the final CloudFormation template generation.
|
397
|
+
It is imaginable that you have a use case where you need to control the resource
|
398
|
+
name. There are two ways to achieve this.
|
399
|
+
|
400
|
+
The first method is to pass a string as resource name, rather than a symbol.
|
401
|
+
When you pass a string it will be taken as the literal resource name and not be
|
402
|
+
camel cased. E.g.:
|
403
|
+
|
404
|
+
```ruby
|
405
|
+
resource "myAmazingResource",
|
406
|
+
type: "AWS::Some::Resource"
|
407
|
+
```
|
408
|
+
|
409
|
+
The second method is to use the resource method `_id`:
|
410
|
+
|
411
|
+
```ruby
|
412
|
+
resource :irrelevant_resource_name,
|
413
|
+
amount: 3,
|
414
|
+
type: "AWS::Some::Resource" do |r, index|
|
415
|
+
r._id "ResourceNameOverride#{index+1}"
|
416
|
+
end
|
417
|
+
```
|
418
|
+
|
419
|
+
## Resource validation
|
420
|
+
|
421
|
+
Rubycfn is shipped with a `CloudFormationResourceSpecification.json` file. It
|
422
|
+
is used to validate whether used properties are valid and if any mandatory
|
423
|
+
properties were omitted. The CloudFormation compiler will throw an error if
|
424
|
+
a mandatory property is missing or if an unknown property is specified. Note
|
425
|
+
that the CloudFormationResourceSpecification.json is not actively maintained
|
426
|
+
by me. It is maintained by AWS at:
|
427
|
+
|
428
|
+
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
|
429
|
+
|
430
|
+
You can also place the `CloudFormationResourceSpecification.json` file in the
|
431
|
+
root of your project. It will override the one supplied by Rubycfn.
|
432
|
+
|
341
433
|
## License
|
342
434
|
|
343
435
|
MIT License
|
data/lib/rubycfn.rb
CHANGED
@@ -17,6 +17,11 @@ require "rubycfn/version"
|
|
17
17
|
@variables = {}
|
18
18
|
@global_variables = {}
|
19
19
|
|
20
|
+
@resource_specification = JSON.parse(File.open(File.join(File.dirname(__FILE__), "/../CloudFormationResourceSpecification.json")).read)
|
21
|
+
if File.file?("CloudFormationResourceSpecification.json")
|
22
|
+
@resource_specification = JSON.parse(File.open("CloudFormationResourceSpecification.json").read)
|
23
|
+
end
|
24
|
+
|
20
25
|
# Monkey patching
|
21
26
|
class Symbol
|
22
27
|
def cfnize
|
@@ -380,6 +385,9 @@ module Rubycfn
|
|
380
385
|
name = name.class == Symbol ? name.to_s.cfnize : name = name.to_s
|
381
386
|
arguments[:type] =~ /^([A-Za-z0-9]*)\:\:/
|
382
387
|
arguments[:cloud] ||= $1
|
388
|
+
resource_specification = TOPLEVEL_BINDING.eval("@resource_specification")
|
389
|
+
|
390
|
+
raise "#{arguments[:type]} is not a valid resource type" unless resource_specification["ResourceTypes"][arguments[:type].to_s] || arguments[:type] =~ /Rspec\:\:/ || arguments[:type] =~ /^Custom\:\:/ || arguments[:type] =~ /AWS\:\:Serverless\:\:/
|
383
391
|
|
384
392
|
# Custom resource types are AWS resources
|
385
393
|
if arguments[:cloud] == "Custom" || arguments[:cloud] == "Rspec"
|
@@ -413,6 +421,19 @@ module Rubycfn
|
|
413
421
|
|
414
422
|
arguments[:depends_on] ||= []
|
415
423
|
rendered_depends_on = TOPLEVEL_BINDING.eval("@depends_on").nil? && arguments[:depends_on] || arguments[:depends_on] + TOPLEVEL_BINDING.eval("@depends_on")
|
424
|
+
if resource_specification["ResourceTypes"][arguments[:type].to_s]
|
425
|
+
resource_specification = TOPLEVEL_BINDING.eval("@resource_specification")
|
426
|
+
known_properties = resource_specification["ResourceTypes"][arguments[:type].to_s]["Properties"].keys
|
427
|
+
mandatory_properties = []
|
428
|
+
known_properties.each do |prop|
|
429
|
+
mandatory_properties.push(prop) if resource_specification["ResourceTypes"][arguments[:type].to_s]["Properties"][prop]["Required"] == true
|
430
|
+
end
|
431
|
+
TOPLEVEL_BINDING.eval("@properties").each do |k, _v|
|
432
|
+
raise "Property `#{k}` for #{arguments[:type]} is not valid." unless known_properties.include? k.to_s
|
433
|
+
mandatory_properties.delete(k.to_s)
|
434
|
+
end
|
435
|
+
raise "Property #{mandatory_properties.join(", ")} is mandatory for #{arguments[:type]}" unless mandatory_properties.count.zero?
|
436
|
+
end
|
416
437
|
res = {
|
417
438
|
"#{name.to_s}#{i.zero? ? "" : resource_postpend}": {
|
418
439
|
Properties: TOPLEVEL_BINDING.eval("@properties"),
|
data/lib/rubycfn/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubycfn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dennis Vink
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: neatjson
|
@@ -259,6 +259,7 @@ files:
|
|
259
259
|
- ".gitignore"
|
260
260
|
- ".rubocop.yml"
|
261
261
|
- CHANGELOG.md
|
262
|
+
- CloudFormationResourceSpecification.json
|
262
263
|
- Gemfile
|
263
264
|
- Gemfile.lock
|
264
265
|
- README.md
|