rubycfn 0.1.8 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0b96f071bbb09b6b63d1b9671330ecccdf35e0c
4
- data.tar.gz: ab86d11cdf67f1de25a9a0fa6a84ad2b9e79af86
3
+ metadata.gz: a50e005191c0b01c26c19c2947b21aa68efc4484
4
+ data.tar.gz: b2d40bc520b69a35494e6a69f822571d7c05bacf
5
5
  SHA512:
6
- metadata.gz: fac7d3197bccd39005f3fb1e312db165db6b2ff938d16f40ff89139f86bf868c85be6b96fc3797e1405a509dc020bd17aa20d9f198454f21976727df77be9a4c
7
- data.tar.gz: 63c4c0164126765d8ddadae458c4b505545f99fa518c3d1e7b385ede3e6c0946463891ac0c6f52296a75b843eb417bb8d26a1728aac1921eae358ef82b826443
6
+ metadata.gz: 5b11a4f464588c4bc027154ce588fbd26837007a3da6c60abd11e3834d016b492272f85befbb03d40cc2ad2a90649b4622db6e3292755031ec40126d4f7f8b44
7
+ data.tar.gz: 1226f8c46e3b2e9c458a49f67c24cc2dd7599a3e6e6d28add060367ec52c9ec0e03174283509ce9ac6217d2a408ef833a0798a47306dfa48537607501c51ca8c
data/CHANGELOG.md CHANGED
@@ -2,10 +2,13 @@
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.1.9 (Next Release)
5
+ ## 0.1.10 (Next Release)
6
+
7
+ ## 0.1.9
8
+ * Merged feature/cicd into release :')
6
9
 
7
10
  ## 0.1.8
8
- * `Export` in outputs now takes both strings and hashes
11
+ * `Export` in outputs now takes both strings and hashes -- [@dennisvink][@dennisvink]
9
12
 
10
13
  ## 0.1.7
11
14
  * Added specs to default project -- [@dennisvink][@dennisvink]
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubycfn (0.1.8)
4
+ rubycfn (0.1.9)
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.8"
15
+ gem "rubycfn", "~> 0.1.9"
16
16
 
17
17
  ```
18
18
 
@@ -24,6 +24,10 @@ Typing `rubycfn` at the prompt and answering its questions generates a new sampl
24
24
 
25
25
  You can find stack examples at [https://github.com/dennisvink/rubycfn-example](https://github.com/dennisvink/rubycfn-example/)
26
26
 
27
+ ## Installing Gems
28
+
29
+ Type `bundle install` to install all dependencies that are listed in the Gemfile.
30
+
27
31
  ## Running specs
28
32
 
29
33
  Type `rake` to run the tests. It tests if RubyCfn creates a valid
data/bin/rubycfn CHANGED
@@ -32,14 +32,18 @@ dotenv = render('.env', {
32
32
  :region => region
33
33
  }, path)
34
34
 
35
+ buildspec = render('buildspec.yml', {}, path)
36
+ cicd = render('cicd.rb', { name: project_name.capitalize, small_name: project_name }, path)
37
+ compile = render('compile.rb', {}, path)
35
38
  dotenv_test = render('.env.test', { project_name: project_name }, path)
39
+ example_spec = render('example_stack_spec.rb', { name: project_name.capitalize }, path)
36
40
  gemfile = render('Gemfile', { version: Rubycfn::VERSION }, path)
37
- rakefile = render('Rakefile', {}, path)
38
- main = render('main.rb', {}, path)
39
- compile = render('compile.rb', {}, path)
40
41
  global_variables = render('global_variables.rb', {}, path)
41
- project_stack = render('project_stack.rb', { name: project_name.capitalize }, path)
42
+ main = render('main.rb', {}, path)
42
43
  project_concern = render('project_concern.rb', { name: project_name.capitalize }, path)
44
+ project_stack = render('project_stack.rb', { name: project_name.capitalize }, path)
45
+ rakefile = render('Rakefile', {}, path)
46
+ spec_helper = render('spec_helper.rb', {}, path)
43
47
 
44
48
  # Create directory structure
45
49
  FileUtils.mkdir_p project_path + '/lib/stacks/' + project_name + '_stack'
@@ -51,9 +55,13 @@ File.open("#{project_path}/.env", 'w') { |file| file.write(dotenv) }
51
55
  File.open("#{project_path}/.env.test", 'w') { |file| file.write(dotenv_test) }
52
56
  File.open("#{project_path}/Gemfile", 'w') { |file| file.write(gemfile) }
53
57
  File.open("#{project_path}/Rakefile", 'w') { |file| file.write(rakefile) }
58
+ File.open("#{project_path}/config/buildspec.yml", 'w') { |file| file.write(buildspec) }
54
59
  File.open("#{project_path}/lib/main.rb", 'w') { |file| file.write(main) }
55
60
  File.open("#{project_path}/lib/compile.rb", 'w') { |file| file.write(compile) }
56
61
  File.open("#{project_path}/lib/shared_concerns/global_variables.rb", 'w') { |file| file.write(global_variables) }
57
62
  File.open("#{project_path}/lib/stacks/#{project_name}_stack.rb", 'w') { |file| file.write(project_stack) }
58
63
  File.open("#{project_path}/lib/stacks/#{project_name}_stack/example.rb", 'w') { |file| file.write(project_concern) }
64
+ File.open("#{project_path}/lib/stacks/#{project_name}_stack/cicd.rb", 'w') { |file| file.write(cicd) }
65
+ File.open("#{project_path}/spec/spec_helper.rb", 'w') { |file| file.write(spec_helper) }
66
+ File.open("#{project_path}/spec/lib/#{project_name}_spec.rb", 'w') { |file| file.write(example_spec) }
59
67
 
data/lib/cli_methods.rb CHANGED
@@ -39,7 +39,10 @@ def rubycfn_structure(project_name)
39
39
  [
40
40
  project_name,
41
41
  project_name + '/build',
42
+ project_name + '/config',
43
+ project_name + '/lib/shared_concerns',
42
44
  project_name + '/lib/stacks',
43
- project_name + '/lib/shared_concerns'
45
+ project_name + '/spec',
46
+ project_name + '/spec/lib'
44
47
  ]
45
48
  end
@@ -1,4 +1,4 @@
1
1
  # Rubycfn version
2
2
  module Rubycfn
3
- VERSION = "0.1.8"
3
+ VERSION = "0.1.9"
4
4
  end
data/lib/rubycfn.rb CHANGED
@@ -106,7 +106,7 @@ class ::Hash
106
106
 
107
107
  def recursive_compact
108
108
  delete_if do |k, v|
109
- next if v === false
109
+ next if v === false || k =~ /Fn\:/
110
110
  (v.respond_to?(:empty?) ? v.empty? : !v) or v.instance_of?(Hash) && v.recursive_compact.empty?
111
111
  end
112
112
  end
data/templates/.env.erb CHANGED
@@ -1,4 +1,5 @@
1
1
  AWS_ACCOUNT_ID="<%= account_id %>"
2
2
  AWS_REGION="<%= region %>"
3
- PROJECT_NAME="<%= project_name %>"
4
3
  ENVIRONMENT="test"
4
+ GITHUB_REPOSITORY="https://github.com/dennisvink/elastic-cloud-engineering/"
5
+ PROJECT_NAME="<%= project_name %>"
@@ -1,3 +1,9 @@
1
- source 'https://rubygems.org' do
2
- gem 'rubycfn', '~> <%= version %>'
1
+ source "https://rubygems.org" do
2
+ gem "rubycfn", "~> <%= version %>"
3
+ gem "rspec", "~> 3.2"
4
+ gem "rspec-its", "~> 1.2"
5
+ gem "rspec-given", "~> 3.7"
6
+ gem "rspec_junit_formatter", "~> 0.2"
7
+ gem "simplecov", "~> 0.16.1"
8
+ gem "launchy", "~> 2.4.3"
3
9
  end
@@ -1,6 +1,12 @@
1
1
  require "rubygems"
2
2
  require "bundler"
3
- Bundler.setup
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new do |t|
6
+ t.rspec_opts = \
7
+ " --format RspecJunitFormatter" \
8
+ " --out test-reports/rspec.xml"
9
+ end
4
10
 
5
11
  desc "Compile CloudFormation"
6
12
  task :compile do
@@ -8,4 +14,4 @@ task :compile do
8
14
  require_relative "lib/compile"
9
15
  end
10
16
 
11
- task default: [:compile]
17
+ task default: %i(spec compile)
@@ -0,0 +1,21 @@
1
+ version: 0.1
2
+
3
+ phases:
4
+ install:
5
+ commands:
6
+ - gem install cfn-nag
7
+ - bundle install
8
+ pre_build:
9
+ commands:
10
+ - echo Do nothing
11
+ build:
12
+ commands:
13
+ - echo Build started on `date`
14
+ - rake
15
+ - cfn_nag_scan --input-path build
16
+ post_build:
17
+ commands:
18
+ - echo Build completed on `date`
19
+ artifacts:
20
+ files:
21
+ - ./**
@@ -0,0 +1,91 @@
1
+ module <%= name %>Stack
2
+ module CICD
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ variable :github_repository,
7
+ default: "https://github.com/dennisvink/elastic-cloud-engineering/",
8
+ value: ENV["GITHUB_REPOSITORY"]
9
+
10
+ resource :code_build_<%= small_name %>_service_role,
11
+ type: "AWS::IAM::Role" do |r|
12
+ r.property(:assume_role_policy_document) do
13
+ {
14
+ "Version": "2012-10-17",
15
+ "Statement": [
16
+ {
17
+ "Effect": "Allow",
18
+ "Principal": {
19
+ "Service": [
20
+ "codebuild.amazonaws.com"
21
+ ]
22
+ },
23
+ "Action": [
24
+ "sts:AssumeRole"
25
+ ]
26
+ }
27
+ ]
28
+ }
29
+ end
30
+ r.property(:path) { "/service-role/" }
31
+ r.property(:policies) do
32
+ [
33
+ {
34
+ "PolicyName": "CodeBuildAccessPolicies",
35
+ "PolicyDocument": {
36
+ "Version": "2012-10-17",
37
+ "Statement": [
38
+ {
39
+ "Effect": "Allow",
40
+ "Action": [
41
+ "logs:CreateLogGroup",
42
+ "logs:CreateLogStream",
43
+ "logs:PutLogEvents"
44
+ ],
45
+ "Resource": [
46
+ "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*".fnsub
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ }
52
+ ]
53
+ end
54
+ end
55
+
56
+ resource :code_build_<%= small_name %>_project,
57
+ type: "AWS::CodeBuild::Project" do |r|
58
+ r.property(:name) { "<%= name %>-project-${AWS::Region}-${AWS::StackName}".fnsub }
59
+ r.property(:service_role) { "code_build_<%= small_name %>_service_role".cfnize.ref("Arn") }
60
+ r.property(:artifacts) do
61
+ {
62
+ "Type": "no_artifacts"
63
+ }
64
+ end
65
+ r.property(:environment) do
66
+ {
67
+ "Type": "LINUX_CONTAINER",
68
+ "ComputeType": "BUILD_GENERAL1_SMALL",
69
+ "Image": "aws/codebuild/ruby:2.3.1"
70
+ }
71
+ end
72
+ r.property(:source) do
73
+ {
74
+ "BuildSpec": text = File.read("config/buildspec.yml"),
75
+ "Auth": {
76
+ "Type": "OAUTH"
77
+ },
78
+ "Location": "#{github_repository}",
79
+ "Type": "GITHUB"
80
+ }
81
+ end
82
+ r.property(:triggers) do
83
+ {
84
+ "Webhook": true
85
+ }
86
+ end
87
+ r.property(:timeout_in_minutes) { 10 }
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,101 @@
1
+ require "spec_helper"
2
+
3
+ require "rubycfn"
4
+ require "active_support/concern"
5
+ require_relative "../../lib/main.rb"
6
+
7
+ describe Rubycfn do
8
+ module RspecStack
9
+ extend ActiveSupport::Concern
10
+ include Rubycfn
11
+
12
+ included do
13
+ description "RSpec Stack"
14
+ include <%= name %>Stack::CICD
15
+ end
16
+ end
17
+
18
+ CloudFormation = include RspecStack
19
+ RspecStack = CloudFormation.render_template
20
+ Given(:json) { JSON.parse(RspecStack) }
21
+
22
+ context "Renders template" do
23
+ let(:template) { json }
24
+ subject { template }
25
+
26
+ it { should_not have_key "Parameters" }
27
+ it { should have_key "Resources" }
28
+
29
+ context "Has Codebuild Resources" do
30
+ let(:resources) { template["Resources"] }
31
+ subject { resources }
32
+
33
+ it { should have_key "CodeBuild<%= name %>Project" }
34
+ it { should have_key "CodeBuild<%= name %>ServiceRole" }
35
+
36
+ context "Codebuild Repository" do
37
+ let(:repository) { resources["CodeBuild<%= name %>Project"] }
38
+ subject { repository }
39
+
40
+ it { should have_key "Properties" }
41
+
42
+ context "Codebuild properties" do
43
+ let(:codebuild_properties) { repository["Properties"] }
44
+ subject { codebuild_properties }
45
+
46
+ it { should have_key "Artifacts" }
47
+ it { should have_key "Environment" }
48
+ it { should have_key "Name" }
49
+ it { should have_key "ServiceRole" }
50
+ it { should have_key "Source" }
51
+ it { should have_key "TimeoutInMinutes" }
52
+ it { should have_key "Triggers" }
53
+
54
+ context "Codebuild Auth Type" do
55
+ let(:auth_type) { codebuild_properties["Source"]["Auth"]["Type"] }
56
+ subject { auth_type }
57
+
58
+ it { should eq "OAUTH" }
59
+ end
60
+
61
+ context "Codebuild creates webhook" do
62
+ let(:webhook) { codebuild_properties["Triggers"]["Webhook"] }
63
+ subject { webhook }
64
+
65
+ it { should eq true }
66
+ end
67
+ end
68
+ end
69
+
70
+ context "Codebuild Service Role" do
71
+ let(:code_build_service_role) { resources["CodeBuild<%= name %>ServiceRole"] }
72
+ subject { code_build_service_role }
73
+
74
+ it { should have_key "Properties" }
75
+
76
+ context "Code build service role properties" do
77
+ let(:code_build_service_role_properties) { code_build_service_role["Properties"] }
78
+ subject { code_build_service_role_properties }
79
+
80
+ it { should have_key "AssumeRolePolicyDocument" }
81
+ it { should have_key "Path" }
82
+ it { should have_key "Policies" }
83
+
84
+ context "Code build service role policy document" do
85
+ let(:policy_document) { code_build_service_role_properties["Policies"][0]["PolicyDocument"] }
86
+ subject { policy_document }
87
+
88
+ it { should have_key "Statement" }
89
+
90
+ context "Code build service role actions" do
91
+ let(:statement) { policy_document["Statement"][0]["Action"] }
92
+ subject { statement }
93
+
94
+ it { should eq %w(logs:CreateLogGroup logs:CreateLogStream logs:PutLogEvents) }
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -19,8 +19,6 @@ module <%= name %>Stack
19
19
  default: true
20
20
  variable :enable_dns_hostnames,
21
21
  default: true
22
- variable :instance_tenancy,
23
- filter: :validate_instance_tenancy
24
22
 
25
23
  # Example resource, custom name
26
24
  resource :my_example_s3_bucket,
@@ -4,5 +4,6 @@ module <%= name %>Stack
4
4
 
5
5
  included do
6
6
  include <%= name %>Stack::Main
7
+ include <%= name %>Stack::CICD
7
8
  end
8
9
  end
@@ -0,0 +1,26 @@
1
+ require "simplecov"
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ end
5
+
6
+ require "json"
7
+ require "launchy"
8
+ require "rspec"
9
+ require "rspec/its"
10
+ require "rspec/given"
11
+
12
+ RSpec.configure do |config|
13
+ config.color = true
14
+ config.formatter = "documentation"
15
+
16
+ config.mock_with :rspec do |c|
17
+ c.syntax = %i(should expect)
18
+ end
19
+
20
+ config.filter_run_excluding broken: true
21
+ config.filter_run_excluding turn_off: true
22
+ config.filter_run focus: true
23
+ config.run_all_when_everything_filtered = true
24
+ config.filter_run_excluding :slow unless ENV["SLOW_SPECS"]
25
+ config.filter_run_excluding :debug unless ENV["DEBUG_SPECS"]
26
+ 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.1.8
4
+ version: 0.1.9
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-09-08 00:00:00.000000000 Z
11
+ date: 2018-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: neatjson
@@ -276,11 +276,15 @@ files:
276
276
  - templates/.env.test.erb
277
277
  - templates/Gemfile.erb
278
278
  - templates/Rakefile.erb
279
+ - templates/buildspec.yml.erb
280
+ - templates/cicd.rb.erb
279
281
  - templates/compile.rb.erb
282
+ - templates/example_stack_spec.rb.erb
280
283
  - templates/global_variables.rb.erb
281
284
  - templates/main.rb.erb
282
285
  - templates/project_concern.rb.erb
283
286
  - templates/project_stack.rb.erb
287
+ - templates/spec_helper.rb.erb
284
288
  homepage: https://github.com/dennisvink/rubycfn
285
289
  licenses:
286
290
  - MIT
@@ -310,3 +314,6 @@ test_files:
310
314
  - spec/lib/rubycfn_spec.rb
311
315
  - spec/spec_helper.rb
312
316
  - templates/.env.test.erb
317
+ - templates/buildspec.yml.erb
318
+ - templates/example_stack_spec.rb.erb
319
+ - templates/spec_helper.rb.erb