rubycfn 0.2.1 → 0.3.0

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: b0849cb139ac3748d7b632536c72f4cfdd24cbdb
4
- data.tar.gz: a2dfc5d8d89ea55f7ca693ebd264f71f4b37efe7
3
+ metadata.gz: 7f56448eca7fe5adea74e68fd2b33d2e92919150
4
+ data.tar.gz: bf9b226d2110b922e81adcb5acc7ef6d67a51182
5
5
  SHA512:
6
- metadata.gz: d84760f33c8903f332e4b78c969768bf550a7b25ae50c4df22f0cdf0b9572ba7439c1cfc6ffa8b19bc93b9e4f647c841d2b5d783b46c41c772d263186b78f908
7
- data.tar.gz: 281ed98ef84978bc640d4ab7ffd475fa2c9d30777e81007aca22ee3dded7ffe53e36804abb744fd68f9d7492a5cff7b20b1f1f0317408a9c9bec2b8d445b7c43
6
+ metadata.gz: 0d01000310dc22988c4c9658c7900366d62d00f1f27d5181f1498ab8d59796160674b987eb32f922364a6cef4867ddbe554bbba4067df11cdc68f15ebc0befc0
7
+ data.tar.gz: 71b2895125dc7fc470e6b9166fa4021b0a9a15331992c8bcfa8952337288859394343d885c831b27607f79a4891cc5e44f55482f6c48e013eb16c7ed44a70cf4
data/CHANGELOG.md CHANGED
@@ -2,8 +2,11 @@
2
2
  All notable changes to Rubycfn will be documented in this file.
3
3
  This project uses [Semantic Versioning](http://semver.org/).
4
4
 
5
- ## 0.2.2 (Next Release)
5
+ ## 0.3.1 (Next Release)
6
6
 
7
+ ## 0.3.0
8
+ * Removed non-AWS code. For non-AWS resources pin to 0.2.1 -- [@dennisvink][@dennisvink]
9
+
7
10
  ## 0.2.1
8
11
  * Fixed bug in VPC compound resource. Resource names are now camel cased -- [@dennisvink][@dennisvink]
9
12
  * Updated README.md -- [@dennisvink][@dennisvink]
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubycfn (0.2.1)
4
+ rubycfn (0.3.0)
5
5
  activesupport (~> 5.1.5)
6
6
  dotenv (~> 2.4.0)
7
7
  json (~> 2.1.0)
@@ -11,25 +11,25 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activesupport (5.1.6)
14
+ activesupport (5.1.7)
15
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
16
  i18n (>= 0.7, < 2)
17
17
  minitest (~> 5.1)
18
18
  tzinfo (~> 1.1)
19
- addressable (2.5.2)
19
+ addressable (2.6.0)
20
20
  public_suffix (>= 2.0.2, < 4.0)
21
21
  awesome_print (1.8.0)
22
22
  coderay (1.1.2)
23
- concurrent-ruby (1.0.5)
23
+ concurrent-ruby (1.1.5)
24
24
  diff-lcs (1.3)
25
25
  docile (1.3.1)
26
26
  dotenv (2.4.0)
27
27
  equatable (0.5.0)
28
- ffi (1.9.25)
28
+ ffi (1.10.0)
29
29
  formatador (0.2.5)
30
30
  given_core (3.8.0)
31
31
  sorcerer (>= 0.3.7)
32
- guard (2.14.2)
32
+ guard (2.15.0)
33
33
  formatador (>= 0.2.4)
34
34
  listen (>= 2.7, < 4.0)
35
35
  lumberjack (>= 1.0.12, < 2.0)
@@ -43,8 +43,7 @@ GEM
43
43
  guard (~> 2.1)
44
44
  guard-compat (~> 1.1)
45
45
  rspec (>= 2.99.0, < 4.0)
46
- hitimes (1.3.0)
47
- i18n (1.1.1)
46
+ i18n (1.6.0)
48
47
  concurrent-ruby (~> 1.0)
49
48
  json (2.1.0)
50
49
  launchy (2.4.3)
@@ -54,7 +53,7 @@ GEM
54
53
  rb-inotify (~> 0.9, >= 0.9.7)
55
54
  ruby_dep (~> 1.2)
56
55
  lumberjack (1.0.13)
57
- method_source (0.9.0)
56
+ method_source (0.9.2)
58
57
  minitest (5.11.3)
59
58
  neatjson (0.8.4)
60
59
  necromancer (0.4.0)
@@ -65,14 +64,14 @@ GEM
65
64
  pastel (0.7.2)
66
65
  equatable (~> 0.5.0)
67
66
  tty-color (~> 0.4.0)
68
- pry (0.11.3)
67
+ pry (0.12.2)
69
68
  coderay (~> 1.1.0)
70
69
  method_source (~> 0.9.0)
71
70
  public_suffix (3.0.3)
72
71
  rake (10.5.0)
73
72
  rb-fsevent (0.10.3)
74
- rb-inotify (0.9.10)
75
- ffi (>= 0.5.0, < 2)
73
+ rb-inotify (0.10.0)
74
+ ffi (~> 1.0)
76
75
  rspec (3.8.0)
77
76
  rspec-core (~> 3.8.0)
78
77
  rspec-expectations (~> 3.8.0)
@@ -85,7 +84,7 @@ GEM
85
84
  rspec-given (3.8.0)
86
85
  given_core (= 3.8.0)
87
86
  rspec (>= 2.14.0)
88
- rspec-its (1.2.0)
87
+ rspec-its (1.3.0)
89
88
  rspec-core (>= 3.0.0)
90
89
  rspec-expectations (>= 3.0.0)
91
90
  rspec-mocks (3.8.0)
@@ -102,10 +101,9 @@ GEM
102
101
  simplecov-html (~> 0.10.0)
103
102
  simplecov-html (0.10.2)
104
103
  sorcerer (1.0.2)
105
- thor (0.20.0)
104
+ thor (0.20.3)
106
105
  thread_safe (0.3.6)
107
- timers (4.1.2)
108
- hitimes
106
+ timers (4.3.0)
109
107
  tty-color (0.4.3)
110
108
  tty-cursor (0.5.0)
111
109
  tty-prompt (0.16.1)
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # RubyCfn
2
2
 
3
3
  [RubyCfn](https://rubycfn.com/) is a light-weight tiny CloudFormation, Deployment Manager and ARM DSL to make expressing
4
- cloud vendor templates as Ruby code a bit more pleasing to the eye.
4
+ AWS templates as Ruby code a bit more pleasing to the eye.
5
5
 
6
6
  ## Quick start
7
7
 
@@ -10,7 +10,7 @@ Install Rubycfn:
10
10
 
11
11
  Starting a new Rubycfn project:
12
12
  `rubycfn`
13
- $ rubycfn
13
+ ```$ rubycfn
14
14
  __________ ____ __________________.___._________ _____________________
15
15
  \______ \ | \______ \__ | |\_ ___ \\_ _____/\______ \
16
16
  | _/ | /| | _// | |/ \ \/ | __) | | _/
@@ -20,6 +20,7 @@ __________ ____ __________________.___._________ _____________________
20
20
  Project name? example
21
21
  Account ID? 1234567890
22
22
  Select region EU (Frankfurt)
23
+ ```
23
24
 
24
25
  Installing project dependencies:
25
26
  `bundle`
@@ -45,7 +46,7 @@ Standardisation is key to keep your engineering team agile. Time spent on projec
45
46
 
46
47
  ## Overview of Rubycfn
47
48
 
48
- RubyCfn is an abstraction layer around several Cloud templates such as CloudFormation (AWS), Deployment Manager (GCP) and ARM (Azure). Rubycfn projects are set up for easy grouping of resources that have a mutual cohesion, and structured in such a way to make it easy for developers to quickly find what they need. Rubycfn is a so-called ‘DSL’ on top of these template formats and presents templates as code that is friendly to the eye and easy to read and understand. In addition of being an alternate representation of a template, Rubycfn allows you to combine template generation with programming logic making it far more versatile than what the respective cloud providers offer in their templates. Last but not least Rubycfn enforces code quality by testing the generated templates against unit tests, checking if the expected resources and their configuration matches with what was actually generated, and by LINTing the templates and the underlying code that generates the templates.
49
+ RubyCfn is an abstraction layer around several Cloud templates such as CloudFormation (AWS). Rubycfn projects are set up for easy grouping of resources that have a mutual cohesion, and structured in such a way to make it easy for developers to quickly find what they need. Rubycfn is a so-called ‘DSL’ on top of these template formats and presents templates as code that is friendly to the eye and easy to read and understand. In addition of being an alternate representation of a template, Rubycfn allows you to combine template generation with programming logic making it far more versatile than what AWS offers in their templates. Last but not least Rubycfn enforces code quality by testing the generated templates against unit tests, checking if the expected resources and their configuration matches with what was actually generated, and by LINTing the templates and the underlying code that generates the templates.
49
50
 
50
51
  Out of the box Rubycfn comes with a CI/CD pipeline. It’s a serverless pipeline running on Amazon Web Services (AWS), which you can fully configure using the complimentary `buildspec.yml`. The CI/CD pipeline is linked to a Github repository, and a change in this repository triggers the CI/CD pipeline to execute the steps you’ve defined in the buildspec.yml.
51
52
 
@@ -56,7 +57,7 @@ Typically a commit to your application GIT repository triggers the build process
56
57
  - Application (unit) tests are ran
57
58
  - The build artifact is stored (versioned), so you can use it as input for your delivery pipeline
58
59
  - The artifact may or may not include the application code. A part of the build process could - for example - also be that the application is dockerized and pushed to a docker registry.
59
- - The resulting artifact is the complete recipe to deploy the application and associated resources to AWS, GCP or Azure.
60
+ - The resulting artifact is the complete recipe to deploy the application and associated resources to AWS
60
61
 
61
62
  ## Example code
62
63
 
@@ -259,9 +260,10 @@ First the flat files:
259
260
  `.env` and `.env.test` are files where you store environment variables that you may want to use in your project code. The difference between the .env and the .env.test file is that the .env file is the “global” environment variable file, whereas the .env.test file is an environment-specific environment variable file, that can override values you’ve specified in your .env file (or add new environment variables, for that matter). You’d typically have a .env.test, .env.acceptance and a .env.production file for things like instance sizing.
260
261
 
261
262
  Example:
262
- $ cat .env.test
263
+ ```$ cat .env.test
263
264
  # ENV vars for test environment
264
265
  APPLICATION_INSTANCE_CLASS="t2.micro"
266
+ ```
265
267
 
266
268
  To make use of - for example - .env.production as source, you can either override the ENVIRONMENT variable in the .env file, setting it to production, or you can invoke rake as: `ENVIRONMENT="production" rake`.
267
269
 
@@ -272,6 +274,7 @@ The `Rakefile` contain the tasks that are performed when you type the `rake` com
272
274
  `cfn2rubycfn` is a small helper script that converts AWS CloudFormation scripts to Rubycfn code. This allows you to migrate your existing projects over to Rubycfn quickly. It exports the converted CloudFormation script to `generated.rb`, a ready to use module for your stacks.
273
275
 
274
276
  Example:
277
+ ```
275
278
  $ cat sample.json
276
279
  {
277
280
  "AWSTemplateFormatVersion": "2010-09-09",
@@ -300,6 +303,7 @@ module ConvertedStack
300
303
  end
301
304
  end
302
305
  end
306
+ ```
303
307
 
304
308
  The `format.vim` file is used by the CloudFormation conversion script to reindent the file after conversion. You can make changes to the file to reflect your preferred style of code indentation.
305
309
 
@@ -308,16 +312,18 @@ Onto the subdirectories:
308
312
  The `build` directory is where all the compiled templates end up.
309
313
 
310
314
  Example:
315
+ ```
311
316
  $ ls -al build/
312
317
  total 24
313
318
  drwxr-xr-x 4 binx staff 128 Oct 17 16:27 .
314
319
  drwxr-xr-x 16 binx staff 512 Oct 17 16:27 ..
315
- -rw-r--r-- 1 binx staff 3197 Oct 17 16:27 test-gcp-demostack.json
316
320
  -rw-r--r-- 1 binx staff 4152 Oct 17 16:27 test-aws-demostack.json
321
+ ```
317
322
 
318
323
  The `spec` directory is where your unit tests live. These are not your application unit tests. A Rubycfn project lives in another universe than your application code. These unit tests test your expectations of the generated templates against reality. Such tests typically check for the existence and absence of particular resources, and values of properties. The tests are always executed when you run the `rake` command or the `rake spec` command. By default a project comes with unit tests that amongst other things check for the generation of the CI/CD pipeline and if it’s been configured correctly.
319
324
 
320
325
  Example:
326
+ ```
321
327
  context "Codebuild Service Role" do
322
328
  let(:code_build_service_role) { resources["CodeBuildDemoServiceRole"] }
323
329
  subject { code_build_service_role }
@@ -347,6 +353,7 @@ Example:
347
353
  end
348
354
  end
349
355
  end
356
+ ```
350
357
 
351
358
  The `config` directory contains your buildspec.yml, which contain all the instructions for the build pipeline. It’s also possible to source the buildspec.yml from another source, such as the application repository.
352
359
 
@@ -354,6 +361,7 @@ And finally, the `lib` directory contains all the relevant project code. The `li
354
361
 
355
362
  There are two directories under `lib`, namely `shared_concerns` and `stacks`. Concerns in this context simply mean Modules. Rubycfn relies on the ActiveConcern gem which makes modularisation of code very easy. The `shared_concerns` directory contains modules that can be used by several stacks. By default it has a `global_variables` module containing the following:
356
363
 
364
+ ```
357
365
  module Concerns
358
366
  module GlobalVariables
359
367
  extend ActiveSupport::Concern
@@ -366,12 +374,13 @@ module Concerns
366
374
  end
367
375
  end
368
376
  end
369
-
377
+ ```
370
378
  This module exposes a variable `environment`, which defaults to `test` if not set. It sources the value from the ENVIRONMENT environment variable. This variable can be used throughout your project at any place you see fit.
371
379
 
372
380
  The `stacks` directory is a container for all stacks that you want to generate. There is no limitation to the amount of stacks that it supports. By default, it comes with a single stack for your project:
373
381
 
374
382
  Example `lib/stacks/demo_stack.rb`:
383
+ ```
375
384
  module DemoStack
376
385
  extend ActiveSupport::Concern
377
386
  include Rubycfn
@@ -381,7 +390,7 @@ module DemoStack
381
390
  include DemoStack::CICD
382
391
  end
383
392
  end
384
-
393
+ ```
385
394
  Our stack file consists of two modules: Main and CICD. When compiling the code, the combined result of the Main and CICD module will be written to the DemoStack json file in the build/ directory. Modularising stacks allows for separation of code by cohesion or any other logic you deem appropriate.
386
395
 
387
396
  The stacks directory also contains a directory that is named the same, minus the .rb extension: `lib/stacks/demo_stack/`
@@ -389,63 +398,26 @@ The stacks directory also contains a directory that is named the same, minus the
389
398
  All the stack modules live inside this directory. The modules that make up the stack are the actual implementation of the resources, parameters and outputs.
390
399
 
391
400
  An example of such a module:
401
+ ```
392
402
  module DemoStack
393
403
  module Main
394
404
  extend ActiveSupport::Concern
395
405
  included do
396
- import(
397
- path: "cloudsql.jinja"
398
- )
399
406
 
400
407
  resource :api_gateway_rest_api,
401
408
  type: "AWS::ApiGateway::RestApi" do |r|
402
409
  r.property(:name) { "#{environment}-webhook" }
403
410
  end
404
-
405
- resource "cloudsql",
406
- type: "GCP::cloudsql.jinja" do |r|
407
- r.property("database") do
408
- {
409
- "name": "#{environment}"
410
- }
411
- end
412
- r.property("dbUser") do
413
- {
414
- "password": "test123_"
415
- }
416
- end
417
- r.property("failover") { true }
418
- r.property("readReplicas") { 1 }
419
- end
420
411
  end
421
412
  end
422
413
  end
423
-
424
- When compiling the project, Rubycfn will recognise the resources for the different Cloud providers and write them to separate template files. When building a cloud agnostic solution, you implement the resources for the respective vendors. To decide which resources are deployed to which cloud provider, and to be able to switch them quickly, you can wrap the resources with `if` statements, but a better solution is to utilise the `amount` property for resources:
425
-
426
- variable :cloudsql_vendor,
427
- default: "GCP",
428
- value: ENV["CLOUDSQL_VENDOR"]
429
-
430
- resource "cloudsql",
431
- amount: cloudsql_vendor == "GCP" ? 1 : 0,
432
- type: "GCP::cloudsql.jinja" do |r|
433
- ...
434
- end
435
-
436
- resource "cloudsql",
437
- amount: cloudsql_vendor == "ARM" ? 1 : 0,
438
- type: "ARM::MSSQL" do |r|
439
- ...
440
- end
441
-
442
- By implementing resources in the above way you can switch particular resources to another cloud vendor by simply updating the environment variable in your CI/CD pipeline, while still being able to use the same variables and the same ecosystem.
414
+ ```
443
415
 
444
416
  ## License
445
417
 
446
418
  MIT License
447
419
 
448
- Copyright (c) 2018 Dennis Vink
420
+ Copyright (c) 2019 Dennis Vink
449
421
 
450
422
  Permission is hereby granted, free of charge, to any person obtaining a copy of
451
423
  this software and associated documentation files (the "Software"), to deal in
data/format.vim ADDED
@@ -0,0 +1,3 @@
1
+ gg=G
2
+ :retab
3
+ ZZ
@@ -1,4 +1,4 @@
1
1
  # Rubycfn version
2
2
  module Rubycfn
3
- VERSION = "0.2.1"
3
+ VERSION = "0.3.0"
4
4
  end
data/lib/rubycfn.rb CHANGED
@@ -14,8 +14,6 @@ require "rubycfn/version"
14
14
  @mappings = {}
15
15
  @conditions = {}
16
16
  @AWSresources = {}
17
- @GCPresources = []
18
- @MSFresources = {}
19
17
  @imports = []
20
18
  @resource_name = ""
21
19
  @variables = {}
@@ -274,10 +272,6 @@ module Rubycfn
274
272
  end
275
273
  end
276
274
 
277
- def self.import(gcp_import)
278
- TOPLEVEL_BINDING.eval("@imports.push(#{gcp_import})")
279
- end
280
-
281
275
  def self.depends_on(resources)
282
276
  case resources
283
277
  when String
@@ -338,24 +332,15 @@ module Rubycfn
338
332
  TOPLEVEL_BINDING.eval("@resource_name = ''")
339
333
  end
340
334
 
341
- if arguments[:cloud] == "AWS"
342
- res = {
343
- "#{name.to_s}#{i == 0 ? "" : resource_postpend}": {
344
- DependsOn: TOPLEVEL_BINDING.eval("@depends_on"),
345
- Properties: TOPLEVEL_BINDING.eval("@properties"),
346
- Type: arguments[:type],
347
- Condition: arguments[:condition]
348
- }
349
- }
350
- TOPLEVEL_BINDING.eval("@AWSresources = @AWSresources.deep_merge(#{res})")
351
- elsif arguments[:cloud] == "GCP"
352
- res = {
353
- "name": "#{name.to_s}",
354
- "type": "#{arguments[:type].to_s.gsub(/GCP::/, "")}",
355
- "properties": TOPLEVEL_BINDING.eval("@properties")
335
+ res = {
336
+ "#{name.to_s}#{i == 0 ? "" : resource_postpend}": {
337
+ DependsOn: TOPLEVEL_BINDING.eval("@depends_on"),
338
+ Properties: TOPLEVEL_BINDING.eval("@properties"),
339
+ Type: arguments[:type],
340
+ Condition: arguments[:condition]
356
341
  }
357
- TOPLEVEL_BINDING.eval("@GCPresources.push(#{res})")
358
- end
342
+ }
343
+ TOPLEVEL_BINDING.eval("@AWSresources = @AWSresources.deep_merge(#{res})")
359
344
  end
360
345
  TOPLEVEL_BINDING.eval("@depends_on = []")
361
346
  TOPLEVEL_BINDING.eval("@properties = {}")
@@ -383,15 +368,6 @@ module Rubycfn
383
368
  TOPLEVEL_BINDING.eval("@depends_on = []")
384
369
  TOPLEVEL_BINDING.eval("@description = ''")
385
370
  JSON.pretty_generate(skeleton.recursive_compact)
386
- when "GCP"
387
- gcp_skeleton = {}
388
- gcp_skeleton = JSON.parse(gcp_skeleton.to_json)
389
- gcp_skeleton.merge!(imports: TOPLEVEL_BINDING.eval("@imports"))
390
- gcp_skeleton.merge!(resources: sort_json(TOPLEVEL_BINDING.eval("@GCPresources")))
391
- TOPLEVEL_BINDING.eval("@variables = @outputs = @properties = @mappings = @parameters = {}")
392
- TOPLEVEL_BINDING.eval("@imports = @GCPresources = @depends_on = []")
393
- TOPLEVEL_BINDING.eval("@description = ''")
394
- JSON.pretty_generate(gcp_skeleton.recursive_compact)
395
371
  end
396
372
  end
397
373
  end
@@ -7,8 +7,6 @@ stacks = {}
7
7
 
8
8
  Module.constants.select do |mod|
9
9
  if mod =~ /Stack$/
10
- send("include", Object.const_get("SharedConcerns"))
11
- google_stacks[mod.to_sym] = send("include", Object.const_get(mod)).render_template("GCP")
12
10
  send("include", Object.const_get("SharedConcerns"))
13
11
  stacks[mod.to_sym] = send("include", Object.const_get(mod)).render_template("AWS")
14
12
  end
@@ -18,8 +16,3 @@ stacks.each do |stack_name, stack|
18
16
  puts "- Saved #{stack_name} to build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json"
19
17
  File.open("build/#{ENV["ENVIRONMENT"]}-#{stack_name.downcase}.json", "w") { |f| f.write(stack) }
20
18
  end
21
-
22
- google_stacks.each do |stack_name, stack|
23
- puts "- Saved #{stack_name} to build/#{ENV["ENVIRONMENT"]}-gcp-#{stack_name.downcase}.json"
24
- File.open("build/#{ENV["ENVIRONMENT"]}-gcp-#{stack_name.downcase}.json", "w") { |f| f.write(stack) }
25
- end
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.2.1
4
+ version: 0.3.0
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-10-19 00:00:00.000000000 Z
11
+ date: 2019-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: neatjson
@@ -263,6 +263,7 @@ files:
263
263
  - README.md
264
264
  - Rakefile
265
265
  - bin/rubycfn
266
+ - format.vim
266
267
  - lib/cli_methods.rb
267
268
  - lib/compound.rb
268
269
  - lib/compound/resources.rb