terraspace 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/lib/templates/base/git_hook/hook.sh +5 -0
  4. data/lib/templates/base/project/.gitignore +0 -1
  5. data/lib/templates/base/shim/terraspace +7 -0
  6. data/lib/templates/hcl/project/config/terraform/backend.tf.tt +3 -3
  7. data/lib/templates/plugin/lib/templates/hcl/project/config/terraform/backend.tf.tt +2 -2
  8. data/lib/terraspace/app.rb +6 -0
  9. data/lib/terraspace/builder.rb +2 -46
  10. data/lib/terraspace/cli.rb +34 -18
  11. data/lib/terraspace/cli/build/placeholder.rb +40 -0
  12. data/lib/terraspace/cli/cloud.rb +24 -0
  13. data/lib/terraspace/cli/commander.rb +8 -1
  14. data/lib/terraspace/cli/init.rb +67 -0
  15. data/lib/terraspace/cli/list.rb +13 -0
  16. data/lib/terraspace/cli/new.rb +8 -0
  17. data/lib/terraspace/cli/new/git_hook.rb +33 -0
  18. data/lib/terraspace/cli/new/shim.rb +58 -0
  19. data/lib/terraspace/cli/summary.rb +9 -12
  20. data/lib/terraspace/compiler/backend.rb +9 -37
  21. data/lib/terraspace/compiler/backend/parser.rb +42 -0
  22. data/lib/terraspace/compiler/builder.rb +6 -2
  23. data/lib/terraspace/compiler/cleaner.rb +19 -2
  24. data/lib/terraspace/compiler/cleaner/backend_change.rb +1 -1
  25. data/lib/terraspace/compiler/dsl/syntax/mod.rb +1 -0
  26. data/lib/terraspace/compiler/dsl/syntax/mod/backend.rb +16 -3
  27. data/lib/terraspace/compiler/expander.rb +28 -1
  28. data/lib/terraspace/compiler/writer.rb +1 -1
  29. data/lib/terraspace/core.rb +7 -1
  30. data/lib/terraspace/mod.rb +37 -12
  31. data/lib/terraspace/mod/remote.rb +1 -1
  32. data/lib/terraspace/plugin/expander/interface.rb +48 -5
  33. data/lib/terraspace/plugin/infer_provider.rb +15 -0
  34. data/lib/terraspace/plugin/layer/interface.rb +5 -0
  35. data/lib/terraspace/seeder.rb +4 -4
  36. data/lib/terraspace/terraform/api.rb +53 -0
  37. data/lib/terraspace/terraform/api/client.rb +10 -0
  38. data/lib/terraspace/terraform/api/http.rb +106 -0
  39. data/lib/terraspace/terraform/api/var.rb +72 -0
  40. data/lib/terraspace/terraform/api/vars.rb +38 -0
  41. data/lib/terraspace/terraform/api/vars/base.rb +7 -0
  42. data/lib/terraspace/terraform/api/vars/json.rb +14 -0
  43. data/lib/terraspace/terraform/api/vars/rb.rb +21 -0
  44. data/lib/terraspace/terraform/args/custom.rb +1 -1
  45. data/lib/terraspace/terraform/args/default.rb +16 -2
  46. data/lib/terraspace/terraform/cloud.rb +25 -0
  47. data/lib/terraspace/terraform/cloud/workspace.rb +95 -0
  48. data/lib/terraspace/terraform/runner.rb +1 -1
  49. data/lib/terraspace/util/sh.rb +1 -1
  50. data/lib/terraspace/version.rb +1 -1
  51. data/spec/fixtures/{cache_build_dir → cache_dir}/variables.tf +0 -0
  52. data/spec/fixtures/projects/hcl/aws/config/backend.tf +1 -1
  53. data/spec/fixtures/projects/hcl/google/config/backend.tf +1 -1
  54. data/spec/terraspace/seeder_spec.rb +1 -1
  55. data/spec/terraspace/terraform/hooks/builder_spec.rb +1 -1
  56. data/terraspace.gemspec +3 -3
  57. metadata +37 -17
  58. data/lib/terraspace/cli/build.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52456a8edcf3307ed3cbfca13ca35f7ff8fc133e77b4301057208bdcc2e52d26
4
- data.tar.gz: 82cb0191a9fc43d77d68114a8b2f8d7bc80636ed16cee89c3f86f47ecf612d0e
3
+ metadata.gz: 6cfa0c4e6aa1aa9871bc8b1902b283f2b91f5392738a066fdc58efb56153bed1
4
+ data.tar.gz: 2219a5bbbd4dbad228e406d7ce586cf5bfdb8392868478e59e3adbd6dc4adda5
5
5
  SHA512:
6
- metadata.gz: 5921b8059c8e5f8edabbe105e25c7342588267fdf387447c34c31dbb6c925eea6ded8f1f5101cfecb7e5006ec5137ecaa86bf0544643f7f7c8cabdb8c901b657
7
- data.tar.gz: 34a89b19065b07c835c9601524ac7fac28094976b32cbc4f5e802c31623d6e8aaaa36eb5edf581a701c95bc253cf2b2c91b6607550e7658780593d7a1b3895b1
6
+ metadata.gz: f3bb558668074f2e278359a887e369c5182c95fd306973a9cae6c4bd7f95d9be653ce41b923e41e5470350c35234443a0ae3d4e16d5c8b35763feab9393a9c12
7
+ data.tar.gz: 24acaffec5e568152133e014697404cc9d80a2bd79d54b700584db93a5884ca184508544519d349e833a17f84ac1cc4f2d095a787ed5cdb5216f25b37f04fb50
@@ -3,6 +3,27 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.2.0]
7
+ * #34 Terraform Cloud and Terraform Enterprise support added.
8
+ * TFC Vars support: JSON and DSL. config.overwrite and config.overwrite_sensitive configs
9
+ * Build all stacks with config/terraform files. Designed to support the TFC VCS-driven workflow.
10
+ * Layer Interface module added. All latest provider plugins like terraspace\_plugin_aws make use of this module.
11
+ * Backend pattern expansion auto-detects the provider bakcend. The `expansion` method replaces the `backend_expand` method. `backend_expand` is deprecated.
12
+ * New expander variables: TYPE_INSTANCE, INSTANCE, CACHE_ROOT. Also added strip trailing - and / behavior.
13
+ * Timeout for terraform init. The default timeout is 10m and will then print out the terraform init log.
14
+ * Terraspace 0.2.x is compatible with terraspace\_plugin_aws 0.2.x, terraspace\_plugin_google 0.2.x, and terraspace\_plugin_azurerm 0.2.x
15
+ * New commands: terraspace list, terraspace cloud list, terraspace cloud setup, terraspace cloud destroy, terraspace new shim, terraspace new git_hook
16
+ * terraspace list: list of modules and stacks
17
+ * terraspace cloud list: shows list of TFC workspaces
18
+ * terraspace cloud setup: setups up TFC workspace for VCS-driven workflow. This automatically happens for the TFC CLI-driven workflow.
19
+ * terraspace cloud destroy: destroys the TFC workspace associated with the stack. Can also use the `terraspace down demo --destroy-workspace` option.
20
+ * terraspace new shim: An quick way to generate a terraspace shim.
21
+ * terraspace new git_hook: An quick way to set up a git pre-push hook for the TFC VCS-driven workflow.
22
+ * terraspace down: works even if there's no app/stacks folder. A fake stack is built.
23
+ * terraspace build: terraspace build placeholder concept.
24
+ * terraspace build: only builds now. auto bucket backend creation and terraform init is is still automatically called by terraform up, etc.
25
+ * terraspace up: --reconfigure option. This is useful if upgrading Terraform version.
26
+
6
27
  ## [0.1.2]
7
28
  - #33 rspec-terraspace dependency added
8
29
 
@@ -0,0 +1,5 @@
1
+ #!/bin/bash -ex
2
+ echo "Running: terraspace build placeholder"
3
+ <%= terraspace_build_commands %>
4
+ git add .terraspace-cache
5
+ git commit -m 'update .terraspace-cache' || true
@@ -14,7 +14,6 @@ terraform.tfvars
14
14
  *.gem
15
15
  *.rbc
16
16
  .idea
17
- .terraspace-cache
18
17
  /.bundle
19
18
  /.config
20
19
  /.yardoc
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ <%= switch_ruby_version_line %>
3
+ if [ -f config/app.rb ]; then
4
+ exec bundle exec terraspace "$@"
5
+ else
6
+ exec terraspace "$@"
7
+ fi
@@ -3,8 +3,8 @@
3
3
  # terraform {
4
4
  # backend "s3" {
5
5
  # bucket = "<%= options[:bucket] || "terraform-state-:ACCOUNT-:REGION-:ENV" %>"
6
- # key = "<%%= "s3", ":REGION/:ENV/:BUILD_DIR/terraform.tfstate" %> # IE: us-west-2/dev/ec2/modules/vpc/terraform.tfstate
7
- # region = "<%%= "s3", ":REGION" %>"
6
+ # key = "<%%= expansion(":REGION/:ENV/:BUILD_DIR/terraform.tfstate") %> # IE: us-west-2/dev/ec2/modules/vpc/terraform.tfstate
7
+ # region = "<%%= expansion(":REGION") %>"
8
8
  # encrypt = true
9
9
  # dynamodb_table = "terraform_locks"
10
10
  # }
@@ -13,6 +13,6 @@
13
13
  # terraform {
14
14
  # backend "gcs" {
15
15
  # bucket = "<%= options[:bucket] || "terraform-state-:PROJECT-:REGION-:ENV" %>"
16
- # prefix = "<%%= backend_expand("gcs", ":REGION/:ENV/:BUILD_DIR") %>" # IE: us-central1/dev/modules/vm
16
+ # prefix = "<%%= expansion(":REGION/:ENV/:BUILD_DIR") %>" # IE: us-central1/dev/modules/vm
17
17
  # }
18
18
  # }
@@ -1,6 +1,6 @@
1
1
  terraform {
2
2
  backend "PROVIDER_BACKEND" {
3
- bucket = "<%%= backend_expand("PROVIDER_BACKEND", "terraform-state-REPLACE_ME-REPLACE_ME-:ENV") %>" # expanded by terraspace
4
- prefix = "<%%= backend_expand("PROVIDER_BACKEND", "REPLACE_ME/:ENV/:BUILD_DIR") %>" # expanded by terraspace
3
+ bucket = "<%%= expansion("terraform-state-REPLACE_ME-REPLACE_ME-:ENV") %>" # expanded by terraspace
4
+ prefix = "<%%= expansion("REPLACE_ME/:ENV/:BUILD_DIR") %>" # expanded by terraspace
5
5
  }
6
6
  }
@@ -14,6 +14,12 @@ module Terraspace
14
14
  config.logger = Logger.new($stdout)
15
15
  config.logger.level = :info
16
16
  config.hooks = Hooks.new
17
+ config.cloud = ActiveSupport::OrderedOptions.new
18
+ config.cloud.overwrite = true
19
+ config.cloud.overwrite_sensitive = true
20
+ config.build = ActiveSupport::OrderedOptions.new
21
+ config.build.cache_root = nil # defaults to .terraspace-cache
22
+ config.build.cache_dir = ":CACHE_ROOT/:REGION/:ENV/:BUILD_DIR"
17
23
  config
18
24
  end
19
25
 
@@ -4,24 +4,15 @@ module Terraspace
4
4
  Terraspace::CLI::CheckSetup.check!
5
5
  @mod.root_module = true
6
6
  Compiler::Cleaner.new(@mod, @options).clean
7
- build_dir = Util.pretty_path(@mod.cache_build_dir)
7
+ build_dir = Util.pretty_path(@mod.cache_dir)
8
8
  logger.info "Building #{build_dir}"
9
9
 
10
10
  build_all("modules") # build all modules and stacks as dependencies
11
11
  build_all("stacks")
12
- build_root_module # build root module at the end
13
-
14
- auto_create_backend
15
- Terraform::Runner.new("init", @options).run if !auto? && @options[:init] != false # will run on @options[:init].nil?
16
- build_remote_dependencies # runs after terraform init, which downloads remote modules
12
+ build_root_module
17
13
  logger.info "Built in #{build_dir}"
18
14
  end
19
15
 
20
- def auto?
21
- # command is only passed from CLI in the update specifically for this check
22
- @options[:auto] && @options[:command] == "update"
23
- end
24
-
25
16
  def build_root_module
26
17
  Compiler::Builder.new(@mod).build
27
18
  end
@@ -35,22 +26,12 @@ module Terraspace
35
26
 
36
27
  consider_stacks = type_dir == "stacks"
37
28
  mod = Mod.new(mod_name, consider_stacks: consider_stacks)
38
- next if root?(mod) # will build root module at the end
39
29
 
40
30
  Compiler::Builder.new(mod).build
41
31
  built << mod_name
42
32
  end
43
33
  end
44
34
 
45
- def root?(mod)
46
- mod.name == @mod.name && mod.type == @mod.type
47
- end
48
-
49
- def auto_create_backend
50
- return unless @options[:command] == "update"
51
- Compiler::Backend.new(@mod).create
52
- end
53
-
54
35
  def local_paths(type_dir)
55
36
  dirs("app/#{type_dir}/*") + dirs("vendor/#{type_dir}/*")
56
37
  end
@@ -58,30 +39,5 @@ module Terraspace
58
39
  def dirs(path)
59
40
  Dir.glob("#{Terraspace.root}/#{path}")
60
41
  end
61
-
62
- # Currently only handles remote modules only one-level deep.
63
- def build_remote_dependencies
64
- modules_json_path = "#{@mod.cache_build_dir}/.terraform/modules/modules.json"
65
- return unless File.exist?(modules_json_path)
66
-
67
- initialized_modules = JSON.load(IO.read(modules_json_path))
68
- # For example of structure see spec/fixtures/initialized/modules.json
69
- initialized_modules["Modules"].each do |meta|
70
- build_remote_mod(meta)
71
- end
72
- end
73
-
74
- def build_remote_mod(meta)
75
- return if local_source?(meta["Source"])
76
- return if meta['Dir'] == '.' # root is already built
77
-
78
- remote_mod = Mod::Remote.new(meta, @mod)
79
- Compiler::Builder.new(remote_mod).build
80
- end
81
-
82
- private
83
- def local_source?(s)
84
- s =~ %r{^\.} || s =~ %r{^/}
85
- end
86
42
  end
87
43
  end
@@ -24,20 +24,25 @@ module Terraspace
24
24
  init_option = Proc.new {
25
25
  option :init, type: :boolean, default: true, desc: "Instance of stack"
26
26
  }
27
+ reconfigure_option = Proc.new {
28
+ option :reconfigure, type: :boolean, desc: "Add terraform -reconfigure option"
29
+ }
27
30
 
28
31
  desc "new SUBCOMMAND", "new subcommands"
29
32
  long_desc Help.text(:new)
30
33
  subcommand "new", New
31
34
 
32
- desc "build MODULE", "build"
35
+ desc "cloud SUBCOMMAND", "cloud subcommands"
36
+ long_desc Help.text(:cloud)
37
+ subcommand "cloud", Cloud
38
+
39
+ desc "build STACK", "build"
33
40
  long_desc Help.text(:build)
34
41
  option :quiet, type: :boolean, default: true, desc: "quiet output"
35
- auto_option.call
36
- init_option.call
37
- input_option.call
38
42
  instance_option.call
43
+ yes_option.call
39
44
  def build(mod)
40
- Build.new(options.merge(mod: mod)).run
45
+ Terraspace::Builder.new(@options.merge(mod: mod)).run
41
46
  end
42
47
 
43
48
  desc "bundle", "bundle"
@@ -58,22 +63,25 @@ module Terraspace
58
63
  Clean.new(options).run
59
64
  end
60
65
 
61
- desc "console", "console .terraspace-cache dir"
66
+ desc "console STACK", "console .terraspace-cache dir"
62
67
  long_desc Help.text(:console)
63
68
  instance_option.call
64
69
  def console(mod)
65
70
  Commander.new("console", options.merge(mod: mod)).run
66
71
  end
67
72
 
68
- desc "down MODULE", "down"
73
+ desc "down STACK", "down"
69
74
  long_desc Help.text(:down)
70
75
  instance_option.call
71
76
  yes_option.call
77
+ reconfigure_option.call
78
+ option :destroy_workspace, type: :boolean, desc: "Also destroy the Cloud workspace. Only applies when using Terraform Cloud remote backend."
72
79
  def down(mod)
73
- Commander.new("destroy", options.merge(mod: mod)).run
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]
74
82
  end
75
83
 
76
- desc "info MODULE", "info"
84
+ desc "info STACK", "info"
77
85
  long_desc Help.text(:info)
78
86
  format_option.call
79
87
  instance_option.call
@@ -81,31 +89,38 @@ module Terraspace
81
89
  Info.new(options.merge(mod: mod)).run
82
90
  end
83
91
 
84
- desc "plan MODULE", "plan module"
92
+ desc "list", "list stacks and modules"
93
+ long_desc Help.text(:list)
94
+ def list
95
+ List.new(options).run
96
+ end
97
+
98
+ desc "plan STACK", "plan stack"
85
99
  long_desc Help.text(:plan)
86
100
  auto_option.call
87
101
  input_option.call
88
102
  instance_option.call
89
103
  out_option.call
104
+ reconfigure_option.call
90
105
  def plan(mod)
91
106
  Commander.new("plan", options.merge(mod: mod)).run
92
107
  end
93
108
 
94
- desc "providers MODULE", "providers"
109
+ desc "providers STACK", "providers"
95
110
  long_desc Help.text(:providers)
96
111
  instance_option.call
97
112
  def providers(mod)
98
113
  Commander.new("providers", options.merge(mod: mod)).run
99
114
  end
100
115
 
101
- desc "refresh", "refresh"
116
+ desc "refresh STACK", "refresh"
102
117
  long_desc Help.text(:refresh)
103
118
  instance_option.call
104
119
  def refresh(mod)
105
120
  Commander.new("refresh", options.merge(mod: mod)).run
106
121
  end
107
122
 
108
- desc "seed MODULE", "seed"
123
+ desc "seed STACK", "seed"
109
124
  long_desc Help.text(:seed)
110
125
  option :yes, aliases: :y, type: :boolean, desc: "bypass prompts and force overwrite files"
111
126
  option :where, desc: "where to create file. either under app or seed folder structure. values: app or stack"
@@ -124,7 +139,7 @@ module Terraspace
124
139
  Summary.new(options).run
125
140
  end
126
141
 
127
- desc "show MODULE", "show"
142
+ desc "show STACK", "show"
128
143
  long_desc Help.text(:show)
129
144
  instance_option.call
130
145
  def show(mod)
@@ -137,7 +152,7 @@ module Terraspace
137
152
  Test.new(options).run
138
153
  end
139
154
 
140
- desc "output MODULE", "output"
155
+ desc "output STACK", "output"
141
156
  long_desc Help.text(:output)
142
157
  format_option.call
143
158
  instance_option.call
@@ -146,20 +161,21 @@ module Terraspace
146
161
  Commander.new("output", options.merge(mod: mod)).run
147
162
  end
148
163
 
149
- desc "update MODULE", "Update infrasturcture. IE: apply plan"
164
+ desc "update STACK", "Update infrasturcture. IE: apply plan"
150
165
  long_desc Help.text(:update)
151
166
  auto_option.call
152
167
  init_option.call
153
168
  input_option.call
154
169
  instance_option.call
155
170
  yes_option.call
171
+ reconfigure_option.call
156
172
  option :plan, desc: "Execution plan that can be used to only execute a pre-determined set of actions."
157
173
  option :var_files, type: :array, desc: "list of var files"
158
174
  def update(mod)
159
- Commander.new("apply", options.merge(mod: mod, command: "update")).run
175
+ Commander.new("apply", options.merge(mod: mod)).run
160
176
  end
161
177
 
162
- desc "validate MODULE", "validate"
178
+ desc "validate STACK", "validate"
163
179
  long_desc Help.text(:validate)
164
180
  instance_option.call
165
181
  def validate(mod)
@@ -0,0 +1,40 @@
1
+ # The placeholder stack is a special stack that is useful in case there are no app/stacks.
2
+ # We build a placeholder back just so we have backend.tf to be used to grab info.
3
+ # It's useful for the summary command.
4
+ module Terraspace::CLI::Build
5
+ class Placeholder
6
+ include Terraspace::Util::Logging
7
+
8
+ def initialize(options={})
9
+ @options = options
10
+ end
11
+
12
+ # Grab the last module and build that.
13
+ # Assume the backend key has the same prefix
14
+ # Note: Tried building a empty "null" stack but with TFC a null space workspace is created, which is undesired.
15
+ def build
16
+ return if ENV['TS_SUMMARY_BUILD'] == '0'
17
+
18
+ mod = @options[:mod]
19
+ if !mod or mod == "placeholder"
20
+ logger.info "Building one of the modules to get backend.tf info"
21
+ mod = find_mod
22
+ end
23
+ Terraspace::Builder.new(@options.merge(mod: mod, init: false)).run # generate and init
24
+ Terraspace::Mod.new(mod, @options) # mod metadata
25
+ end
26
+
27
+ # Used by: terraspace build placeholder
28
+ def find_mod
29
+ mod_path = Dir.glob("{app,vendor}/{modules,stacks}/*").last
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
35
+ exit 0
36
+ end
37
+ File.basename(mod_path) # mod name
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,24 @@
1
+ class Terraspace::CLI
2
+ class Cloud < Terraspace::Command
3
+ Workspace = Terraspace::Terraform::Cloud::Workspace
4
+
5
+ desc "list", "List workspaces"
6
+ long_desc Help.text("cloud:list")
7
+ def list
8
+ Workspace.new(options).list
9
+ end
10
+
11
+ desc "destroy", "Destroy workspace"
12
+ long_desc Help.text("cloud:destroy")
13
+ option :yes, aliases: :y, type: :boolean, desc: "bypass are you sure prompt"
14
+ def destroy(mod)
15
+ Workspace.new(options.merge(mod: mod)).destroy
16
+ end
17
+
18
+ desc "setup", "Setup workspace"
19
+ long_desc Help.text("cloud:setup")
20
+ def setup(mod)
21
+ Workspace.new(options.merge(mod: mod)).setup
22
+ end
23
+ end
24
+ end
@@ -7,8 +7,15 @@ class Terraspace::CLI
7
7
 
8
8
  # Commander always runs Build#run
9
9
  def run
10
- Build.new(@options).run # generate and init
10
+ Terraspace::Builder.new(@options).run # generate and init
11
+ auto_create_backend
12
+ Init.new(@options.merge(calling_command: @name)).run
11
13
  Terraspace::Terraform::Runner.new(@name, @options).run
12
14
  end
15
+
16
+ def auto_create_backend
17
+ return unless @name == "apply"
18
+ Terraspace::Compiler::Backend.new(@mod).create
19
+ end
13
20
  end
14
21
  end
@@ -0,0 +1,67 @@
1
+ require 'timeout'
2
+
3
+ class Terraspace::CLI
4
+ class Init < Base
5
+ def initialize(options={})
6
+ # Original calling command. Can be from Commander which is a terraform command. IE: terraform apply
7
+ # Or can be from terraspace cloud setup. Which will be cloud-setup.
8
+ @calling_command = options[:calling_command]
9
+ super(options)
10
+ end
11
+
12
+ def run
13
+ init if init?
14
+ build_remote_dependencies # runs after terraform init, which downloads remote modules
15
+ sync_cloud
16
+ end
17
+
18
+ # Note the init will always create the Terraform Cloud Workspace
19
+ def init
20
+ # default init timeout is pretty generous in case of slow internet to download the provider plugins
21
+ init_timeout = Integer(ENV['TS_INIT_TIMEOUT'] || 600)
22
+ Timeout::timeout(init_timeout) do
23
+ Terraspace::Terraform::Runner.new("init", @options).run if !auto? && @options[:init] != false # will run on @options[:init].nil?
24
+ end
25
+ rescue Timeout::Error
26
+ logger.error "ERROR: It took too long to run terraform init. Here is the output logs of terraform init:".color(:red)
27
+ logger.error IO.read(Terraspace::Terraform::Args::Default.terraform_init_log)
28
+ end
29
+
30
+ def sync_cloud
31
+ Terraspace::Terraform::Cloud.new(@options).run if %w[apply plan destroy cloud-setup].include?(@calling_command)
32
+ end
33
+
34
+ # Currently only handles remote modules only one-level deep.
35
+ def build_remote_dependencies
36
+ modules_json_path = "#{@mod.cache_dir}/.terraform/modules/modules.json"
37
+ return unless File.exist?(modules_json_path)
38
+
39
+ initialized_modules = JSON.load(IO.read(modules_json_path))
40
+ # For example of structure see spec/fixtures/initialized/modules.json
41
+ initialized_modules["Modules"].each do |meta|
42
+ build_remote_mod(meta)
43
+ end
44
+ end
45
+
46
+ def build_remote_mod(meta)
47
+ return if local_source?(meta["Source"])
48
+ return if meta['Dir'] == '.' # root is already built
49
+
50
+ remote_mod = Mod::Remote.new(meta, @mod)
51
+ Compiler::Builder.new(remote_mod).build
52
+ end
53
+
54
+ def auto?
55
+ # command is only passed from CLI in the update specifically for this check
56
+ @options[:auto] && @calling_command == "apply"
57
+ end
58
+ private
59
+ def local_source?(s)
60
+ s =~ %r{^\.} || s =~ %r{^/}
61
+ end
62
+
63
+ def init?
64
+ %w[apply console destroy output plan providers refresh show validate cloud-setup].include?(@calling_command)
65
+ end
66
+ end
67
+ end