rubycfn 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/compound/resources.rb +1 -0
- data/lib/compound/vpc.rb +89 -0
- data/lib/compound.rb +1 -0
- data/lib/rubycfn/version.rb +1 -1
- data/lib/rubycfn.rb +54 -2
- data/templates/compile.rb.erb +2 -2
- data/templates/project_concern.rb.erb +18 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d01bd17b4d8c71bd2377cbee3606eddb28778df
|
4
|
+
data.tar.gz: 7d92a19ab91e083aed1492c4b0a00f74b01896d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3708591c58295896ef5a5b46924eead40ace9744a800a52361842d6e6057f4639bc87f13ee2bc80e50dc7e879b3f8fd51a8687e8e9bb2c1a5c37c6eab9191e8
|
7
|
+
data.tar.gz: 9174d991980b0ec38e0b2d92894f9de68307c1f0fc82f14b0fdcad7d347bd412ba61d319d108ecb2c1f2a11b930ad152fa7f13a5e08aba25c3b14fda516af831
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "vpc"
|
data/lib/compound/vpc.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
module RubyCfn
|
2
|
+
module VPC
|
3
|
+
def self.[](prefix, suffix, &block)
|
4
|
+
Module.new do
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
|
9
|
+
def validate_instance_tenancy(value)
|
10
|
+
unless ["", 'default', 'dedicated'].include? value
|
11
|
+
raise "Expected instance_tenancy to be within `default` or `dedicated`. Received `#{value}`"
|
12
|
+
end
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
variable :cidr_block,
|
17
|
+
default: "10.0.0.0/16"
|
18
|
+
variable :enable_dns_support,
|
19
|
+
default: true
|
20
|
+
variable :enable_dns_hostnames,
|
21
|
+
default: true
|
22
|
+
variable :instance_tenancy,
|
23
|
+
filter: :validate_instance_tenancy
|
24
|
+
# TODO: Move to separate compound resource
|
25
|
+
# variable :ipv6,
|
26
|
+
# default: false
|
27
|
+
# variable :subnets,
|
28
|
+
# default: 3
|
29
|
+
# variable :subnet_ip_addresses,
|
30
|
+
# default: 256
|
31
|
+
|
32
|
+
yield self if block_given? # Variable overrides
|
33
|
+
|
34
|
+
resource "#{prefix}_vpc#{suffix}",
|
35
|
+
type: "AWS::EC2::VPC" do |r, index|
|
36
|
+
r.property(:cidr_block) { cidr_block }
|
37
|
+
r.property(:enable_dns_support) { enable_dns_support }
|
38
|
+
r.property(:enable_dns_hostnames) { enable_dns_hostnames }
|
39
|
+
r.property(:instance_tenancy) { instance_tenancy } unless instance_tenancy.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
resource "#{prefix}_internet_gateway#{suffix}",
|
43
|
+
type: "AWS::EC2::InternetGateway"
|
44
|
+
|
45
|
+
resource "#{prefix}_route#{suffix}",
|
46
|
+
type: "AWS::EC2::Route" do |r, index|
|
47
|
+
r.property(:destination_cidr_block) { "0.0.0.0/0" }
|
48
|
+
r.property(:gateway_id) { "#{prefix}_internet_gateway#{suffix}".cfnize.ref }
|
49
|
+
r.property(:route_table_id) { "#{prefix}_route_table#{suffix}".cfnize.ref }
|
50
|
+
end
|
51
|
+
|
52
|
+
resource "#{prefix}_route_table#{suffix}",
|
53
|
+
type: "AWS::EC2::RouteTable" do |r, index|
|
54
|
+
r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
|
55
|
+
end
|
56
|
+
|
57
|
+
resource "#{prefix}_vpc_gateway_attachment#{suffix}",
|
58
|
+
type: "AWS::EC2::VPCGatewayAttachment" do |r, index|
|
59
|
+
r.property(:internet_gateway_id) { "#{prefix}_internet_gateway#{suffix}".cfnize.ref }
|
60
|
+
r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
|
61
|
+
end
|
62
|
+
|
63
|
+
# TODO: Move to separate compound resource
|
64
|
+
#subnets.times do |i|
|
65
|
+
# resource "#{prefix}_subnet#{suffix}#{i == 0 ? "" : i+1}",
|
66
|
+
# type: "AWS::EC2::Subnet",
|
67
|
+
# compound: true do |r, index|
|
68
|
+
# r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
|
69
|
+
# r.property(:cidr_block) { ["#{prefix}_vpc#{suffix}".cfnize.ref("CidrBlock"), subnets.to_s, ((Math.log(subnet_ip_addresses)/Math.log(2)).floor).to_s].fncidr.fnselect(i) }
|
70
|
+
# #if ipv6 == "true"
|
71
|
+
# # r.property(:ipv6_cidr_block) do
|
72
|
+
# # .. todo ..
|
73
|
+
# # end
|
74
|
+
# #end
|
75
|
+
# end
|
76
|
+
#end
|
77
|
+
|
78
|
+
#if ipv6 == "true"
|
79
|
+
# resource "#{prefix}_ipv6_cidr_block#{suffix}",
|
80
|
+
# type: "AWS::EC2::VPCCidrBlock" do |r, index|
|
81
|
+
# r.property(:vpc_id) { "#{prefix}_vpc#{suffix}".cfnize.ref }
|
82
|
+
# r.property(:amazon_provided_ipv6_cidr_block) { true }
|
83
|
+
# end
|
84
|
+
#end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/compound.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "compound/vpc"
|
data/lib/rubycfn/version.rb
CHANGED
data/lib/rubycfn.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require "neatjson"
|
3
3
|
require "json"
|
4
4
|
require "rubycfn/version"
|
5
|
+
require "compound/resources"
|
5
6
|
require 'active_support/concern'
|
6
7
|
|
7
8
|
@depends_on = []
|
@@ -9,6 +10,7 @@ require 'active_support/concern'
|
|
9
10
|
@outputs = {}
|
10
11
|
@parameters = {}
|
11
12
|
@properties = {}
|
13
|
+
@mappings = {}
|
12
14
|
@resources = {}
|
13
15
|
@variables = {}
|
14
16
|
@global_variables = {}
|
@@ -59,6 +61,22 @@ class String
|
|
59
61
|
end
|
60
62
|
|
61
63
|
class Array
|
64
|
+
def fncidr
|
65
|
+
{
|
66
|
+
"Fn::Cidr": self
|
67
|
+
}
|
68
|
+
end
|
69
|
+
alias_method :cidr, :fncidr
|
70
|
+
|
71
|
+
def fnfindinmap(name = nil)
|
72
|
+
self.unshift(name.cfnize) if name
|
73
|
+
{
|
74
|
+
"Fn::FindInMap": self
|
75
|
+
}
|
76
|
+
end
|
77
|
+
alias_method :find_in_map, :fnfindinmap
|
78
|
+
alias_method :findinmap, :fnfindinmap
|
79
|
+
|
62
80
|
def fnjoin(separator = "")
|
63
81
|
{
|
64
82
|
"Fn::Join": [
|
@@ -93,6 +111,15 @@ class ::Hash
|
|
93
111
|
def compact
|
94
112
|
delete_if { |k, v| v.nil? }
|
95
113
|
end
|
114
|
+
|
115
|
+
def fnselect(index = 0)
|
116
|
+
{
|
117
|
+
"Fn::Select": [
|
118
|
+
index,
|
119
|
+
self
|
120
|
+
]
|
121
|
+
}
|
122
|
+
end
|
96
123
|
end
|
97
124
|
|
98
125
|
module Rubycfn
|
@@ -115,6 +142,24 @@ module Rubycfn
|
|
115
142
|
end
|
116
143
|
end
|
117
144
|
|
145
|
+
def self.mapping(name, arguments = {})
|
146
|
+
raise "`name` is required for mapping." unless arguments[:name]
|
147
|
+
unless arguments[:data]
|
148
|
+
%w(key value).each do |k|
|
149
|
+
raise "`#{k}` is required for mapping, unless a `data` hash is passed." unless arguments[k.to_sym]
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
name = name.to_s.cfnize
|
154
|
+
kv_pairs = arguments[:data] ? arguments[:data] : { "#{arguments[:key]}": "#{arguments[:value]}" }
|
155
|
+
res = {
|
156
|
+
"#{name}": {
|
157
|
+
"#{arguments[:name]}": kv_pairs
|
158
|
+
}
|
159
|
+
}
|
160
|
+
TOPLEVEL_BINDING.eval("@mappings = @mappings.deep_merge(#{res})")
|
161
|
+
end
|
162
|
+
|
118
163
|
def self.parameter(name, arguments)
|
119
164
|
name = name.to_s.cfnize
|
120
165
|
arguments[:type] ||= "String"
|
@@ -151,6 +196,7 @@ module Rubycfn
|
|
151
196
|
arguments[:value] ||= ""
|
152
197
|
arguments[:required] ||= false
|
153
198
|
arguments[:global] ||= false
|
199
|
+
arguments[:filter] ||= nil
|
154
200
|
|
155
201
|
if arguments[:value].empty?
|
156
202
|
arguments[:value] = arguments[:default]
|
@@ -161,6 +207,10 @@ module Rubycfn
|
|
161
207
|
end
|
162
208
|
end
|
163
209
|
|
210
|
+
if arguments[:filter]
|
211
|
+
arguments[:value] = self.send(arguments[:filter], arguments[:value])
|
212
|
+
end
|
213
|
+
|
164
214
|
res = {
|
165
215
|
"#{name}": arguments[:value]
|
166
216
|
}
|
@@ -197,11 +247,12 @@ module Rubycfn
|
|
197
247
|
|
198
248
|
def self.resource(name, arguments, &block)
|
199
249
|
arguments[:amount] ||= 1
|
250
|
+
origname = name.to_s
|
200
251
|
name = name.to_s.cfnize
|
201
252
|
arguments[:amount].times do |i|
|
202
253
|
resource_suffix = i == 0 ? "" : "#{i+1}"
|
203
254
|
if arguments[:type].class == Module
|
204
|
-
send("include", arguments[:type][
|
255
|
+
send("include", arguments[:type][origname, resource_suffix, &block])
|
205
256
|
else
|
206
257
|
yield self, i if block_given?
|
207
258
|
res = {
|
@@ -228,10 +279,11 @@ module Rubycfn
|
|
228
279
|
skeleton = { "AWSTemplateFormatVersion": "2010-09-09" }
|
229
280
|
skeleton = JSON.parse(skeleton.to_json)
|
230
281
|
skeleton.merge!(Description: TOPLEVEL_BINDING.eval("@description"))
|
282
|
+
skeleton.merge!(Mappings: sort_json(TOPLEVEL_BINDING.eval("@mappings")))
|
231
283
|
skeleton.merge!(Parameters: sort_json(TOPLEVEL_BINDING.eval("@parameters")))
|
232
284
|
skeleton.merge!(Resources: sort_json(TOPLEVEL_BINDING.eval("@resources")))
|
233
285
|
skeleton.merge!(Outputs: sort_json(TOPLEVEL_BINDING.eval("@outputs")))
|
234
|
-
TOPLEVEL_BINDING.eval("@variables = @resources = @outputs = @properties = @parameters = {}")
|
286
|
+
TOPLEVEL_BINDING.eval("@variables = @resources = @outputs = @properties = @mappings = @parameters = {}")
|
235
287
|
TOPLEVEL_BINDING.eval("@depends_on = []")
|
236
288
|
TOPLEVEL_BINDING.eval("@description = ''")
|
237
289
|
JSON.pretty_generate(skeleton.recursive_compact)
|
data/templates/compile.rb.erb
CHANGED
@@ -11,6 +11,6 @@ Module.constants.select do |mod|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
stacks.each do |stack_name, stack|
|
14
|
-
puts "- Saved #{stack_name} to build/#{stack_name.downcase}.json"
|
15
|
-
File.open("build/#{stack_name.downcase}.json", "w") { |f| f.write(stack) }
|
14
|
+
puts "- Saved #{stack_name} to build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json"
|
15
|
+
File.open("build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json", "w") { |f| f.write(stack) }
|
16
16
|
end
|
@@ -20,6 +20,24 @@ module <%= name %>Stack
|
|
20
20
|
r.property(:name) { example_variable }
|
21
21
|
end
|
22
22
|
|
23
|
+
# Example VPC, creates VPC, IGW, Route, and VPCGatewayAttachment
|
24
|
+
# Settable variables:
|
25
|
+
# - cidr_block (defaults to 10.0.0.0/16)
|
26
|
+
# - enable_dns_support (boolean, default true)
|
27
|
+
# - enable_dns_hostnames (boolean, default true)
|
28
|
+
# - instance_tenancy (`default` or `dedicated`)
|
29
|
+
resource :my_first,
|
30
|
+
type: RubyCfn::VPC do |r|
|
31
|
+
r.set(:cidr_block) { "10.1.0.0/16" }
|
32
|
+
end
|
33
|
+
variable :cidr_block,
|
34
|
+
default: "10.0.0.0/16"
|
35
|
+
variable :enable_dns_support,
|
36
|
+
default: true
|
37
|
+
variable :enable_dns_hostnames,
|
38
|
+
default: true
|
39
|
+
variable :instance_tenancy,
|
40
|
+
filter: :validate_instance_tenancy
|
23
41
|
# Example resource, dynamically generated name
|
24
42
|
resource :my_example_s3_bucket,
|
25
43
|
type: "AWS::S3::Bucket"
|
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.1.
|
4
|
+
version: 0.1.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: 2018-
|
11
|
+
date: 2018-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: neatjson
|
@@ -263,6 +263,9 @@ files:
|
|
263
263
|
- Rakefile
|
264
264
|
- bin/rubycfn
|
265
265
|
- lib/cli_methods.rb
|
266
|
+
- lib/compound.rb
|
267
|
+
- lib/compound/resources.rb
|
268
|
+
- lib/compound/vpc.rb
|
266
269
|
- lib/rubycfn.rb
|
267
270
|
- lib/rubycfn/version.rb
|
268
271
|
- rubycfn.gemspec
|