terraspace 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -1
  3. data/README.md +14 -1
  4. data/lib/templates/base/git_hook/hook.sh +1 -1
  5. data/lib/templates/base/project/.gitignore +1 -0
  6. data/lib/templates/base/project/README.md +17 -0
  7. data/lib/terraspace.rb +4 -0
  8. data/lib/terraspace/all/base.rb +8 -0
  9. data/lib/terraspace/all/grapher.rb +129 -0
  10. data/lib/terraspace/all/preview.rb +43 -0
  11. data/lib/terraspace/all/runner.rb +169 -0
  12. data/lib/terraspace/all/summary.rb +99 -0
  13. data/lib/terraspace/app.rb +30 -9
  14. data/lib/terraspace/booter.rb +9 -0
  15. data/lib/terraspace/builder.rb +51 -23
  16. data/lib/terraspace/cli.rb +39 -12
  17. data/lib/terraspace/cli/all.rb +63 -0
  18. data/lib/terraspace/cli/build/placeholder.rb +2 -5
  19. data/lib/terraspace/cli/bundle.rb +1 -1
  20. data/lib/terraspace/cli/check_setup.rb +5 -0
  21. data/lib/terraspace/cli/cloud.rb +18 -2
  22. data/lib/terraspace/cli/cloud/runs.rb +24 -0
  23. data/lib/terraspace/cli/commander.rb +6 -3
  24. data/lib/terraspace/cli/down.rb +20 -0
  25. data/lib/terraspace/cli/help/cloud/runs/list.md +36 -0
  26. data/lib/terraspace/cli/help/cloud/runs/prune.md +25 -0
  27. data/lib/terraspace/cli/help/cloud/sync.md +19 -0
  28. data/lib/terraspace/cli/help/log.md +42 -0
  29. data/lib/terraspace/cli/init.rb +35 -7
  30. data/lib/terraspace/cli/list.rb +14 -1
  31. data/lib/terraspace/cli/log.rb +112 -0
  32. data/lib/terraspace/cli/log/concern.rb +24 -0
  33. data/lib/terraspace/cli/logs.rb +15 -0
  34. data/lib/terraspace/cli/logs/tasks.rb +32 -0
  35. data/lib/terraspace/cli/new/git_hook.rb +1 -1
  36. data/lib/terraspace/cli/tfc_concern.rb +14 -0
  37. data/lib/terraspace/cli/up.rb +32 -0
  38. data/lib/terraspace/compiler/builder.rb +3 -3
  39. data/lib/terraspace/compiler/cleaner.rb +1 -1
  40. data/lib/terraspace/compiler/cleaner/backend_change.rb +21 -7
  41. data/lib/terraspace/compiler/dirs_concern.rb +47 -0
  42. data/lib/terraspace/compiler/dsl/syntax/helpers/common.rb +26 -1
  43. data/lib/terraspace/core.rb +11 -2
  44. data/lib/terraspace/dependency/graph.rb +139 -0
  45. data/lib/terraspace/dependency/node.rb +38 -0
  46. data/lib/terraspace/dependency/registry.rb +11 -0
  47. data/lib/terraspace/logger.rb +6 -18
  48. data/lib/terraspace/logger/formatter.rb +13 -0
  49. data/lib/terraspace/mod.rb +7 -1
  50. data/lib/terraspace/seeder/where.rb +6 -2
  51. data/lib/terraspace/shell.rb +79 -0
  52. data/lib/terraspace/terraform/api.rb +7 -45
  53. data/lib/terraspace/terraform/api/base.rb +7 -0
  54. data/lib/terraspace/terraform/api/client.rb +23 -3
  55. data/lib/terraspace/terraform/api/http.rb +14 -34
  56. data/lib/terraspace/terraform/api/http/concern.rb +10 -0
  57. data/lib/terraspace/terraform/api/runs.rb +28 -0
  58. data/lib/terraspace/terraform/api/token.rb +65 -0
  59. data/lib/terraspace/terraform/api/var.rb +20 -6
  60. data/lib/terraspace/terraform/api/vars.rb +2 -1
  61. data/lib/terraspace/terraform/api/workspace.rb +98 -0
  62. data/lib/terraspace/terraform/args/default.rb +48 -21
  63. data/lib/terraspace/terraform/cloud/runs.rb +13 -0
  64. data/lib/terraspace/terraform/cloud/runs/base.rb +33 -0
  65. data/lib/terraspace/terraform/cloud/runs/item_presenter.rb +37 -0
  66. data/lib/terraspace/terraform/cloud/runs/lister.rb +22 -0
  67. data/lib/terraspace/terraform/cloud/runs/pruner.rb +109 -0
  68. data/lib/terraspace/terraform/cloud/sync.rb +41 -0
  69. data/lib/terraspace/terraform/cloud/syncer.rb +52 -0
  70. data/lib/terraspace/terraform/cloud/workspace.rb +10 -21
  71. data/lib/terraspace/terraform/hooks/builder.rb +1 -1
  72. data/lib/terraspace/terraform/remote_state/fetcher.rb +122 -0
  73. data/lib/terraspace/terraform/remote_state/marker/output.rb +39 -0
  74. data/lib/terraspace/terraform/remote_state/marker/pretty_tracer.rb +37 -0
  75. data/lib/terraspace/terraform/remote_state/output_proxy.rb +29 -0
  76. data/lib/terraspace/terraform/runner.rb +24 -14
  77. data/lib/terraspace/util.rb +1 -5
  78. data/lib/terraspace/util/pretty.rb +18 -0
  79. data/lib/terraspace/version.rb +1 -1
  80. data/spec/fixtures/fetcher/c1.json +37 -0
  81. data/spec/fixtures/parser/cache_dirs/all/01-test.auto.tfvars +5 -0
  82. data/spec/fixtures/parser/cache_dirs/depends_on/01-test.auto.tfvars +2 -0
  83. data/spec/fixtures/parser/cache_dirs/output/01-test.auto.tfvars +2 -0
  84. data/spec/fixtures/summary/down.log +12 -0
  85. data/spec/fixtures/summary/output.log +5 -0
  86. data/spec/fixtures/summary/plan/error.log +20 -0
  87. data/spec/fixtures/summary/plan/success.log +17 -0
  88. data/spec/fixtures/summary/show.log +22 -0
  89. data/spec/fixtures/summary/up/error.log +13 -0
  90. data/spec/fixtures/summary/up/success.log +63 -0
  91. data/spec/fixtures/summary/validate/error.log +13 -0
  92. data/spec/fixtures/summary/validate/success.log +5 -0
  93. data/spec/terraspace/all/grapher_spec.rb +38 -0
  94. data/spec/terraspace/all/runner_spec.rb +48 -0
  95. data/spec/terraspace/all/summary_spec.rb +93 -0
  96. data/spec/terraspace/dependency/graph_spec.rb +162 -0
  97. data/spec/terraspace/seeder_spec.rb +0 -1
  98. data/spec/terraspace/terraform/remote_state/fetcher_spec.rb +52 -0
  99. data/terraspace.gemspec +5 -1
  100. metadata +137 -5
  101. data/lib/terraspace/terraform/cloud.rb +0 -25
  102. data/lib/terraspace/util/sh.rb +0 -19
@@ -0,0 +1,99 @@
1
+ module Terraspace::All
2
+ class Summary
3
+ include Terraspace::CLI::Log::Concern
4
+ include Terraspace::Util::Logging
5
+
6
+ def initialize(data={})
7
+ @data = data
8
+ @command = data[:command]
9
+ @log_path = data[:log_path]
10
+ @terraspace_command = data[:terraspace_command]
11
+ end
12
+
13
+ @@header_shown = false
14
+ def run
15
+ @lines = readlines(@log_path)
16
+ if respond_to?(@command.to_sym)
17
+ send(@command)
18
+ else
19
+ default
20
+ end
21
+ summarize
22
+ end
23
+
24
+ # Examples of "complete" line:
25
+ # [2020-09-06T21:58:25 #11313 terraspace up b1]: Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
26
+ # [2020-09-07T08:28:15 #26093 terraspace down a1]: Destroy complete! Resources: 2 destroyed.
27
+ #
28
+ # handles: up and down
29
+ def default
30
+ @lines.select! do |line|
31
+ line.include?("complete! Resources:") || # success: handles both apply and destroy output
32
+ line.include?("Changes to Outputs") ||
33
+ line.include?("No changes") ||
34
+ line.include?("Error: ") # error
35
+ end
36
+ end
37
+
38
+ # Example 1:
39
+ # [2020-09-07T14:45:14 #23340 terraspace plan b1]: No changes. Infrastructure is up-to-date.
40
+ # Example 2:
41
+ # [2020-09-07T14:46:58 #31974 terraspace plan b1]: Changes to Outputs:
42
+ # [2020-09-07T14:46:58 #31974 terraspace plan b1]: ~ length = 1 -> 2
43
+ def plan
44
+ @lines.select! do |line|
45
+ line.include?("No changes. Infrastructure") ||
46
+ line.include?("Changes to Outputs") ||
47
+ line.include?("Plan:") ||
48
+ line.include?("Changes to ") ||
49
+ line.include?("Error: ") # error
50
+ end
51
+ end
52
+
53
+ def output
54
+ @lines # pass through all output info
55
+ end
56
+
57
+ def show
58
+ resources = @lines.grep(/: resource "/).count
59
+ outputs = count_outputs(@lines)
60
+ summary = "Resources: #{resources} Outputs: #{outputs}"
61
+ # get summary line before running select! which will remove lines
62
+ @lines.select! do |line|
63
+ line.include?("Error: ") # error
64
+ end
65
+ @lines.unshift(summary) # add to top
66
+ end
67
+
68
+ # [2020-09-07T14:53:36 #31106 terraspace show b1]: Outputs:
69
+ # [2020-09-07T14:53:36 #31106 terraspace show b1]:
70
+ # [2020-09-07T14:53:36 #31106 terraspace show b1]: length = 1
71
+ # [2020-09-07T14:53:36 #31106 terraspace show b1]: length2 = 2
72
+ # [2020-09-07T14:53:36 #31106 terraspace show b1]: random_pet_id = "corgi"
73
+ def count_outputs(lines)
74
+ count = 0
75
+ counting = false
76
+ lines.each do |line|
77
+ counting ||= line.include?(": Outputs:")
78
+ count += 1 if counting && line.include?(' = ')
79
+ end
80
+ count
81
+ end
82
+
83
+ # [2020-09-07T13:51:45 #21323 terraspace validate a1]: Success! The configuration is valid.
84
+ def validate
85
+ @lines.select! do |line|
86
+ line.include?("The configuration is") || # success
87
+ line.include?("Error: ") # error
88
+ end
89
+ end
90
+
91
+ private
92
+ def summarize
93
+ @lines.each do |line|
94
+ line.sub!(/.*\]:\s+/, ' ') # remove log info from line
95
+ logger.info("#{@terraspace_command}: #{line}")
96
+ end
97
+ end
98
+ end
99
+ end
@@ -10,18 +10,39 @@ module Terraspace
10
10
 
11
11
  def defaults
12
12
  config = ActiveSupport::OrderedOptions.new
13
- config.test_framework = "rspec"
14
- config.logger = Logger.new($stdout)
15
- config.logger.level = :info
16
- config.hooks = Hooks.new
17
- config.cloud = ActiveSupport::OrderedOptions.new
18
- config.cloud.overwrite = true
19
- config.cloud.overwrite_sensitive = true
20
- config.cloud.relative_root = nil
13
+ config.all = ActiveSupport::OrderedOptions.new
14
+ config.all.concurrency = 5
15
+ config.all.exit_on_fail = ActiveSupport::OrderedOptions.new
16
+ config.all.exit_on_fail.down = true
17
+ config.all.exit_on_fail.up = true
18
+ config.all.ignore_stacks = []
21
19
  config.build = ActiveSupport::OrderedOptions.new
22
- config.build.cache_root = nil # defaults to /full/path/to/.terraspace-cache
23
20
  config.build.cache_dir = ":CACHE_ROOT/:REGION/:ENV/:BUILD_DIR"
21
+ config.build.cache_root = nil # defaults to /full/path/to/.terraspace-cache
24
22
  config.build.clean_cache = nil # defaults to /full/path/to/.terraspace-cache
23
+ config.cloud = ActiveSupport::OrderedOptions.new
24
+ config.cloud.auto_sync = true
25
+ config.cloud.working_dir_prefix = nil
26
+ config.cloud.hostname = nil
27
+ config.cloud.vars = ActiveSupport::OrderedOptions.new
28
+ config.cloud.vars.overwrite = true
29
+ config.cloud.vars.overwrite_sensitive = true
30
+ config.cloud.vars.show_message = "create"
31
+ config.cloud.workspace = ActiveSupport::OrderedOptions.new
32
+ config.cloud.workspace.attrs = ActiveSupport::OrderedOptions.new
33
+ config.hooks = Hooks.new
34
+ config.init = ActiveSupport::OrderedOptions.new
35
+ config.init.mode = "auto" # auto, never, always
36
+ config.log = ActiveSupport::OrderedOptions.new
37
+ config.log.root = Terraspace.log_root
38
+ config.logger = Logger.new(ENV['TS_LOG_PATH'] || $stderr)
39
+ config.logger.level = ENV['TS_LOG_LEVEL'] || :info
40
+ config.logger.formatter = Logger::Formatter.new
41
+ config.test_framework = "rspec"
42
+ config.terraform = ActiveSupport::OrderedOptions.new
43
+ config.terraform.plugin_cache = ActiveSupport::OrderedOptions.new
44
+ config.terraform.plugin_cache.enabled = true
45
+ config.terraform.plugin_cache.dir = ENV['TF_PLUGIN_CACHE_DIR'] || "#{Terraspace.tmp_root}/plugin_cache"
25
46
  config
26
47
  end
27
48
 
@@ -5,6 +5,7 @@ module Terraspace
5
5
  load_plugin_default_configs
6
6
  Terraspace.config # load project config
7
7
  Terraspace::App::Hooks.run_hook(:on_boot)
8
+ set_plugin_cache!
8
9
  end
9
10
 
10
11
  def load_plugin_default_configs
@@ -14,6 +15,14 @@ module Terraspace
14
15
  end
15
16
  end
16
17
 
18
+ def set_plugin_cache!
19
+ plugin_cache = Terraspace.config.terraform.plugin_cache
20
+ return unless plugin_cache.enabled
21
+ dir = ENV['TF_PLUGIN_CACHE_DIR'] ||= plugin_cache.dir
22
+ FileUtils.mkdir_p(dir)
23
+ dir
24
+ end
25
+
17
26
  extend self
18
27
  end
19
28
  end
@@ -1,48 +1,76 @@
1
1
  module Terraspace
2
2
  class Builder < Terraspace::CLI::Base
3
+ include Compiler::DirsConcern
4
+
5
+ attr_reader :graph
6
+
3
7
  def run
8
+ return if @options[:build] == false
4
9
  Terraspace::CLI::CheckSetup.check!
5
10
  @mod.root_module = true
6
- Compiler::Cleaner.new(@mod, @options).clean if clean?
11
+ clean
7
12
  build_dir = Util.pretty_path(@mod.cache_dir)
8
- logger.info "Building #{build_dir}"
13
+ placeholder_stack_message
14
+ logger.info "Building #{build_dir}" unless @options[:quiet] # from terraspace all
15
+
16
+ build_unresolved
17
+ batches = build_batches
18
+ build_all
19
+ logger.info "Built in #{build_dir}" unless @options[:quiet] # from terraspace all
20
+ batches
21
+ end
22
+
23
+ # Builds dependency graph and returns the batches to run
24
+ def build_batches
25
+ dependencies = Terraspace::Dependency::Registry.data # populated after build_unresolved
26
+ @graph = Terraspace::Dependency::Graph.new(stack_names, dependencies, @options)
27
+ @graph.build
28
+ end
9
29
 
10
- build_all("modules") # build all modules and stacks as dependencies
11
- build_all("stacks")
30
+ def build_all
31
+ # At this point dependencies have been resolved.
32
+ Terraspace::Terraform::RemoteState::Fetcher.flush!
33
+ @resolved = true
34
+ build_unresolved
35
+ end
36
+
37
+ def build_unresolved
38
+ build_dir("modules")
39
+ build_dir("stacks")
12
40
  build_root_module
13
- logger.info "Built in #{build_dir}"
14
41
  end
15
42
 
16
43
  def build_root_module
44
+ @mod.resolved = @resolved
17
45
  Compiler::Builder.new(@mod).build
18
46
  end
19
47
 
20
- def build_all(type_dir)
21
- built = []
22
- local_paths(type_dir).each do |path|
23
- next unless File.directory?(path)
24
- mod_name = File.basename(path)
25
- next if built.include?(mod_name) # ensures modules in app folder take higher precedence than vendor folder
26
-
27
- consider_stacks = type_dir == "stacks"
28
- mod = Mod.new(mod_name, consider_stacks: consider_stacks)
29
-
48
+ def build_dir(type_dir)
49
+ with_each_mod(type_dir) do |mod|
50
+ mod.resolved = @resolved
51
+ is_root_module = mod.cache_dir == @mod.cache_dir
52
+ next if is_root_module # handled by build_root_module
30
53
  Compiler::Builder.new(mod).build
31
- built << mod_name
32
54
  end
33
55
  end
34
56
 
35
- def local_paths(type_dir)
36
- dirs("app/#{type_dir}/*") + dirs("vendor/#{type_dir}/*")
57
+ def clean
58
+ Compiler::Cleaner.new(@mod, @options).clean if clean?
37
59
  end
38
60
 
39
- def dirs(path)
40
- Dir.glob("#{Terraspace.root}/#{path}")
61
+ def clean?
62
+ if @options[:clean].nil?
63
+ clean_cache = Terraspace.config.build.clean_cache
64
+ clean_cache.nil? ? true : clean_cache
65
+ else
66
+ @options[:clean]
67
+ end
41
68
  end
42
69
 
43
- def clean?
44
- clean_cache = Terraspace.config.build.clean_cache
45
- clean_cache.nil? ? true : clean_cache
70
+ def placeholder_stack_message
71
+ return if @options[:quiet]
72
+ return unless @options[:mod] == "placeholder"
73
+ logger.info "Building one stack to build all stacks"
46
74
  end
47
75
  end
48
76
  end
@@ -28,21 +28,29 @@ module Terraspace
28
28
  option :reconfigure, type: :boolean, desc: "Add terraform -reconfigure option"
29
29
  }
30
30
 
31
- desc "new SUBCOMMAND", "new subcommands"
32
- long_desc Help.text(:new)
33
- subcommand "new", New
31
+ desc "all SUBCOMMAND", "all subcommands"
32
+ long_desc Help.text(:all)
33
+ subcommand "all", All
34
34
 
35
35
  desc "cloud SUBCOMMAND", "cloud subcommands"
36
36
  long_desc Help.text(:cloud)
37
37
  subcommand "cloud", Cloud
38
38
 
39
- desc "build STACK", "build"
39
+ desc "logs SUBCOMMAND", "logs management subcommands"
40
+ long_desc Help.text(:logs)
41
+ subcommand "logs", Logs
42
+
43
+ desc "new SUBCOMMAND", "new subcommands"
44
+ long_desc Help.text(:new)
45
+ subcommand "new", New
46
+
47
+ desc "build [STACK]", "build"
40
48
  long_desc Help.text(:build)
41
- option :quiet, type: :boolean, default: true, desc: "quiet output"
49
+ option :quiet, type: :boolean, desc: "quiet output"
42
50
  instance_option.call
43
51
  yes_option.call
44
- def build(mod)
45
- Terraspace::Builder.new(@options.merge(mod: mod)).run
52
+ def build(mod="placeholder")
53
+ Terraspace::Builder.new(options.merge(mod: mod)).run # building any stack builds them all
46
54
  end
47
55
 
48
56
  desc "bundle", "bundle"
@@ -77,8 +85,7 @@ module Terraspace
77
85
  reconfigure_option.call
78
86
  option :destroy_workspace, type: :boolean, desc: "Also destroy the Cloud workspace. Only applies when using Terraform Cloud remote backend."
79
87
  def down(mod)
80
- Commander.new("destroy", options.merge(mod: mod, command: "down")).run
81
- Terraspace::Terraform::Cloud::Workspace.new(options.merge(mod: mod)).destroy if @options[:destroy_workspace]
88
+ Down.new(options.merge(mod: mod)).run
82
89
  end
83
90
 
84
91
  desc "info STACK", "info"
@@ -89,12 +96,30 @@ module Terraspace
89
96
  Info.new(options.merge(mod: mod)).run
90
97
  end
91
98
 
99
+ desc "init STACK", "init"
100
+ long_desc Help.text(:init)
101
+ instance_option.call
102
+ def init(mod)
103
+ Commander.new("init", options.merge(mod: mod, quiet: false)).run
104
+ end
105
+
92
106
  desc "list", "list stacks and modules"
93
107
  long_desc Help.text(:list)
108
+ option :type, aliases: %w[t], desc: "Type: stack or module. Default all"
94
109
  def list
95
110
  List.new(options).run
96
111
  end
97
112
 
113
+ desc "log [ACTION] [STACK]", "The all log command allows you to view multiple logs."
114
+ long_desc Help.text("log")
115
+ option :timestamps, aliases: %w[t], type: :boolean, desc: "Whether or not to show the leading timestamp. Defaults to timestamps for multiple logs, and no timestamp if a single log is specified. Note: In follow mode, timestamp always shown"
116
+ option :follow, aliases: %w[f], type: :boolean, desc: "Follow the log in live tail fashion. Must specify a stack if using this option."
117
+ option :limit, aliases: %w[n], default: 10, type: :numeric, desc: "Number of lines to limit showing. Only applies in no-follow mode."
118
+ option :all, aliases: %w[a], type: :boolean, desc: "All mode turns off the limit. Defaults to all if a single log is specified. Only applies in no-follow mode."
119
+ def log(action=nil, stack=nil)
120
+ Log.new(@options.merge(action: action, stack: stack)).run
121
+ end
122
+
98
123
  desc "plan STACK", "plan stack"
99
124
  long_desc Help.text(:plan)
100
125
  auto_option.call
@@ -142,6 +167,8 @@ module Terraspace
142
167
  desc "show STACK", "show"
143
168
  long_desc Help.text(:show)
144
169
  instance_option.call
170
+ option :plan, desc: "path to created.plan"
171
+ option :json, type: :boolean, desc: "show plan in json format"
145
172
  def show(mod)
146
173
  Commander.new("show", options.merge(mod: mod)).run
147
174
  end
@@ -161,7 +188,7 @@ module Terraspace
161
188
  Commander.new("output", options.merge(mod: mod)).run
162
189
  end
163
190
 
164
- desc "update STACK", "Update infrasturcture. IE: apply plan"
191
+ desc "up STACK", "Deploy infrastructure. IE: terraform apply"
165
192
  long_desc Help.text(:update)
166
193
  auto_option.call
167
194
  init_option.call
@@ -171,8 +198,8 @@ module Terraspace
171
198
  reconfigure_option.call
172
199
  option :plan, desc: "Execution plan that can be used to only execute a pre-determined set of actions."
173
200
  option :var_files, type: :array, desc: "list of var files"
174
- def update(mod)
175
- Commander.new("apply", options.merge(mod: mod)).run
201
+ def up(mod)
202
+ Up.new(options.merge(mod: mod)).run
176
203
  end
177
204
 
178
205
  desc "validate STACK", "validate"
@@ -0,0 +1,63 @@
1
+ class Terraspace::CLI
2
+ class All < Terraspace::Command
3
+ class_option :yes, aliases: :y, type: :boolean, desc: "auto approve all batch commands"
4
+ class_option :exit_on_fail, type: :boolean, desc: "whether or not to exit when one of the batch commands fails"
5
+
6
+ desc "down", "destroy all"
7
+ long_desc Help.text("all/down")
8
+ option :destroy_workspace, type: :boolean, desc: "Also destroy the Cloud workspace. Only applies when using Terraform Cloud remote backend."
9
+ def down(*stacks)
10
+ Terraspace::All::Runner.new("down", @options.merge(stacks: stacks)).run
11
+ end
12
+
13
+ desc "graph", "graph all"
14
+ long_desc Help.text("all/graph")
15
+ option :format, default: "png", desc: "format: text or diagram"
16
+ option :full,type: :boolean, desc: "draw the full graph with highlighted nodes or draw the subgraph. text format defaults to false, graph format defaults to true"
17
+ def graph(*stacks)
18
+ Terraspace::All::Grapher.new(@options.merge(stacks: stacks)).run
19
+ end
20
+
21
+ desc "refresh", "refresh all"
22
+ long_desc Help.text("all/refresh")
23
+ def refresh(*stacks)
24
+ Terraspace::All::Runner.new("refresh", @options.merge(stacks: stacks)).run
25
+ end
26
+
27
+ desc "output", "output all"
28
+ long_desc Help.text("all/output")
29
+ def output(*stacks)
30
+ Terraspace::All::Runner.new("output", @options.merge(stacks: stacks)).run
31
+ end
32
+
33
+ desc "plan", "plan all"
34
+ long_desc Help.text("all/plan")
35
+ def plan(*stacks)
36
+ Terraspace::All::Runner.new("plan", @options.merge(stacks: stacks)).run
37
+ end
38
+
39
+ desc "providers", "providers all"
40
+ long_desc Help.text("all/providers")
41
+ def providers(*stacks)
42
+ Terraspace::All::Runner.new("providers", @options.merge(stacks: stacks)).run
43
+ end
44
+
45
+ desc "show", "show all"
46
+ long_desc Help.text("all/show")
47
+ def show(*stacks)
48
+ Terraspace::All::Runner.new("show", @options.merge(stacks: stacks)).run
49
+ end
50
+
51
+ desc "up", "deploy all"
52
+ long_desc Help.text("all/up")
53
+ def up(*stacks)
54
+ Terraspace::All::Runner.new("up", @options.merge(stacks: stacks)).run
55
+ end
56
+
57
+ desc "validate", "validate all"
58
+ long_desc Help.text("all/validate")
59
+ def validate(*stacks)
60
+ Terraspace::All::Runner.new("validate", @options.merge(stacks: stacks)).run
61
+ end
62
+ end
63
+ end
@@ -16,7 +16,7 @@ module Terraspace::CLI::Build
16
16
  return if ENV['TS_SUMMARY_BUILD'] == '0'
17
17
 
18
18
  mod = @options[:mod]
19
- if !mod or mod == "placeholder"
19
+ if !mod or %w[placeholder].include?(mod)
20
20
  logger.info "Building one of the modules to get backend.tf info"
21
21
  mod = find_mod
22
22
  end
@@ -28,10 +28,7 @@ module Terraspace::CLI::Build
28
28
  def find_mod
29
29
  mod_path = Dir.glob("{app,vendor}/{modules,stacks}/*").last
30
30
  unless mod_path
31
- logger.info <<~EOL
32
- No modules or stacks found.
33
- Unable to determine the backend state path without at least one module.
34
- EOL
31
+ logger.info "No modules or stacks found."
35
32
  exit 0
36
33
  end
37
34
  File.basename(mod_path) # mod name