lono 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +16 -284
  4. data/lib/lono.rb +6 -0
  5. data/lib/lono/cfn.rb +5 -0
  6. data/lib/lono/cfn/base.rb +86 -9
  7. data/lib/lono/cfn/create.rb +27 -2
  8. data/lib/lono/cfn/help.rb +12 -12
  9. data/lib/lono/cfn/preview.rb +12 -11
  10. data/lib/lono/cfn/update.rb +3 -2
  11. data/lib/lono/default/settings.yml +13 -0
  12. data/lib/lono/env.rb +11 -0
  13. data/lib/lono/param.rb +1 -1
  14. data/lib/lono/param/generator.rb +144 -22
  15. data/lib/lono/settings.rb +28 -0
  16. data/lib/lono/template.rb +13 -2
  17. data/lib/lono/template/aws_services.rb +7 -0
  18. data/lib/lono/template/dsl.rb +24 -33
  19. data/lib/lono/template/helpers.rb +144 -0
  20. data/lib/lono/template/template.rb +69 -68
  21. data/lib/lono/template/upload.rb +75 -0
  22. data/lib/lono/version.rb +1 -1
  23. data/lib/starter_projects/json_project/config/{lono.rb → templates/base/blog.rb} +3 -3
  24. data/lib/starter_projects/{yaml_project/config/lono/api.rb → json_project/config/templates/base/stacks.rb} +9 -9
  25. data/lib/starter_projects/json_project/templates/{db.json.erb → db.json} +1 -1
  26. data/lib/starter_projects/json_project/templates/partial/{host_record.json.erb → host_record.json} +0 -0
  27. data/lib/starter_projects/json_project/templates/partial/{server.json.erb → server.json} +2 -2
  28. data/lib/starter_projects/json_project/templates/user_data/{app.sh.erb → app.sh} +0 -0
  29. data/lib/starter_projects/json_project/templates/user_data/{db.sh.erb → db.sh} +0 -0
  30. data/lib/starter_projects/json_project/templates/user_data/{db2.sh.erb → db2.sh} +0 -0
  31. data/lib/starter_projects/json_project/templates/user_data/{ruby_script.rb.erb → ruby_script.rb} +0 -0
  32. data/lib/starter_projects/json_project/templates/{web.json.erb → web.json} +2 -2
  33. data/lib/starter_projects/yaml_project/config/{lono.rb → templates/base/blog.rb} +4 -8
  34. data/lib/starter_projects/{json_project/config/lono/api.rb → yaml_project/config/templates/base/stacks.rb} +11 -13
  35. data/lib/starter_projects/yaml_project/config/templates/prod/stacks.rb +1 -0
  36. data/lib/starter_projects/yaml_project/config/templates/stag/stacks.rb +1 -0
  37. data/lib/starter_projects/yaml_project/config/variables/base/variables.rb +4 -0
  38. data/lib/starter_projects/yaml_project/config/variables/prod/variables.rb +1 -0
  39. data/lib/starter_projects/yaml_project/config/variables/stag/variables.rb +1 -0
  40. data/lib/starter_projects/yaml_project/helpers/my_custom_helper.rb +17 -0
  41. data/lib/starter_projects/yaml_project/params/{api-web-prod.txt → base/api-web-prod.txt} +0 -0
  42. data/lib/starter_projects/yaml_project/params/{example.txt → base/example.txt} +0 -0
  43. data/lib/starter_projects/yaml_project/params/prod/example.txt +1 -0
  44. data/lib/starter_projects/yaml_project/params/stag/example.txt +1 -0
  45. data/lib/starter_projects/yaml_project/templates/{db.yml.erb → db.yml} +1 -1
  46. data/lib/starter_projects/yaml_project/templates/{example.yml.erb → example.yml} +0 -0
  47. data/lib/starter_projects/yaml_project/templates/partial/{host_record.yml.erb → host_record.yml} +0 -0
  48. data/lib/starter_projects/yaml_project/templates/partial/{server.yml.erb → server.yml} +0 -0
  49. data/lib/starter_projects/yaml_project/templates/partial/user_data/{bootstrap.sh.erb → bootstrap.sh} +0 -0
  50. data/lib/starter_projects/yaml_project/templates/{web.yml.erb → web.yml} +2 -2
  51. data/lono.gemspec +1 -0
  52. data/spec/fixtures/params/baseonly/params/base/network.txt +1 -0
  53. data/spec/fixtures/params/envonly/params/prod/network.txt +1 -0
  54. data/spec/fixtures/params/overlay/params/base/network.txt +1 -0
  55. data/spec/fixtures/params/overlay/params/prod/network.txt +1 -0
  56. data/spec/lib/lono/new_spec.rb +1 -1
  57. data/spec/lib/lono/param/generator_spec.rb +34 -0
  58. data/spec/lib/lono/template/dsl_spec.rb +1 -1
  59. data/spec/lib/lono/template_spec.rb +5 -0
  60. metadata +60 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 01b405f56d85200ea0063749316264a0587ea359
4
- data.tar.gz: 8963150180a2ff89f2cf125bea08099e27b73917
3
+ metadata.gz: 2d0a86c90a4434f8330f76b0dd3c804449d42c68
4
+ data.tar.gz: d8a703e5267a622bf1280d60283e80aeb4cf41ad
5
5
  SHA512:
6
- metadata.gz: c9c78aa0037081874d77499a5ae30e127558fcf36c99098a318bb87dd3b493c6c59b5092c316ce7c77be55d71634ec70143e1520463f0657d1312732376c24b8
7
- data.tar.gz: 9cf8a0df5380cf41469efcb82ec35466d5e9a7737d60275c727f4897f47ed0f55c3ee4b88aec7cb02c308a63bbb8a701fd4fe1a64275cc2bf906419cbb1a5625
6
+ metadata.gz: 5051c3a781e0eb8b9e00c2eb38072c7f764e2d75516622a61a823d13810753e24718829783a50ffd4fdc24ebfe37b90c9df70b25cb3b587ce505d7aa15d8a9c7
7
+ data.tar.gz: 2e1180d405393ed872c504727f2d612dea0e301b7197a6aefa82de3f3396c83cb464276e4639be60d5c6824a567eab6f8066c7a58c2a6bb15881115b749f5df1
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [3.0.0]
7
+ - Major feature changes
8
+ - Lono structural changes
9
+ - Layering Support
10
+ - Shared Variable Support
11
+ - Nested Stacks Support
12
+ - Format and Extension Detection
13
+ - Custom Helper Support
14
+ - Source Name Convention Support
15
+ - Settings File Support
16
+
6
17
  ## [2.1.0]
7
18
  - improve instance_eval error when lono.rb errors, print out line of code and context
8
19
 
data/README.md CHANGED
@@ -1,22 +1,24 @@
1
1
  # Lono
2
2
 
3
- [![ReadmeCI](http://www.readmeci.com/images/readmeci-badge.svg)](http://www.readmeci.com/tongueroo/lono)
4
3
  [![Gem Version](https://badge.fury.io/rb/lono.png)](http://badge.fury.io/rb/lono)
5
4
  [![CircleCI](https://circleci.com/gh/tongueroo/lono.svg?style=svg)](https://circleci.com/gh/tongueroo/lono)
6
5
  [![Code Climate][3]][4]
7
6
  [![Dependency Status](https://gemnasium.com/tongueroo/lono.png)](https://gemnasium.com/tongueroo/lono)
8
7
  [![Coverage Status](https://coveralls.io/repos/tongueroo/lono/badge.png)](https://coveralls.io/r/tongueroo/lono)
8
+ [![ReadmeCI](http://www.readmeci.com/images/readmeci-badge.svg)](http://www.readmeci.com/tongueroo/lono)
9
+ [![Join the chat at https://gitter.im/tongueroo/lono](https://badges.gitter.im/tongueroo/lono.svg)](https://gitter.im/tongueroo/lono?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
10
+ [![Support](https://img.shields.io/badge/get-support-blue.svg)](https://boltops.com?utm_source=badge&utm_medium=badge&utm_campaign=lono)
9
11
 
10
12
  [3]: https://codeclimate.com/repos/51d7f1407e00a4042c010ab4/badges/5273fe6cdb5a13e58554/gpa.png
11
13
  [4]: https://codeclimate.com/repos/51d7f1407e00a4042c010ab4/feed
12
14
 
13
- Lono is a tool for managing CloudFormation templates.
15
+ Lono is a tool to help you easily manage your CloudFormation templates. Lono handles the entire CloudFormation lifecyle. It starts with helping you craft of the templates and helps you all the way to end when you provision of the infrastructure.
14
16
 
15
17
  * Lono generates CloudFormation templates based on ERB ruby templates in either `yaml` or `json` format.
16
18
  * Lono takes simple env-like files to and generates the CloudFormation parameter files.
17
19
  * Lono wraps the CloudFormation api calls in a simple interface using the generated files to launch the CloudFormation stacks.
18
20
 
19
- Lono documentation is at [lono.cloud](http://lono.cloud).
21
+ See [lono.cloud](http://lono.cloud) for full lono documentation.
20
22
 
21
23
  These blog posts also cover lono:
22
24
 
@@ -26,213 +28,24 @@ These blog posts also cover lono:
26
28
  * [CloudFormation Tools: lono, lono-params and lono cfn Together](https://medium.com/boltops/cloudformation-tools-lono-lono-params-and-lono-cfn-play-together-620af51e616)
27
29
  * [AWS CloudFormation dry-run with lono cfn preview](https://medium.com/boltops/aws-cloudformation-dry-run-with-lono-cfn-plan-2a1e0f80d13c)
28
30
 
29
- ## Usage
30
-
31
- <pre>
32
- $ lono new infra
33
- </pre>
34
-
35
- This sets up a starter lono project called infra with example templates. Next you cd into the folder and generate the template and parameter files.
36
-
37
- <pre>
38
- $ cd infra
39
- $ lono generate
40
- </pre>
41
-
42
- This CloudFormation template and parameter files are now available under `output` and `output/params`.
31
+ ## Quick Usage
43
32
 
44
- ### Generate Template Files
33
+ It only takes a couple of commands to start using lono.
45
34
 
46
- The CloudFormation templates files that were generated from the `config` and `templates` folders and written to the `output` folder.
47
-
48
- The starter lono template project config files looks like [this](lib/starter_project_yaml/config/lono.rb) and [this](lib/starter_project_yaml/config/lono/api.rb). Here's a snippet from one of the config files: [config/lono.rb](lib/starter_project_yaml/config/lono.rb).
49
-
50
- ```ruby
51
- template "api-web-prod.yml" do
52
- app,role,env = name.sub('.yml','').split('-')
53
- source "web.yml.erb"
54
- variables(
55
- env: env,
56
- app: app,
57
- role: role,
58
- ami: "ami-123",
59
- instance_type: "m1.small",
60
- port: "80",
61
- high_threshold: "15",
62
- high_periods: "4",
63
- low_threshold: "5",
64
- low_periods: "10",
65
- max_size: "24",
66
- min_size: "6",
67
- down_adjustment: "-3",
68
- up_adjustment: "3",
69
- ssl_cert: "arn:aws:iam::12345:server-certificate/wildcard"
70
- )
71
- end
35
+ ```sh
36
+ brew cask install boltopslabs/software/bolts
37
+ lono new infra
38
+ cd infra
39
+ lono generate # not needed but showing for explanation
40
+ lono cfn create example
72
41
  ```
73
42
 
74
- Here is the corresponding ERB template [templates/web.yml.erb](lib/starter_project_yaml/templates/web.yml.erb). Note that some of the source code has been shorten for brevity.
75
-
76
- ```yaml
77
- <% @app,@role,@env = name.sub('.yml','').split('-') -%>
78
- ---
79
- AWSTemplateFormatVersion: '2010-09-09'
80
- Description: <%= @app.capitalize %> Stack
81
- Mappings:
82
- ...
83
- Outputs:
84
- ...
85
- Parameters:
86
- Application:
87
- Default: <%= @app %>
88
- Description: Application name
89
- Type: String
90
- ...
91
- Resources:
92
- CPUAlarmHigh:
93
- Properties:
94
- AlarmActions:
95
- - Ref: WebServerScaleUpPolicy
96
- AlarmDescription: Scale-up if CPU > <%= @high_threshold %>% for <%= @high_mins %>
97
- ...
98
- <%= partial("host_record.yml.erb", domain: "mydomain.com") %>
99
- LaunchConfig:
100
- Properties:
101
- BlockDeviceMappings:
102
- - DeviceName: "/dev/sdb"
103
- VirtualName: ephemeral0
104
- ImageId:
105
- ...
106
- UserData:
107
- Fn::Base64: !Sub | # No more Fn::Join needed
108
- #!/bin/bash -lexv
109
- <% stack_name = "#{@env}-#{@app}-#{@role}" %>
110
- exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
111
- echo <%= stack_name %> > /tmp/stack_name
112
- cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
113
- Type: AWS::AutoScaling::LaunchConfiguration
114
-
115
- ```
116
-
117
- The generated `output/blog-web-prod.yml` CloudFormation template looks like this:
118
-
119
- ```yaml
120
- ---
121
- AWSTemplateFormatVersion: '2010-09-09'
122
- Description: Api Stack
123
- Mappings:
124
- ...
125
- Outputs:
126
- ...
127
- Parameters:
128
- Application:
129
- Default: api
130
- Description: Application name
131
- Type: String
132
- ...
133
- Resources:
134
- CPUAlarmHigh:
135
- Properties:
136
- AlarmActions:
137
- - Ref: WebServerScaleUpPolicy
138
- AlarmDescription: Scale-up if CPU > 15% for
139
- ...
140
- HostRecord:
141
- Properties:
142
- Comment: DNS name for mydomain.com
143
- HostedZoneName: ".mydomain.net."
144
- Name:
145
- Fn::Join:
146
- - ''
147
- - - Ref: AWS::StackName
148
- - mydomain.com
149
- ResourceRecords:
150
- - Fn::GetAtt:
151
- - elb
152
- - DNSName
153
- TTL: '60'
154
- Type: CNAME
155
- Type: AWS::Route53::RecordSet
156
- LaunchConfig:
157
- Properties:
158
- BlockDeviceMappings:
159
- - DeviceName: "/dev/sdb"
160
- VirtualName: ephemeral0
161
- ImageId:
162
- ...
163
- UserData:
164
- Fn::Base64: |
165
- #!/bin/bash -lexv
166
-
167
- exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
168
- echo api-web-prod > /tmp/stack_name
169
- cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
170
- Type: AWS::AutoScaling::LaunchConfiguration
171
- ```
172
-
173
- You can use the generated CloudFormation templates in the `output` folder just as you would a normal CloudFormation template. Here's a flow chart of the overall process.
43
+ This sets up a starter lono project called infra with example templates. You cd into the folder and call `lono cfn create` which automatically generates the CloudFormation template and parameter files to `output` and `output/params` and launches the stack.
174
44
 
175
45
  ![Lono flowchart](http://tongueroo.com/images/github-readmes/lono-flowchart.png "Lono flowchart")
176
46
 
177
- ### Generate Parameter Files
178
-
179
- With lono you write simpler params file that is formatted with a simple `key=value` env-like file. The `params/mystack.txt` is shorter format versus the verbose standard CloudFormation parameters json file. Here is an example of a simple `params/mystack.txt` param file.
180
-
181
- ```bash
182
- Param1=1
183
- Param2=2
184
- ```
185
-
186
- The `lono generate` command generates the CloudFormation parameter file in `output/params/mystack.json` which looks like this:
47
+ ### lono cfn summary
187
48
 
188
-
189
- ```json
190
- [
191
- {
192
- "ParameterKey": "Param1",
193
- "ParameterValue": "1"
194
- },
195
- {
196
- "ParameterKey": "Param2",
197
- "ParameterValue": "2"
198
- }
199
- ]
200
- ```
201
-
202
- ## Template helper methods
203
-
204
- There are helper methods that are available in templates.
205
-
206
- * partial(relative_path, variables, options) - Can be use to embed other files in a template. The partial view should be placed in the `templates/partial` folder of the project. So:
207
- * partial('launch\_config.json.erb') -> `templates/partial/launch_config.json.erb`
208
- * partial('launch\_config.json.erb', foo: "bar", hello: "world") - variables can be passed to the partial helper method are available to the partial as instance variables. So, in this case `@foo` and `@hello` will be available in the `launch_config.json.erb` partial.
209
- * partial('user_data/bootstrap.sh.erb', {}, indent: 10) - Indent the result partial by 10 spaces. Useful for yaml format.
210
-
211
- * user\_data - Helpful if you are using CloudFormation json format. More info on the [wiki page](https://github.com/tongueroo/lono/wiki/user_data-helper-for-json-format).
212
-
213
- ## Breaking up config/lono.rb
214
-
215
- If you have a lot of templates, the config/lono.rb file can get unwieldy long. You can break up the lono.rb file and put template defintions in the config/lono directory. Any file in this directory will be automatically loaded. An [example](lib/starter_project_yaml/config/lono/api.rb) is in the starter project.
216
-
217
-
218
- ## lono generate
219
-
220
- You can generate the CloudFormation templates by running:
221
-
222
- <pre>
223
- $ lono generate
224
- $ lono g -c # shortcut
225
- </pre>
226
-
227
- The lono init command also sets up guard-lono. Guard-lono continuously generates the cloudformation templates. Just run guard.
228
-
229
- <pre>
230
- $ guard
231
- </pre>
232
-
233
- # lono cfn
234
-
235
- ## Summary
236
49
  Lono also provides a `lono cfn` management command that allows you to launch stacks from the lono templates. The `lono cfn` tool automatically runs `lono generate` internally and then launches the CloudFormation stack all in one command. Provided that you are in a lono project and have a `my-stack` lono template definition. To create a stack you can simply run:
237
50
 
238
51
  ```
@@ -251,88 +64,7 @@ $ lono cfn delete mystack-1493859659
251
64
  $ lono cfn create -h # getting help
252
65
  ```
253
66
 
254
- ### Conventions
255
-
256
- The template by convention defaults to the name of the stack. In turn, the params by convention defaults to the name of the template.
257
-
258
- * stack - This is a required parameter and is the CLI first parameter.
259
- * template - By convention matches the stack name but can be overriden with `--template`.
260
- * params - By convention matches the template name but can be overriden with `--params`.
261
-
262
- The conventions allows the command to be a very nice short command that can be easily remembered. For example, these 2 commands are the same:
263
-
264
- ### lono cfn create
265
-
266
- Long form:
267
-
268
- ```
269
- $ lono cfn create my-stack --template my-stack --params --my-stack
270
- ```
271
-
272
- Short form:
273
-
274
- ```
275
- $ lono cfn create my-stack
276
- ```
277
-
278
-
279
- Both template and params conventions can be overridden. Here are examples of overriding the template and params name conventions.
280
-
281
- ```
282
- $ lono cfn create my-stack --template different-name1
283
- ```
284
-
285
- The template that will be use is output/different-name1.json and the parameters will use params/different-name1.json.
286
-
287
- ```
288
- $ lono cfn create my-stack --params different-name2
289
- ```
290
-
291
- The template that will be use is output/different-name2.json and the parameters will use params/different-name2.json.
292
-
293
- ```
294
- $ lono cfn create my-stack --template different-name3 --params different-name4
295
- ```
296
-
297
- The template that will be use is output/different-name3.json and the parameters will use params/different-name4.json.
298
-
299
- ### lono cfn update
300
-
301
- To update stacks you can use `lono cfn update`:
302
-
303
- ```
304
- $ lono cfn update my-stack --template template-name --params params-name
305
- ```
306
-
307
- By default the update command will display a preview of the stack changes before applying the update and prompt to check if you are sure. If you want to bypass the are you sure prompt, use the `--sure` option.
308
-
309
- ```
310
- $ lono cfn update my-stack --template template-name --params params-name --sure
311
- ```
312
-
313
- ### lono cfn delete
314
-
315
- ```
316
- $ lono cfn delete my-stack --sure
317
- ```
318
-
319
- ### lono cfn preview
320
-
321
- If you want to see the CloudFormation preview without updating the stack you can also use the `lono cfn preview` command. The preview command is also covered in this blog post: [AWS CloudFormation dry-run with lono cfn preview](https://medium.com/boltops/aws-cloudformation-dry-run-with-lono-cfn-plan-2a1e0f80d13c)
322
-
323
- ```
324
- $ lono cfn preview example --template single_instance --params single_instance
325
- Using template: output/single_instance.yml
326
- Using parameters: params/single_instance.txt
327
- Generating CloudFormation templates:
328
- ./output/single_instance.yml
329
- Params file generated for example at ./output/params/example.json
330
- Generating CloudFormation Change Set for preview.....
331
- CloudFormation preview for 'example' stack update. Changes:
332
- Remove AWS::Route53::RecordSet: DnsRecord testsubdomain.sub.tongueroo.com
333
- $
334
- ```
335
-
67
+ See [lono.cloud](http://lono.cloud) for full lono documentation.
336
68
 
337
69
  ## Contributing
338
70
 
@@ -3,6 +3,8 @@ require 'yaml'
3
3
  require 'pp'
4
4
  require 'colorize'
5
5
  require 'fileutils'
6
+ # http://guides.rubyonrails.org/active_support_core_extensions.html#inflections
7
+ require 'active_support/core_ext/string'
6
8
 
7
9
  # vendor because need https://github.com/futurechimp/plissken/pull/6 to be merged
8
10
  $:.unshift(File.expand_path("../../vendor/plissken/lib", __FILE__))
@@ -11,6 +13,7 @@ require "plissken"
11
13
  $:.unshift(File.expand_path('../', __FILE__))
12
14
  module Lono
13
15
  autoload :VERSION, 'lono/version'
16
+ autoload :Env, 'lono/env'
14
17
  autoload :Help, 'lono/help'
15
18
  autoload :ProjectChecker, 'lono/project_checker'
16
19
  autoload :Command, 'lono/command'
@@ -20,4 +23,7 @@ module Lono
20
23
  autoload :Cfn, 'lono/cfn'
21
24
  autoload :Param, 'lono/param'
22
25
  autoload :Clean, 'lono/clean'
26
+ autoload :Settings, 'lono/settings'
23
27
  end
28
+
29
+ Lono::Env.setup!
@@ -21,8 +21,13 @@ class Lono::Cfn < Lono::Command
21
21
  class_option :template, desc: "override convention and specify the template file to use"
22
22
  class_option :param, desc: "override convention and specify the param file to use"
23
23
  class_option :lono, type: :boolean, desc: "invoke lono to generate CloudFormation templates", default: true
24
+ class_option :s3_upload, type: :boolean, desc: "uploads templates to s3 if s3.path detected", default: true
25
+ class_option :capabilities, type: :array, desc: "iam capabilities. Ex: CAPABILITY_IAM, CAPABILITY_NAMED_IAM"
26
+ class_option :iam, type: :boolean, desc: "Shortcut for common IAM capabilities: CAPABILITY_IAM, CAPABILITY_NAMED_IAM"
27
+ class_option :rollback, type: :boolean, desc: "rollback", default: true
24
28
 
25
29
  desc "create STACK", "create a CloudFormation stack"
30
+ option :randomize_stack_name, type: :boolean, desc: "tack on random string at the end of the stack name", default: nil
26
31
  long_desc Help.create
27
32
  def create(name)
28
33
  Create.new(name, options).run
@@ -1,17 +1,18 @@
1
1
  require "lono"
2
- require "byebug"
3
2
 
4
3
  class Lono::Cfn::Base
5
4
  include Lono::Cfn::AwsServices
6
5
  include Lono::Cfn::Util
7
6
 
7
+ attr_reader :randomize_stack_name
8
8
  def initialize(stack_name, options={})
9
- @stack_name = stack_name
9
+ @randomize_stack_name = options[:randomize_stack_name]
10
+ @stack_name = randomize(stack_name)
10
11
  @options = options
11
12
  @project_root = options[:project_root] || '.'
12
13
  Lono::ProjectChecker.check(@project_root) unless options[:lono] # already ran checker in lono generate
13
14
 
14
- @template_name = options[:template] || @stack_name
15
+ @template_name = options[:template] || derandomize(@stack_name)
15
16
  @param_name = options[:param] || @template_name
16
17
  @template_path = get_source_path(@template_name, :template)
17
18
  @param_path = get_source_path(@param_name, :param)
@@ -21,13 +22,42 @@ class Lono::Cfn::Base
21
22
 
22
23
  def run
23
24
  params = generate_all
24
- save_stack(params) # defined in the sub class
25
+ begin
26
+ save_stack(params) # defined in the sub class
27
+ rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
28
+ capabilities = e.message.match(/\[(.*)\]/)[1]
29
+ confirm = prompt_for_iam(capabilities)
30
+ if confirm =~ /^y/
31
+ @options.merge!(capabilities: [capabilities])
32
+ puts "Re-running: #{command_with_iam(capabilities).colorize(:green)}"
33
+ retry
34
+ else
35
+ puts "Exited"
36
+ exit 1
37
+ end
38
+ end
39
+ end
40
+
41
+ def prompt_for_iam(capabilities)
42
+ puts "This stack will create IAM resources. Please approve to run the command again with #{capabilities} capabilities."
43
+ puts " #{command_with_iam(capabilities)}"
44
+
45
+ puts "Please confirm (y/n)"
46
+ confirm = $stdin.gets
47
+ end
48
+
49
+ def command_with_iam(capabilities)
50
+ "#{File.basename($0)} #{ARGV.join(' ')} --capabilities #{capabilities}"
25
51
  end
26
52
 
27
53
  def generate_all
28
- generate_templates if @options[:lono]
54
+ if @options[:lono]
55
+ generate_templates
56
+ upload_templates if @options[:s3_upload] and !@options[:noop]
57
+ end
58
+ params = generate_params(mute: @options[:mute_params])
29
59
  check_for_errors
30
- generate_params(mute: @options[:mute_params])
60
+ params
31
61
  end
32
62
 
33
63
  def generate_templates
@@ -37,6 +67,17 @@ class Lono::Cfn::Base
37
67
  ).run
38
68
  end
39
69
 
70
+ def upload_templates
71
+ # only upload templates if s3.path configured in settings
72
+ settings = Lono::Settings.new(@project_root)
73
+ return unless settings.s3_path
74
+
75
+ Lono::Template::Upload.new(
76
+ project_root: @project_root,
77
+ pretty: true
78
+ ).run
79
+ end
80
+
40
81
  def generate_params(options={})
41
82
  generator_options = {
42
83
  project_root: @project_root,
@@ -66,8 +107,13 @@ class Lono::Cfn::Base
66
107
  unless File.exist?(@template_path)
67
108
  warns << "Template file missing: could not find #{@template_path}"
68
109
  end
69
- if @options[:param] && !File.exist?(@param_path)
70
- warns << "Parameters file missing: could not find #{@param_path}"
110
+ # Examples:
111
+ # @param_path = params/prod/ecs.txt
112
+ # => output/params/prod/ecs.json
113
+ output_param_path = @param_path.sub(/\.txt/, '.json')
114
+ output_param_path = "#{@project_root}/output/#{output_param_path}"
115
+ if @options[:param] && !File.exist?(output_param_path)
116
+ warns << "Parameters file missing: could not find #{output_param_path}"
71
117
  end
72
118
  [errors, warns]
73
119
  end
@@ -92,7 +138,7 @@ class Lono::Cfn::Base
92
138
  format = detect_format
93
139
  "#{@project_root}/output/#{name}.#{format}"
94
140
  when :param
95
- "#{@project_root}/params/#{name}.txt"
141
+ "#{@project_root}/params/#{LONO_ENV}/#{name}.txt"
96
142
  else
97
143
  raise "hell: dont come here"
98
144
  end
@@ -143,4 +189,35 @@ class Lono::Cfn::Base
143
189
  def quit(signal)
144
190
  exit signal
145
191
  end
192
+
193
+ # Do nothing unless in Create class
194
+ def randomize(stack_name)
195
+ stack_name
196
+ end
197
+
198
+ # Strip the random string at end of the template name
199
+ def derandomize(template_name)
200
+ if randomize_stack_name?
201
+ template_name.sub(/-(\w{3})/,'') # strip the random part
202
+ else
203
+ template_name
204
+ end
205
+ end
206
+
207
+ def randomize_stack_name?
208
+ if !randomize_stack_name.nil?
209
+ return randomize_stack_name # CLI option takes highest precedence
210
+ end
211
+
212
+ # otherwise use the settings preference
213
+ settings = Lono::Settings.new(@project_root)
214
+ settings.data['randomize_stack_name']
215
+ end
216
+
217
+ def capabilities
218
+ return @options[:capabilities] if @options[:capabilities]
219
+ if @options[:iam]
220
+ ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
221
+ end
222
+ end
146
223
  end