lono 5.3.4 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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