stackr 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ed539b980b7fb3b579691b37b7fd4e730cb3c58
4
+ data.tar.gz: 09df285fe2c3db0b1b1f658bd65d88c856291798
5
+ SHA512:
6
+ metadata.gz: 56a2d4cc0a7a07c1c57b6217abc091a12b593d1713467d8978a560389bd991590029b0c19cbadfa7efcce302d0abb3b0800ff977a027b8f258f787659f340aa2
7
+ data.tar.gz: 357b0e3ca89f0a0126c1ef54592161fd61153fa6bc13abcfaafe7f3ffaff1de23e0abe8e36b2059daeeabad6928d66ff9fdddf7d386a502b1fb5f5c044431ce5
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/sandbox
10
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ stackr
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in stackr.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Leaf Software Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Stackr
2
+
3
+ [![Build Status](https://travis-ci.org/LeafSoftware/stackr.svg?branch=master)](https://travis-ci.org/LeafSoftware/stackr)
4
+
5
+ Create CloudFormation templates using ruby DSL and launch them with a CLI.
6
+
7
+ ## TODO
8
+
9
+ * Add options to create-template to add boilerplate stuff like vpc, instance, etc
10
+ * Add tests for cli for all the exception handling
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'stackr'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install stackr
27
+
28
+ ## Configuration
29
+
30
+ You must configure your AWS credentials to use stackr. Refer to the ruby [aws-sdk](http://docs.aws.amazon.com/sdkforruby/api/).
31
+
32
+ ## Usage
33
+
34
+ ```
35
+ Commands:
36
+ stackr create-project PROJECT_NAME # create stackr project
37
+ stackr create-stack TEMPLATE # create a stack from TEMPLATE
38
+ stackr create-template TEMPLATE # create a new template generator
39
+ stackr delete-stack STACK # delete the stack named STACK
40
+ stackr generate-template TEMPLATE # write the template json file
41
+ stackr help [COMMAND] # Describe available commands
42
+ stackr list-stacks # list all stacks
43
+ stackr update-stack TEMPLATE # update the stack created from TEMPLATE
44
+ stackr validate-template TEMPLATE # Verify template and parameters
45
+ stackr version # show version
46
+ ```
47
+
48
+ 1. Create a project with ```stackr create-project myproject```
49
+ 2. Change directory into your project ```cd myproject```
50
+ 3. ```cp .env.example .env``` and edit ```.env```
51
+ 5. ```source .env```
52
+ 2. Create a template with ```stackr create-template mytemplate```
53
+ 3. Edit the new template in ```templates/mytemplate.rb``` adding parameters, resources, outputs, etc. See [cloudformation-ruby-dsl](https://github.com/bazaarvoice/cloudformation-ruby-dsl) for tips
54
+ 4. Run ```stackr generate-template mytemplate``` and review the json document created at ```templates/mytemplate.json```
55
+ 5. Create a CloudFormation stack from your template using ```stackr create-stack mytemplate```
56
+ 6. List all of your stacks with ```stackr list-stacks```
57
+ 7. Tear your stack down with ```stackr delete-stack mytemplate```
58
+
59
+ ## Parameter Mapping
60
+
61
+ Many times you want to include secrets as stack parameters. These secrets do not belong in your source code. So we hand them in as environment variables.
62
+
63
+ You can set up a mapping between stack parameters and environment variables using the template parameter_map method.
64
+
65
+ This example tells stackr to fill in the "Environment" stack parameter with the contents of $ENVIRONMENT when creating or updating the stack.
66
+
67
+ ```ruby
68
+ t.parameter_map = {
69
+ 'Environment' => 'ENVIRONMENT'
70
+ }
71
+ ```
72
+
73
+ You can use a ```.env``` file for your environment variables. It's included in the project .gitignore file.
74
+
75
+ ## Environment Map
76
+
77
+ You may want to use the same template to launch stacks in different environments (e.g. 'dev', 'prd', 'test'). You can edit ```includes/environment_map.rb``` to configure your different environments. This is useful when you are creating resources in different VPCs or Regions for different environments.
78
+
79
+ ## Contributing
80
+
81
+ Bug reports and pull requests are welcome on GitHub at https://github.com/LeafSoftware/stackr.
82
+
83
+
84
+ ## License
85
+
86
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/exe/stackr ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "stackr"
4
+
5
+ Stackr::Cli.start ARGV
data/lib/stackr/cli.rb ADDED
@@ -0,0 +1,193 @@
1
+ require 'thor'
2
+
3
+ module Stackr
4
+ class Cli < Thor
5
+
6
+ no_commands do
7
+ def project_path=(name)
8
+ @project_path = name
9
+ end
10
+
11
+ def project_path
12
+ @project_path || File.basename(Dir.getwd)
13
+ end
14
+
15
+ def templates_path=(path)
16
+ @templates_path = path
17
+ end
18
+
19
+ def templates_path()
20
+ @templates_path || 'templates'
21
+ end
22
+
23
+ def json_template_path(name)
24
+ File.join(templates_path, "#{name}.json")
25
+ end
26
+
27
+ # Only load the template the first time
28
+ def load_template(name)
29
+ if @template.nil?
30
+ template_file = File.join(templates_path, "#{name}.rb")
31
+ @template = Stackr::Template.load(template_file)
32
+ end
33
+ @template
34
+ end
35
+ end
36
+
37
+ ## version
38
+ desc 'version', 'show version'
39
+ def version
40
+ say Stackr::VERSION
41
+ end
42
+
43
+ ## project
44
+ include Thor::Actions
45
+ def self.source_root
46
+ File.join(File.dirname(__FILE__),'..','..')
47
+ end
48
+
49
+ desc 'create-project PROJECT_NAME', 'create stackr project'
50
+ def create_project(name)
51
+ @project_name = name
52
+
53
+ say "Creating stackr project: #{name}\n"
54
+ directory 'templates/project', name
55
+ end
56
+
57
+ ## create-template
58
+ desc 'create-template TEMPLATE', 'create a new template generator'
59
+ def create_template(name)
60
+ @template_name = name
61
+ say "Creating template generator #{name}\n"
62
+ template 'templates/generator.rb.tt', File.join(templates_path, "#{name}.rb")
63
+ end
64
+
65
+ ## generate-template
66
+ desc 'generate-template TEMPLATE', 'write the template json file'
67
+ def generate_template(template_name)
68
+ template = load_template(template_name)
69
+ if !template
70
+ say "There is no template named \'#{template_name}\'."
71
+ return
72
+ end
73
+
74
+ json_file = json_template_path(template_name)
75
+
76
+ say "Writing #{template_name} to #{json_file}\n"
77
+ File.open(json_file, 'w') do |f|
78
+ f.write(template.body)
79
+ end
80
+ end
81
+
82
+ ## validate-template
83
+ desc 'validate-template TEMPLATE', 'Verify template and parameters'
84
+ def validate_template(template_name)
85
+ template = load_template(template_name)
86
+ if !template
87
+ say "There is no template named \'#{template_name}\'."
88
+ return
89
+ end
90
+
91
+ launcher = Stackr::CloudFormation.new
92
+ begin
93
+ launcher.validate_template(template)
94
+ rescue Aws::S3::Errors::ServiceError => e
95
+ say e.message
96
+ return false
97
+ else
98
+ say "Template #{template_name} validates."
99
+ return true
100
+ end
101
+ end
102
+
103
+ ## create-stack
104
+ desc 'create-stack TEMPLATE', 'create a stack from TEMPLATE'
105
+ option :name,
106
+ aliases: '-n',
107
+ desc: 'Stack name, defaults to template name'
108
+
109
+ option :disable_rollback,
110
+ type: :boolean,
111
+ default: false,
112
+ desc: 'disable rollback of failed stacks'
113
+
114
+ # TODO: log parameters and their values
115
+ def create_stack(template_name)
116
+ return if !validate_template(template_name)
117
+
118
+ template = load_template(template_name)
119
+ if !template
120
+ say "There is no template named \'#{template_name}\'."
121
+ return
122
+ end
123
+
124
+ name = options[:name] || template.name
125
+ launcher = Stackr::CloudFormation.new
126
+ say "Creating CloudFormation stack #{name} from template #{template.name}\n"
127
+ begin
128
+ launcher.create_stack(template, options)
129
+ rescue Stackr::StackAlreadyExistsError => e
130
+ say e.message
131
+ end
132
+ end
133
+
134
+ ## update-stack
135
+ desc 'update-stack TEMPLATE', 'update the stack created from TEMPLATE'
136
+ option :name,
137
+ aliases: '-n',
138
+ desc: 'Stack name, defaults to template name'
139
+
140
+ # TODO: log parameters and their values
141
+ def update_stack(template_name)
142
+ return if !validate_template(template_name)
143
+
144
+ template = load_template(template_name)
145
+ if !template
146
+ say "There is no template named \'#{template_name}\'."
147
+ return
148
+ end
149
+
150
+ name = options[:name] || template.name
151
+ say "Updating CloudFormation stack #{name} from template #{template.name}\n"
152
+ launcher = Stackr::CloudFormation.new
153
+ begin
154
+ launcher.update_stack(template, options)
155
+ rescue Stackr::StackMissingError => e
156
+ say e.message
157
+ rescue Stackr::StackUpdateNotRequiredError => e
158
+ say e.message
159
+ rescue Stackr::InsufficientCapabilitiesError => e
160
+ say e.message
161
+ end
162
+ end
163
+
164
+ ## delete-stack
165
+ desc 'delete-stack STACK', 'delete the stack named STACK'
166
+ def delete_stack(stack_name)
167
+ say "Deleting CloudFormation stack #{stack_name}\n"
168
+ launcher = Stackr::CloudFormation.new
169
+ begin
170
+ launcher.delete_stack(stack_name)
171
+ rescue Stackr::StackMissingError => e
172
+ say e.message
173
+ end
174
+ end
175
+
176
+ ## list-stacks
177
+ desc 'list-stacks', 'list all stacks'
178
+ def list_stacks
179
+ launcher = Stackr::CloudFormation.new
180
+ rows = []
181
+ launcher.list_stacks.each do |stack|
182
+ rows << [
183
+ stack.name,
184
+ stack.stack_status,
185
+ stack.creation_time ? stack.creation_time.iso8601 : '',
186
+ stack.last_updated_time ? stack.last_updated_time.iso8601 : ''
187
+ ]
188
+ end
189
+ print_table rows
190
+ end
191
+
192
+ end
193
+ end
@@ -0,0 +1,160 @@
1
+ require 'aws-sdk'
2
+ require 'stackr'
3
+
4
+ module Stackr
5
+ class CloudFormation
6
+
7
+ # Is this template too big to include in API calls?
8
+ # If so, we better upload it to S3
9
+ def is_too_big?(template_str)
10
+ template_str.bytesize > 51200
11
+ true
12
+ end
13
+
14
+ # Is this template too big for CloudFormation
15
+ def is_way_too_big?(template_str)
16
+ template_str.bytesize > 460800
17
+ end
18
+
19
+ # Requires TEMPLATE_BUCKET environment variable to be set.
20
+ # If TEMPLATE_PREFIX environment variable is set, templates will be uploaded
21
+ # using that prefix.
22
+ def upload_to_s3(template_str, name)
23
+ s3 = Aws::S3::Resource.new
24
+ if ENV['TEMPLATE_BUCKET'].nil?
25
+ raise Stackr::MissingTemplateBucketError, 'Please set TEMPLATE_BUCKET environment variable before uploading templates to S3.'
26
+ end
27
+ bucket = s3.bucket(ENV['TEMPLATE_BUCKET'])
28
+ key = "#{name}.json"
29
+ if ENV['TEMPLATE_PREFIX']
30
+ key = "#{ENV['TEMPLATE_PREFIX']}/#{key}"
31
+ end
32
+ s3_object = bucket.object(key)
33
+ s3_object.put(body: template_str)
34
+ return s3_object.public_url
35
+ end
36
+
37
+ # Return proper argument for CloudFormation api calls.
38
+ # If template is too big, upload it to s3 first and return
39
+ # {template_url: s3_url}
40
+ # otherwise return
41
+ # {template_body: template_contents}
42
+ # But if we've already uploaded the template to s3 this run,
43
+ # (because we validated it and then ran a create-stack),
44
+ # don't upload it a second time, just return the s3 url.
45
+ def template_argument(template)
46
+
47
+ if is_way_too_big? template.body
48
+ raise Stackr::TemplateTooBigError, "Template #{template.name} is too big for CloudFormation."
49
+ end
50
+
51
+ if is_too_big? template.body
52
+ if template.url.nil?
53
+ template.url = upload_to_s3(template.body, template.name)
54
+ end
55
+ return {template_url: template.url}
56
+ end
57
+
58
+ return {template_body: template.body}
59
+ end
60
+
61
+ def stack_parameters(parameter_map)
62
+ parameter_map.map { |k,v| {parameter_key: k, parameter_value: ENV[v]} }
63
+ end
64
+
65
+ # Raise an error if the template does not validate
66
+ # takes a Stackr::Template
67
+ def validate_template(template)
68
+ cfn = Aws::CloudFormation::Client.new
69
+
70
+ opts = template_argument(template)
71
+ begin
72
+ resp = cfn.validate_template(opts)
73
+ rescue Aws::CloudFormation::Errors::ValidationError => e
74
+ raise Stackr::TemplateValidationError, e.message
75
+ end
76
+
77
+ # validate parameters
78
+ # Make sure each parameter w/o a default has a value
79
+ resp.parameters.each do |param|
80
+ param_name = param[:parameter_key]
81
+ env_var = template.parameter_map[param_name]
82
+
83
+ if param[:default_value].nil? && ENV[env_var].nil?
84
+ raise Stackr::MissingParameterError, "Required parameter #{param_name} (#{env_var}) not specified."
85
+ end
86
+ end
87
+ end
88
+
89
+ # Takes a Stackr::Template
90
+ def create_stack(template, options)
91
+ cfn = Aws::CloudFormation::Resource.new
92
+ stack_name = options[:name] || template.name
93
+
94
+ opts = {
95
+ stack_name: options[:name] || template.name,
96
+ parameters: stack_parameters(template.parameter_map),
97
+ disable_rollback: options[:disable_rollback],
98
+ capabilities: template.capabilities
99
+ }
100
+
101
+ # are we using template_body or template_url?
102
+ opts.merge!( template_argument(template) )
103
+
104
+ # Trap error raised when stack already exists
105
+ begin
106
+ cfn.create_stack(opts)
107
+ rescue Aws::CloudFormation::Errors::AlreadyExistsException => e
108
+ raise Stackr::StackAlreadyExistsError, e.message
109
+ end
110
+ end
111
+
112
+ # Takes a Stackr::Template
113
+ def update_stack(template, options)
114
+ cfn = Aws::CloudFormation::Resource.new
115
+ stack_name = options[:name] || template.name
116
+ stack = cfn.stack(stack_name)
117
+ if !stack
118
+ raise Stackr::StackMissingError, "Stack #{stack_name} does not exist."
119
+ end
120
+
121
+ opts = {
122
+ parameters: stack_parameters(template.parameter_map),
123
+ capabilities: template.capabilities
124
+ }
125
+
126
+ # are we using template_body or template_url?
127
+ opts.merge!( template_argument(template) )
128
+
129
+ begin
130
+ stack.update(opts)
131
+ rescue Aws::CloudFormation::Errors::ValidationError => e
132
+ case e.message
133
+ when 'No updates are to be performed.'
134
+ raise Stackr::StackUpdateNotRequiredError, "Stack [#{stack_name}] requires no updates."
135
+ when "Stack [#{stack_name}] does not exist"
136
+ raise Stackr::StackMissingError, e.message
137
+ else
138
+ raise e
139
+ end
140
+ rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
141
+ raise Stackr::InsufficientCapabilitiesError, "#{e.message}\nPlease add them to your template and run update again."
142
+ end
143
+ end
144
+
145
+ def delete_stack(stack_name)
146
+ cfn = Aws::CloudFormation::Resource.new
147
+ stack = cfn.stack(stack_name)
148
+ if stack.exists?
149
+ stack.delete
150
+ else
151
+ raise Stackr::StackMissingError, "Stack [#{stack_name}] does not exist."
152
+ end
153
+ end
154
+
155
+ def list_stacks
156
+ cfn = Aws::CloudFormation::Resource.new
157
+ cfn.stacks
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,10 @@
1
+ module Stackr
2
+ class StackMissingError < StandardError; end
3
+ class StackAlreadyExistsError < StandardError; end
4
+ class StackUpdateNotRequiredError < StandardError; end
5
+ class InsufficientCapabilitiesError < StandardError; end
6
+ class TemplateValidationError < StandardError; end
7
+ class MissingParameterError < StandardError; end
8
+ class TemplateTooBigError < StandardError; end
9
+ class MissingTemplateBucketError < StandardError; end
10
+ end
@@ -0,0 +1,34 @@
1
+ require 'json'
2
+ require 'stackr/template_helpers'
3
+
4
+ include Stackr::TemplateHelpers
5
+
6
+ module Stackr
7
+ class Template
8
+ attr_accessor :name, :parameter_map, :template_dsl, :capabilities
9
+ attr_accessor :includes_path, :url
10
+
11
+ def initialize
12
+ @capabilities = []
13
+ @parameter_map = {}
14
+ @includes_path = 'includes'
15
+ end
16
+
17
+ # eval the contents in the context of this class
18
+ def self.load(template_file)
19
+ return nil if !File.exist?(template_file)
20
+ eval File.read(template_file)
21
+ end
22
+
23
+ def generate
24
+ JSON.pretty_generate(template_dsl)
25
+ end
26
+
27
+ def body
28
+ if @body.nil?
29
+ @body = generate()
30
+ end
31
+ @body
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ require 'cloudformation-ruby-dsl/cfntemplate'
2
+
3
+ module Stackr
4
+ module TemplateHelpers
5
+ # Put all helper methods that you want to add to the DSL here.
6
+ # TODO: Make something that loads project helpers too.
7
+
8
+ def find_in_env(name)
9
+ find_in_map('EnvironmentMap', ref('Environment'), name)
10
+ end
11
+
12
+ def include_file(filepath, locals={})
13
+ interpolate(file(filepath), locals)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Stackr
2
+ VERSION = "1.0.0"
3
+ end
data/lib/stackr.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'stackr/version'
2
+ require 'stackr/errors'
3
+ require 'stackr/cli'
4
+ require 'stackr/template'
5
+ require 'stackr/template_helpers'
6
+ require 'stackr/cloudformation'
data/stackr.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'stackr/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "stackr"
8
+ spec.version = Stackr::VERSION
9
+ spec.authors = ["Chris Chalfant"]
10
+ spec.email = ["cchalfant@leafsoftwaresolutions.com"]
11
+
12
+ spec.summary = %q{Framework for managing CloudFormation stacks}
13
+ spec.description = %q{Framework for managing CloudFormation stacks}
14
+ spec.homepage = "https://github.com/LeafSoftware/stackr"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "aws-sdk"
23
+ spec.add_dependency "cloudformation-ruby-dsl"
24
+ spec.add_dependency "thor"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.12"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ end
@@ -0,0 +1,42 @@
1
+ Stackr::Template.new.tap do |t|
2
+
3
+ t.name = '<%= @template_name %>' # Name for this stack
4
+
5
+ # Map CloudFormation Stack parameters to environment variables
6
+ # Use this to hand in secrets that don't belong in the environment map
7
+ # like database passwords.
8
+ t.parameter_map = {
9
+ 'Environment' => 'ENVIRONMENT'
10
+ }
11
+
12
+ # Uncomment if you have IAM resources in this template
13
+ # t.capabilities = ['CAPABILITY_IAM']
14
+ # Or, if you have custom names for IAM resources, this instead
15
+ # t.capabilities = ['CAPABILITY_NAMED_IAM']
16
+
17
+ ##
18
+ ## CloudFormation template stuff goes here
19
+ ## See https://github.com/bazaarvoice/cloudformation-ruby-dsl
20
+ ##
21
+ t.template_dsl = template do
22
+ value AWSTemplateFormatVersion: '2010-09-09'
23
+ value Description: 'Template for <%= @template_name %>'
24
+
25
+ parameter 'Environment',
26
+ Description: 'Launch stack in this environment',
27
+ Type: 'String',
28
+ Default: 'dev',
29
+ AllowedValues: ['dev'] # Add new environment strings as necessary
30
+
31
+ # Add other parameters here.
32
+
33
+ # Add in the environment map in includes/environment_map.rb
34
+ # You can edit the map to include environment specific things
35
+ # like Vpc, Subnets, Security Groups, etc.
36
+ mapping 'EnvironmentMap', File.join(includes_path, 'environment_map.rb')
37
+
38
+ # Add resources here.
39
+
40
+ # Add outputs here.
41
+ end
42
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # example .env file
3
+ # cp .env.example .env
4
+ #
5
+ # Set environment variables for all template parameters here.
6
+ # This .env file is in gitignore to help keep application
7
+ # secrets from leaking out into source code control.
8
+ #
9
+ # I suggest something like https://github.com/kennethreitz/autoenv
10
+ # to automagically set your environment when you cd into the project
11
+ # directory.
12
+ export ENVIRONMENT=dev
13
+
14
+ # If templates are too big the CloudFormation API, they must be uploaded
15
+ # to s3. Set this variable to the bucket you want to use.
16
+ # export TEMPLATE_BUCKET=mytemplatebucket
17
+
18
+ # You can prefix the templates in the bucket as well.
19
+ # export TEMPLATE_PREFIX=stackr-templates
@@ -0,0 +1,2 @@
1
+ .env
2
+ templates/*.json
@@ -0,0 +1 @@
1
+ <%= @project_name %>
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'stackr'
@@ -0,0 +1,15 @@
1
+ {
2
+ 'Mappings' => {
3
+ 'EnvironmentMap' => {
4
+ # In your template, use find_in_env('VpcId').
5
+ # It will use the Environment parameter to determine
6
+ # which VpcId to return.
7
+ dev: {
8
+ # VpcId: '' # Your Dev VPC
9
+ },
10
+ test: {
11
+ # VpcId: '' # Your Test VPC
12
+ }
13
+ }
14
+ }
15
+ }
File without changes
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stackr
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Chalfant
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cloudformation-ruby-dsl
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ description: Framework for managing CloudFormation stacks
98
+ email:
99
+ - cchalfant@leafsoftwaresolutions.com
100
+ executables:
101
+ - stackr
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".ruby-gemset"
108
+ - ".ruby-version"
109
+ - ".travis.yml"
110
+ - Gemfile
111
+ - LICENSE.txt
112
+ - README.md
113
+ - Rakefile
114
+ - exe/stackr
115
+ - lib/stackr.rb
116
+ - lib/stackr/cli.rb
117
+ - lib/stackr/cloudformation.rb
118
+ - lib/stackr/errors.rb
119
+ - lib/stackr/template.rb
120
+ - lib/stackr/template_helpers.rb
121
+ - lib/stackr/version.rb
122
+ - stackr.gemspec
123
+ - templates/generator.rb.tt
124
+ - templates/project/.env.example
125
+ - templates/project/.gitignore
126
+ - templates/project/.ruby-gemset.tt
127
+ - templates/project/Gemfile
128
+ - templates/project/includes/environment_map.rb
129
+ - templates/project/templates/.keep
130
+ homepage: https://github.com/LeafSoftware/stackr
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.5.1
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Framework for managing CloudFormation stacks
154
+ test_files: []