rubycfn 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c09925e14474150813c8cc1fc68f659c2fd9b4f6
4
- data.tar.gz: 147d961011de3e4452b273cd9d7192fa14bfa50a
3
+ metadata.gz: 7d01bd17b4d8c71bd2377cbee3606eddb28778df
4
+ data.tar.gz: 7d92a19ab91e083aed1492c4b0a00f74b01896d4
5
5
  SHA512:
6
- metadata.gz: a2d9cc012275a915b20b7ceaaf952d40d741d74b1efb5b22f5d84c62d448e000f9ad021607a53a12ed4e94d252331ece33cb6725fb3ce0af9a90e3c85b8d5fad
7
- data.tar.gz: 4f4fd5565902584c1568bb5ed8198783a2f3ba6befe96a3a20d9de65206ddf2c6b4ccc46f261ec1d9fafb65d3fea5e26e2aa19c2cd3ad68bb260508c9293d985
6
+ metadata.gz: d3708591c58295896ef5a5b46924eead40ace9744a800a52361842d6e6057f4639bc87f13ee2bc80e50dc7e879b3f8fd51a8687e8e9bb2c1a5c37c6eab9191e8
7
+ data.tar.gz: 9174d991980b0ec38e0b2d92894f9de68307c1f0fc82f14b0fdcad7d347bd412ba61d319d108ecb2c1f2a11b930ad152fa7f13a5e08aba25c3b14fda516af831
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubycfn (0.1.1)
4
+ rubycfn (0.1.2)
5
5
  activesupport (~> 5.1.5)
6
6
  dotenv (~> 2.4.0)
7
7
  json (~> 2.1.0)
data/README.md CHANGED
@@ -12,7 +12,7 @@ or, create a Gemfile with this content:
12
12
  ```
13
13
  source "https://rubygems.org"
14
14
 
15
- gem "rubycfn", "~> 0.1.1"
15
+ gem "rubycfn", "~> 0.1.2"
16
16
 
17
17
  ```
18
18
 
@@ -0,0 +1 @@
1
+ require_relative "vpc"
@@ -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"
@@ -1,4 +1,4 @@
1
1
  # Rubycfn version
2
2
  module Rubycfn
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.2"
4
4
  end
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][name, resource_suffix, &block])
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)
@@ -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.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-06-29 00:00:00.000000000 Z
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