lono 5.3.4 → 6.0.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/demo.rb +21 -21
  3. data/CHANGELOG.md +14 -0
  4. data/lib/lono.rb +1 -1
  5. data/lib/lono/blueprint/meta.rb +38 -0
  6. data/lib/lono/cfn/base.rb +19 -12
  7. data/lib/lono/cfn/delete.rb +2 -1
  8. data/lib/lono/cfn/preview/changeset.rb +14 -1
  9. data/lib/lono/cfn/rollback.rb +1 -1
  10. data/lib/lono/cfn/status.rb +1 -1
  11. data/lib/lono/help/blueprint.md +35 -24
  12. data/lib/lono/help/param.md +4 -1
  13. data/lib/lono/help/seed.md +13 -6
  14. data/lib/lono/help/summary.md +22 -8
  15. data/lib/lono/inspector/summary.rb +4 -3
  16. data/lib/lono/output_template.rb +2 -2
  17. data/lib/lono/s3/bucket.rb +1 -1
  18. data/lib/lono/seed/base.rb +1 -0
  19. data/lib/lono/seed/service_role.rb +11 -0
  20. data/lib/lono/template/dsl/builder.rb +3 -7
  21. data/lib/lono/template/dsl/builder/base.rb +24 -3
  22. data/lib/lono/template/dsl/builder/fn.rb +15 -11
  23. data/lib/lono/template/dsl/builder/{helper.rb → helpers.rb} +5 -4
  24. data/lib/lono/template/dsl/builder/helpers/param_helper.rb +33 -0
  25. data/lib/lono/template/dsl/builder/output.rb +4 -4
  26. data/lib/lono/template/dsl/builder/parameter.rb +2 -2
  27. data/lib/lono/template/dsl/builder/resource.rb +4 -3
  28. data/lib/lono/template/dsl/builder/resource/property_mover.rb +4 -0
  29. data/lib/lono/template/dsl/builder/syntax.rb +6 -7
  30. data/lib/lono/version.rb +1 -1
  31. data/lib/templates/blueprint/%blueprint_name%.gemspec.tt +1 -1
  32. data/lib/templates/blueprint/.meta/config.yml.tt +2 -1
  33. data/lib/templates/blueprint/README.md +1 -1
  34. data/lib/templates/blueprint_types/dsl/app/templates/%blueprint_name%.rb +22 -22
  35. data/lib/templates/skeleton/README.md +1 -1
  36. data/lono.gemspec +1 -1
  37. data/vendor/cfn-status/CHANGELOG.md +4 -0
  38. data/vendor/cfn-status/README.md +4 -2
  39. data/vendor/cfn-status/bin/console +1 -1
  40. data/vendor/cfn-status/cfn-status.gemspec +2 -2
  41. data/vendor/cfn-status/lib/cfn-status.rb +1 -1
  42. data/vendor/cfn-status/lib/cfn_status.rb +245 -0
  43. data/vendor/cfn-status/lib/{cfn → cfn_status}/aws_service.rb +1 -1
  44. data/vendor/cfn-status/lib/cfn_status/version.rb +3 -0
  45. data/vendor/cfn-status/spec/fixtures/cfn/pages/fresh/describe_stack_events-1.json +1103 -0
  46. data/vendor/cfn-status/spec/fixtures/cfn/pages/fresh/describe_stack_events-2.json +1104 -0
  47. data/vendor/cfn-status/spec/fixtures/cfn/pages/fresh/describe_stack_events-3.json +1103 -0
  48. data/vendor/cfn-status/spec/fixtures/cfn/pages/updating/describe_stack_events-1.json +1103 -0
  49. data/vendor/cfn-status/spec/fixtures/cfn/pages/updating/describe_stack_events-2.json +1104 -0
  50. data/vendor/cfn-status/spec/fixtures/cfn/pages/updating/describe_stack_events-3.json +1103 -0
  51. data/vendor/cfn-status/spec/lib/cfn_status_spec.rb +153 -0
  52. data/vendor/cfn-status/spec/spec_helper.rb +1 -1
  53. metadata +17 -8
  54. data/vendor/cfn-status/lib/cfn/status.rb +0 -219
  55. data/vendor/cfn-status/lib/cfn/status/version.rb +0 -5
  56. data/vendor/cfn-status/spec/cfn/status_spec.rb +0 -81
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae375abbd7489be7dc9cd29b79b006ab1e35f10814ee119a14a0b099f27d42a7
4
- data.tar.gz: 077c285ab9b7a282dca83e857bef4cb3930fb76859aa6cb2f9763c3444f33ee0
3
+ metadata.gz: 277fec8b235735156d549bc309cebad6c7277eaf102ef4ac7d242d0af610c54a
4
+ data.tar.gz: 80239ae154cbd2de9ad4730fbcdccbc2b746654db65935f84ed1293a776c76be
5
5
  SHA512:
6
- metadata.gz: 82a5a341de1ef8bfd76e0af97dad1f11d8c45cdf0fcabec29b53594efc9867b5e591f8bbc5a2c97528159619ab1b40e21e5d280be2e0ab44db6822ba2ef0c740
7
- data.tar.gz: 68b0d96d00f7ccb6d11892ca6563f96b818d137a2e3f607fc43f814221425640c64ed5783be2d46d9a825a688f98533f4baa784b7c0fd8c7ae3d810a4d7e1524
6
+ metadata.gz: 937af6ff08ea6e36ad6cb785f50665f3e50d9c45b90fcaa2dd4e09771824791cd7ea7cb9b1816dfaff6bd7a188824a9d4d30fbac93ccdafc508f79b17d9c2b8e
7
+ data.tar.gz: 16b40f4b8ddae0d6de37992ab7f8f673622d6a3097bec434db90cec0951386be2f96ddb6bd41d22758a5b3fef44d3bc8ee84672fe4623f97db53bef9e82302e0
@@ -2,25 +2,25 @@
2
2
  aws_template_format_version "2010-09-09"
3
3
  description "Demo stack"
4
4
 
5
- parameter(:instance_type, "t3.micro")
5
+ parameter("InstanceType", "t3.micro")
6
6
 
7
- mapping(:ami_map,
8
- "ap-northeast-1": { ami: "ami-0f9ae750e8274075b" },
9
- "ap-northeast-2": { ami: "ami-047f7b46bd6dd5d84" },
10
- "ap-south-1": { ami: "ami-0889b8a448de4fc44" },
11
- "ap-southeast-1": { ami: "ami-0b419c3a4b01d1859" },
12
- "ap-southeast-2": { ami: "ami-04481c741a0311bbb" },
13
- "ca-central-1": { ami: "ami-03338e1f67dae0168" },
14
- "eu-central-1": { ami: "ami-09def150731bdbcc2" },
15
- "eu-north-1": { ami: "ami-d16fe6af" },
16
- "eu-west-1": { ami: "ami-07683a44e80cd32c5" },
17
- "eu-west-2": { ami: "ami-09ead922c1dad67e4" },
18
- "eu-west-3": { ami: "ami-0451ae4fd8dd178f7" },
19
- "sa-east-1": { ami: "ami-0669a96e355eac82f" },
20
- "us-east-1": { ami: "ami-0de53d8956e8dcf80" },
21
- "us-east-2": { ami: "ami-02bcbb802e03574ba" },
22
- "us-west-1": { ami: "ami-0019ef04ac50be30f" },
23
- "us-west-2": { ami: "ami-061392db613a6357b" }
7
+ mapping("AmiMap",
8
+ "ap-northeast-1": { Ami: "ami-0f9ae750e8274075b" },
9
+ "ap-northeast-2": { Ami: "ami-047f7b46bd6dd5d84" },
10
+ "ap-south-1": { Ami: "ami-0889b8a448de4fc44" },
11
+ "ap-southeast-1": { Ami: "ami-0b419c3a4b01d1859" },
12
+ "ap-southeast-2": { Ami: "ami-04481c741a0311bbb" },
13
+ "ca-central-1": { Ami: "ami-03338e1f67dae0168" },
14
+ "eu-central-1": { Ami: "ami-09def150731bdbcc2" },
15
+ "eu-north-1": { Ami: "ami-d16fe6af" },
16
+ "eu-west-1": { Ami: "ami-07683a44e80cd32c5" },
17
+ "eu-west-2": { Ami: "ami-09ead922c1dad67e4" },
18
+ "eu-west-3": { Ami: "ami-0451ae4fd8dd178f7" },
19
+ "sa-east-1": { Ami: "ami-0669a96e355eac82f" },
20
+ "us-east-1": { Ami: "ami-0de53d8956e8dcf80" },
21
+ "us-east-2": { Ami: "ami-02bcbb802e03574ba" },
22
+ "us-west-1": { Ami: "ami-0019ef04ac50be30f" },
23
+ "us-west-2": { Ami: "ami-061392db613a6357b" }
24
24
  )
25
25
 
26
26
  # Comment out instance to save costs
@@ -30,9 +30,9 @@ mapping(:ami_map,
30
30
  # security_group_ids: [get_att("security_group.group_id")],
31
31
  # user_data: base64(user_data("bootstrap.sh"))
32
32
  # )
33
- resource(:security_group, "AWS::EC2::SecurityGroup",
34
- group_description: "demo security group",
33
+ resource("SecurityGroup", "AWS::EC2::SecurityGroup",
34
+ GroupDescription: "demo security group",
35
35
  )
36
36
 
37
37
  # output(:instance)
38
- output(:security_group, get_att("security_group.group_id"))
38
+ output("SecurityGroup", get_att("SecurityGroup.GroupId"))
@@ -3,6 +3,20 @@
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
+ ## [6.0.0]
7
+ - #13 DSL improvements: auto camelize off by default
8
+ - `auto_camelize: off` as new default for blueprints.
9
+ - Old blueprints will continue to auto_camelize unless the `.meta/config.yml` is updated to `auto_camelize: off`
10
+ - Upgrade vendor/cfn_status
11
+ - Update docs to encourage CamelCase for attributes and properties
12
+ - Add and encourage shorthand bang intrinsic methods: `if!`, `not!`, `and!`, `or!`
13
+ - Fix iam permission error for `lono cfn preview` command
14
+ - Update cli help
15
+ - Improve `lono summary` output
16
+ - Introduced experimental helpers: `conditional_parameter` and `optional_ref`. Note that their interfaces may change
17
+ - Treat common attributes `DependsOn` and `Condition` at the property level specially and move them to the attribute level automatically. Allows for cleaner resource definitions.
18
+ - update blueprint starter skeleton
19
+
6
20
  ## [5.3.4]
7
21
  - fix param preview for noecho values that are set
8
22
 
@@ -14,7 +14,7 @@ require 'cfn_camelizer'
14
14
  gem_root = File.dirname(__dir__)
15
15
  $:.unshift("#{gem_root}/lib")
16
16
  $:.unshift("#{gem_root}/vendor/cfn-status/lib")
17
- require "cfn/status"
17
+ require "cfn_status"
18
18
 
19
19
  require "lono/autoloader"
20
20
  Lono::Autoloader.setup
@@ -0,0 +1,38 @@
1
+ require "yaml"
2
+
3
+ class Lono::Blueprint
4
+ class Meta
5
+ extend Memoist
6
+
7
+ def initialize(blueprint)
8
+ @blueprint = blueprint
9
+ end
10
+
11
+ def data
12
+ blueprint_location = Find.find(@blueprint)
13
+ meta_config = "#{blueprint_location}/.meta/config.yml"
14
+ YAML.load_file(meta_config)
15
+ end
16
+ memoize :data
17
+
18
+ %w[blueprint_name template_type].each do |meth|
19
+ define_method meth do
20
+ data[meth]
21
+ end
22
+ end
23
+
24
+ def auto_camelize?(target_section)
25
+ auto_camelize = data['auto_camelize']
26
+ # auto_camelize.nil? for backward compatibility
27
+ return true if auto_camelize.nil? || auto_camelize == true
28
+
29
+ if auto_camelize == "except_resource"
30
+ return target_section != "resource"
31
+ end
32
+
33
+ if auto_camelize.is_a?(Array)
34
+ auto_camelize.include?(target_section)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -38,16 +38,8 @@ class Lono::Cfn
38
38
  begin
39
39
  save_stack(params) # defined in the sub class
40
40
  rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
41
- capabilities = e.message.match(/\[(.*)\]/)[1]
42
- confirm = prompt_for_iam(capabilities)
43
- if confirm =~ /^y/
44
- @options.merge!(capabilities: [capabilities])
45
- puts "Re-running: #{command_with_iam(capabilities).color(:green)}"
46
- retry
47
- else
48
- puts "Exited"
49
- exit
50
- end
41
+ yes = rerun_with_iam?(e)
42
+ retry if yes
51
43
  rescue Aws::CloudFormation::Errors::ValidationError => e
52
44
  if e.message.include?("No updates") # No updates are to be performed.
53
45
  puts "WARN: #{e.message}".color(:yellow)
@@ -102,14 +94,29 @@ class Lono::Cfn
102
94
  end
103
95
 
104
96
  def status
105
- @status ||= Cfn::Status.new(@stack_name)
97
+ @status ||= Status.new(@stack_name)
98
+ end
99
+
100
+ def rerun_with_iam?(e)
101
+ # e.message is "Requires capabilities : [CAPABILITY_IAM]"
102
+ # grab CAPABILITY_IAM with regexp
103
+ capabilities = e.message.match(/\[(.*)\]/)[1]
104
+ confirm = prompt_for_iam(capabilities)
105
+ if confirm =~ /^y/
106
+ @options.merge!(capabilities: [capabilities])
107
+ puts "Re-running: #{command_with_iam(capabilities).color(:green)}"
108
+ true
109
+ else
110
+ puts "Exited"
111
+ exit 1
112
+ end
106
113
  end
107
114
 
108
115
  def prompt_for_iam(capabilities)
109
116
  puts "This stack will create IAM resources. Please approve to run the command again with #{capabilities} capabilities."
110
117
  puts " #{command_with_iam(capabilities)}"
111
118
 
112
- puts "Please confirm (y/n)"
119
+ puts "Please confirm (y/N)"
113
120
  $stdin.gets
114
121
  end
115
122
 
@@ -9,7 +9,7 @@ class Lono::Cfn
9
9
  end
10
10
 
11
11
  def run
12
- message = "Deleted #{@stack_name} stack."
12
+ message = "Deleting #{@stack_name} stack."
13
13
  if @options[:noop]
14
14
  puts "NOOP #{message}"
15
15
  else
@@ -20,6 +20,7 @@ class Lono::Cfn
20
20
  puts message
21
21
  else
22
22
  puts "#{@stack_name.inspect} stack does not exist".color(:red)
23
+ return
23
24
  end
24
25
  end
25
26
 
@@ -30,13 +30,26 @@ module Lono::Cfn::Preview
30
30
  change_set_name: change_set_name,
31
31
  stack_name: @stack_name,
32
32
  parameters: params,
33
- capabilities: capabilities, # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"],
34
33
  }
35
34
  params[:tags] = tags unless tags.empty?
36
35
  set_template_body!(params)
37
36
  show_parameters(params, "cfn.create_change_set")
38
37
  begin
38
+ # Tricky for preview need to set capabilities so that it gets updated. For Base#run save_stack within the begin block already.
39
+ params[:capabilities] = capabilities # ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"]
39
40
  cfn.create_change_set(params)
41
+ rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
42
+ # If coming from cfn_preview_command automatically add iam capabilities
43
+ cfn_preview_command = ARGV.join(" ").include?("cfn preview")
44
+ if cfn_preview_command
45
+ # e.message is "Requires capabilities : [CAPABILITY_IAM]"
46
+ # grab CAPABILITY_IAM with regexp
47
+ capabilities = e.message.match(/\[(.*)\]/)[1]
48
+ @options.merge!(capabilities: [capabilities])
49
+ retry
50
+ end
51
+ yes = rerun_with_iam?(e)
52
+ retry if yes
40
53
  rescue Aws::CloudFormation::Errors::ValidationError => e
41
54
  handle_error(e)
42
55
  end
@@ -19,7 +19,7 @@ class Lono::Cfn
19
19
  end
20
20
 
21
21
  def status
22
- Cfn::Status.new(@stack_name)
22
+ Lono::Cfn::Status.new(@stack_name)
23
23
  end
24
24
  memoize :status
25
25
  end
@@ -1,5 +1,5 @@
1
1
  class Lono::Cfn
2
- class Status < ::Cfn::Status
2
+ class Status < CfnStatus
3
3
  include Util
4
4
 
5
5
  def initialize(stack_name, options={})
@@ -1,46 +1,57 @@
1
1
  ## Examples
2
2
 
3
- lono blueprint new ec2 # skeleton blueprint with barebones structure
3
+ lono blueprint new demo # skeleton blueprint with barebones structure
4
4
 
5
5
  ## Example Output
6
6
 
7
- $ lono blueprint new ec2
8
- => Creating new blueprint called ec2.
9
- create ec2
10
- create ec2/ec2.gemspec
11
- create ec2/.gitignore
12
- create ec2/Gemfile
13
- create ec2/README.md
14
- create ec2/app/definitions/base.rb
15
- create ec2/seed/configs.rb
16
- create ec2/app/templates
17
- => Initialize git repo
18
- run git init from "."
19
- Initialized empty Git repository in /home/ec2-user/environment/infra/blueprints/ec2/.git/
7
+ $ lono blueprint new demo
8
+ => Creating new blueprint called demo.
9
+ create blueprints/demo
10
+ create blueprints/demo/demo.gemspec
11
+ create blueprints/demo/.gitignore
12
+ create blueprints/demo/.meta/config.yml
13
+ create blueprints/demo/CHANGELOG.md
14
+ create blueprints/demo/Gemfile
15
+ create blueprints/demo/README.md
16
+ create blueprints/demo/Rakefile
17
+ create blueprints/demo/seed/configs.rb
18
+ exist blueprints/demo
19
+ create blueprints/demo/app/templates/demo.rb
20
+ create blueprints/demo/app/user_data/bootstrap.sh
21
+ exist blueprints/demo/app/templates
22
+ exist
23
+ create configs/demo/params/development.txt
24
+ create configs/demo/params/production.txt
25
+ create configs/demo/variables/development.rb
26
+ create configs/demo/variables/production.rb
20
27
  => Installing dependencies with: bundle install
28
+ Fetching gem metadata from https://rubygems.org/..........
29
+ ...
30
+ Bundle complete! 4 Gemfile dependencies, 9 gems now installed.
31
+ Use `bundle info [gemname]` to see where a bundled gem is installed.
21
32
  ================================================================
22
33
  Congrats You have successfully created a lono blueprint.
23
34
 
24
35
  Cd into your blueprint and check things out.
25
36
 
26
- cd ec2
37
+ cd demo
27
38
 
28
39
  More info: https://lono.cloud/docs/core/blueprints
29
40
 
30
- Here's the structure your blueprint:
41
+ Here is the structure of your blueprint:
31
42
 
32
43
  .
33
44
  ├── app
34
- │ ├── definitions
35
- │ │ └── base.rb
36
- │ └── templates
37
- ├── ec2.gemspec
45
+ │ ├── templates
46
+ │ │ └── demo.rb
47
+ │ └── user_data
48
+ │ └── bootstrap.sh
49
+ ├── CHANGELOG.md
50
+ ├── demo.gemspec
38
51
  ├── Gemfile
39
52
  ├── Gemfile.lock
53
+ ├── Rakefile
40
54
  ├── README.md
41
- └── setup
55
+ └── seed
42
56
  └── configs.rb
43
-
44
- 4 directories, 6 files
45
-
46
57
  $
@@ -1,3 +1,6 @@
1
1
  ## Examples
2
2
 
3
- lono param generate
3
+ $ lono param generate ecs-asg
4
+ Generating parameter files for blueprint ecs-asg:
5
+ output/ecs-asg/params/development.json
6
+ $
@@ -2,15 +2,22 @@
2
2
 
3
3
  $ lono seed ecs-asg
4
4
  Creating starter config files for ecs-asg
5
- Starter params created: configs/ecs-asg/params/development.txt
5
+ create configs/ecs-asg/params/development.txt
6
6
  $ cat configs/ecs-asg/params/development.txt
7
7
  # Required parameters:
8
- VpcId=vpc-111
9
- Subnets=subnet-111,subnet-222,subnet-333
10
- EcsCluster=development
8
+ VpcId=vpc-111 # Find at vpc CloudFormation Outputs
9
+ Subnets=subnet-111,subnet-222,subnet-333 # Find at vpc CloudFormation Outputs
11
10
  # Optional parameters:
12
11
  # InstanceType=m5.large
13
12
  # KeyName=...
14
13
  # SshLocation=...
15
- # TagName=ecs-asg
16
- $
14
+ # EcsCluster=development
15
+ # TagName=ecs-asg-development
16
+ # ExistingIamInstanceProfile=...
17
+ # ExistingSecurityGroups=...
18
+ # EbsVolumeSize=50
19
+ # MinSize=1
20
+ # MaxSize=4
21
+ # MinInstancesInService=2
22
+ # MaxBatchSize=1
23
+ $
@@ -2,14 +2,28 @@ The `lono summary` command helps you quickly understand a CloudFormation templat
2
2
 
3
3
  ## Examples
4
4
 
5
- $ lono summary ec2
6
- => CloudFormation Template Summary:
7
- Parameters:
8
- Required:
9
- KeyName (AWS::EC2::KeyPair::KeyName)
10
- Optional:
11
- InstanceType (String) Default: t2.micro
12
- SSHLocation (String) Default: 0.0.0.0/0
5
+ $ bundle exec lono summary ec2
6
+ Generating CloudFormation templates for blueprint ec2:
7
+ output/ec2/templates/ec2-old.yml
8
+ output/ec2/templates/ec2-new.yml
9
+ => CloudFormation Template Summary for template ec2-new:
10
+ Required Parameters (0):
11
+ There are no required parameters.
12
+ Optional Parameters (3):
13
+ InstanceType (String) Default: t3.micro
14
+ Subnet (String) Default:
15
+ Vpc (String) Default:
16
+ Resources:
17
+ 1 AWS::EC2::Instance
18
+ 1 AWS::EC2::SecurityGroup
19
+ 2 Total
20
+ => CloudFormation Template Summary for template ec2-old:
21
+ Required Parameters (0):
22
+ There are no required parameters.
23
+ Optional Parameters (3):
24
+ InstanceType (String) Default: t3.micro
25
+ Subnet (String) Default:
26
+ Vpc (String) Default:
13
27
  Resources:
14
28
  1 AWS::EC2::Instance
15
29
  1 AWS::EC2::SecurityGroup
@@ -17,15 +17,16 @@ module Lono::Inspector
17
17
  if parameters.empty?
18
18
  puts "There are no parameters in this template."
19
19
  else
20
- print_parameters("Required Parameters", required_parameters)
21
- print_parameters("Optional Parameters", optional_parameters)
20
+ print_parameters("Required Parameters (#{required_parameters.size})", required_parameters)
21
+ print_parameters("Optional Parameters (#{optional_parameters.size})", optional_parameters)
22
22
  end
23
23
  end
24
24
 
25
25
  def print_parameters(label, parameters)
26
26
  puts "#{label}:"
27
27
  if parameters.empty?
28
- puts " There are no #{label.downcase} parameters"
28
+ text = label.downcase.include?("required") ? "required" : "optional"
29
+ puts " There are no #{text} parameters."
29
30
  else
30
31
  parameters.each do |logical_id, p|
31
32
  output = " #{logical_id} (#{p["Type"]})"
@@ -20,11 +20,11 @@ module Lono
20
20
  end
21
21
 
22
22
  def required_parameters
23
- parameters.reject { |logical_id, p| p["Default"].nil? }
23
+ parameters.select { |logical_id, p| p["Default"].nil? }
24
24
  end
25
25
 
26
26
  def optional_parameters
27
- parameters.select { |logical_id, p| !p["Default"].nil? }
27
+ parameters.reject { |logical_id, p| p["Default"].nil? }
28
28
  end
29
29
 
30
30
  def parameters