terraspace 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +1 -1
- data/lib/terraspace.rb +1 -0
- data/lib/terraspace/builder.rb +2 -7
- data/lib/terraspace/cli.rb +1 -1
- data/lib/terraspace/cli/help/cloud/runs/prune.md +1 -1
- data/lib/terraspace/cli/help/log.md +6 -2
- data/lib/terraspace/compiler/backend.rb +10 -0
- data/lib/terraspace/compiler/builder.rb +2 -1
- data/lib/terraspace/compiler/commands_concern.rb +18 -0
- data/lib/terraspace/shell.rb +30 -12
- data/lib/terraspace/terraform/remote_state/fetcher.rb +24 -3
- data/lib/terraspace/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4501185815eeebafbdadd49e8afac52af4fc1c6b8d6d297269614482a38df47
|
4
|
+
data.tar.gz: b532e32f8c4a2a34e14b528649ff313041610adb7fc89349f7f97336a4c767d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8e949cadb19e163b961bebc40cc8e31bfba8e6ccefb07e28cdabb88a6cf0696a7a8a62b7f4c5f73ab1ae420c9b1956f38d2916f65ad0bfae3ee4e64ba885de5
|
7
|
+
data.tar.gz: 0f0ef1edc6432743dc6f3535449c880615057038a4e097ca03227660d7dd39270da8186675c26315f86636344635017d16f4c60fef580dfb6188bd0c785e92ab
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,9 @@
|
|
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.3.3]
|
7
|
+
* #41 fix `terraspace build` and `terraspace seed` when bucket doesnt exist yet and there are dependenices defined.
|
8
|
+
|
6
9
|
## [0.3.2]
|
7
10
|
* #40 fix backend auto creation
|
8
11
|
|
data/README.md
CHANGED
@@ -88,7 +88,7 @@ When you use the all command, the dependency graph is calculated and the stacks
|
|
88
88
|
* [Config Structure](https://terraspace.cloud/docs/config/): A common config structure that gets materializes with the deployed module. Configs can be dynamically controlled to keep your code DRY. You can override the settings if needed, like for using existing backends. See: [Existing Backends](https://terraspace.cloud/docs/state/existing/).
|
89
89
|
* [Generators](https://terraspace.cloud/docs/generators/): Built-in generators to quickly create the starter module. Focus on code instead of boilerplate structure.
|
90
90
|
* [Tfvars](https://terraspace.cloud/docs/tfvars/) & [Layering](https://terraspace.cloud/docs/tfvars/layering/): Use the same code with different tfvars to create multiple environments. Terraspace conventionally loads tfvars from the `tfvars` folder. Rich layering support allows you to build different environments like dev and prod with the same code. Examples are in [Full Layering](https://terraspace.cloud/docs/tfvars/full-layering/).
|
91
|
-
* [Deploy Multiple Stacks](https://terraspace.cloud/docs/
|
91
|
+
* [Deploy Multiple Stacks](https://terraspace.cloud/docs/intro/deploy-all/): The ability to deploy multiple stacks with a single command. Terraspace calculates the [dependency graph](https://terraspace.cloud/docs/dependencies/) and deploys stacks in the right order. You can also target specific stacks and deploy [subgraphs](https://terraspace.cloud/docs/dependencies/subgraphs/).
|
92
92
|
* [Configurable CLI](https://terraspace.cloud/docs/cli/): Configurable [CLI Hooks](https://terraspace.cloud/docs/cli/hooks/) and [CLI Args](https://terraspace.cloud/docs/cli/args/) allow you to adjust the underlying terraform command.
|
93
93
|
* [Testing](https://terraspace.cloud/docs/testing/): A testing framework that allows you to create test harnesses, deploy real-resources, and have higher confidence that your code works.
|
94
94
|
* [Terraform Cloud and Terraform Enterprise Support](https://terraspace.cloud/docs/cloud/): TFC and TFE are both supported. Terraspace adds additional conveniences to make working with Terraform Cloud Workspaces easier.
|
data/lib/terraspace.rb
CHANGED
data/lib/terraspace/builder.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Terraspace
|
2
2
|
class Builder < Terraspace::CLI::Base
|
3
3
|
include Compiler::DirsConcern
|
4
|
+
include Compiler::CommandsConcern
|
4
5
|
|
5
6
|
attr_reader :graph
|
6
7
|
|
@@ -58,16 +59,10 @@ module Terraspace
|
|
58
59
|
# Auto create after build_unresolved since will need to run state pull for dependencies
|
59
60
|
def auto_create_backend
|
60
61
|
return if Terraspace.config.auto_create_backend == false
|
61
|
-
return unless
|
62
|
+
return unless requires_backend?
|
62
63
|
Terraspace::Compiler::Backend.new(@mod).create
|
63
64
|
end
|
64
65
|
|
65
|
-
def create_backend?
|
66
|
-
commands = %w[down init output plan providers refresh show up validate]
|
67
|
-
commands.include?(ARGV[0]) || # IE: terraspace up
|
68
|
-
ARGV[0] == "all" && commands.include?(ARGV[1]) # IE: terraspace all up
|
69
|
-
end
|
70
|
-
|
71
66
|
def clean
|
72
67
|
Compiler::Cleaner.new(@mod, @options).clean if clean?
|
73
68
|
end
|
data/lib/terraspace/cli.rb
CHANGED
@@ -110,7 +110,7 @@ module Terraspace
|
|
110
110
|
List.new(options).run
|
111
111
|
end
|
112
112
|
|
113
|
-
desc "log [ACTION] [STACK]", "The
|
113
|
+
desc "log [ACTION] [STACK]", "The log command allows you to view multiple logs."
|
114
114
|
long_desc Help.text("log")
|
115
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
116
|
option :follow, aliases: %w[f], type: :boolean, desc: "Follow the log in live tail fashion. Must specify a stack if using this option."
|
@@ -1,4 +1,4 @@
|
|
1
|
-
This leaves the
|
1
|
+
This leaves the top run alone. The top run usually starts immediately planning once the other runs are pruned. Runs that are also in "Needs Confirmation" will be cancelled.
|
2
2
|
|
3
3
|
## Examples
|
4
4
|
|
@@ -23,7 +23,7 @@ To show all logs, use the `-a` option.
|
|
23
23
|
|
24
24
|
terraspace log up -a
|
25
25
|
|
26
|
-
Note, if both an action and stack is specified, then it defaults to showing all logs. If you want to
|
26
|
+
Note, if both an action and stack is specified, then it defaults to showing all logs. If you want not to show all logs, use `--no-all`.
|
27
27
|
|
28
28
|
## Tail Logs
|
29
29
|
|
@@ -36,7 +36,11 @@ To tail logs, use the `-f` option.
|
|
36
36
|
|
37
37
|
## Timestamps
|
38
38
|
|
39
|
-
The timestamps are shown by default when you are looking for multiple files. When you specify
|
39
|
+
The timestamps are shown by default when you are looking for multiple files. When you specify both the action and stack for a single log file, then timestamps are not shown.
|
40
40
|
|
41
41
|
terraspace log up # timestamps will be shown in this case
|
42
42
|
terraspace log up network # timestamps not be shown in this case
|
43
|
+
|
44
|
+
To show timestamps:
|
45
|
+
|
46
|
+
terraspace up up network --timestamps
|
@@ -6,7 +6,13 @@ module Terraspace::Compiler
|
|
6
6
|
@mod = mod
|
7
7
|
end
|
8
8
|
|
9
|
+
@@created = {}
|
9
10
|
def create
|
11
|
+
return if @@created[cache_key]
|
12
|
+
# set immediately, since local storage wont reach bottom.
|
13
|
+
# if fail for other backends, there will be an exception anyway
|
14
|
+
@@created[cache_key] = true
|
15
|
+
|
10
16
|
klass = backend_interface(backend_name)
|
11
17
|
return unless klass # in case auto-creation is not supported for specific backend
|
12
18
|
|
@@ -14,6 +20,10 @@ module Terraspace::Compiler
|
|
14
20
|
interface.call
|
15
21
|
end
|
16
22
|
|
23
|
+
def cache_key
|
24
|
+
@mod.build_dir
|
25
|
+
end
|
26
|
+
|
17
27
|
def backend_name
|
18
28
|
backend.keys.first # IE: s3, gcs, etc
|
19
29
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Terraspace::Compiler
|
2
2
|
class Builder
|
3
|
+
include CommandsConcern
|
3
4
|
include Basename
|
4
5
|
|
5
6
|
def initialize(mod)
|
@@ -9,7 +10,7 @@ module Terraspace::Compiler
|
|
9
10
|
def build
|
10
11
|
build_config
|
11
12
|
build_module if @mod.resolved
|
12
|
-
build_tfvars
|
13
|
+
build_tfvars unless command_is?(:seed) # avoid dependencies being built and erroring when backend bucket doesnt exist
|
13
14
|
end
|
14
15
|
|
15
16
|
# build common config files: provider and backend for the root module
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Terraspace::Compiler
|
2
|
+
module CommandsConcern
|
3
|
+
def requires_backend?
|
4
|
+
command_is?(requires_backend_commands)
|
5
|
+
end
|
6
|
+
|
7
|
+
def requires_backend_commands
|
8
|
+
%w[down init output plan providers refresh show up validate]
|
9
|
+
end
|
10
|
+
|
11
|
+
def command_is?(*commands)
|
12
|
+
commands.flatten!
|
13
|
+
commands.map!(&:to_s)
|
14
|
+
commands.include?(ARGV[0]) || # IE: terraspace up
|
15
|
+
ARGV[0] == "all" && commands.include?(ARGV[1]) # IE: terraspace all up
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/terraspace/shell.rb
CHANGED
@@ -6,7 +6,7 @@ module Terraspace
|
|
6
6
|
|
7
7
|
def initialize(mod, command, options={})
|
8
8
|
@mod, @command, @options = mod, command, options
|
9
|
-
@
|
9
|
+
@error_type, @error_messages = nil, ''
|
10
10
|
end
|
11
11
|
|
12
12
|
# requires @mod to be set
|
@@ -22,10 +22,13 @@ module Terraspace
|
|
22
22
|
Open3.popen3(env, @command, chdir: @mod.cache_dir) do |stdin, stdout, stderr, wait_thread|
|
23
23
|
mimic_terraform_input(stdin, stdout)
|
24
24
|
while err = stderr.gets
|
25
|
-
@
|
26
|
-
if @
|
27
|
-
@
|
25
|
+
@error_type ||= known_error_type(err)
|
26
|
+
if @error_type
|
27
|
+
@error_messages << err
|
28
28
|
else
|
29
|
+
# Sometimes may print a "\e[31m\n" which like during dependencies fetcher init
|
30
|
+
# suppress it so dont get a bunch of annoying "newlines"
|
31
|
+
next if err == "\e[31m\n" && @options[:suppress_error_color]
|
29
32
|
logger.error(err)
|
30
33
|
end
|
31
34
|
end
|
@@ -35,24 +38,39 @@ module Terraspace
|
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
41
|
+
def known_error_type(err)
|
42
|
+
if reinitialization_required?(err)
|
43
|
+
:reinitialization_required
|
44
|
+
elsif bucket_not_found?(err)
|
45
|
+
:bucket_not_found
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def bucket_not_found?(err)
|
50
|
+
# Message is included in aws, azurerm, and google. See: https://bit.ly/3iOKDri
|
51
|
+
err.include?("Failed to get existing workspaces")
|
52
|
+
end
|
53
|
+
|
54
|
+
def reinitialization_required?(err)
|
55
|
+
err.include?("reinitialization required") ||
|
56
|
+
err.include?("terraform init") ||
|
57
|
+
err.include?("require reinitialization")
|
58
|
+
end
|
59
|
+
|
38
60
|
def exit_status(status)
|
39
61
|
return if status == 0
|
40
62
|
|
41
63
|
exit_on_fail = @options[:exit_on_fail].nil? ? true : @options[:exit_on_fail]
|
42
|
-
if @
|
43
|
-
raise InitRequiredError.new(@
|
64
|
+
if @error_type == :reinitialization_required
|
65
|
+
raise InitRequiredError.new(@error_messages)
|
66
|
+
elsif @error_type == :bucket_not_found
|
67
|
+
raise BucketNotFoundError.new(@error_messages)
|
44
68
|
elsif exit_on_fail
|
45
69
|
logger.error "Error running command: #{@command}".color(:red)
|
46
70
|
exit status
|
47
71
|
end
|
48
72
|
end
|
49
73
|
|
50
|
-
def reinitialization_required?(err)
|
51
|
-
err.include?("reinitialization required") ||
|
52
|
-
err.include?("terraform init") ||
|
53
|
-
err.include?("require reinitialization")
|
54
|
-
end
|
55
|
-
|
56
74
|
# Terraform doesnt seem to stream the line that prompts with "Enter a value:" when using Open3.popen3
|
57
75
|
# Hack around it by mimicking the "Enter a value:" prompt
|
58
76
|
#
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Terraspace::Terraform::RemoteState
|
2
2
|
class Fetcher
|
3
3
|
extend Memoist
|
4
|
+
include Terraspace::Compiler::CommandsConcern
|
4
5
|
include Terraspace::Util::Logging
|
5
6
|
|
6
7
|
def initialize(parent, identifier, options={})
|
@@ -10,7 +11,7 @@ module Terraspace::Terraform::RemoteState
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def run
|
13
|
-
validate!
|
14
|
+
validate! # check child stack exists
|
14
15
|
pull
|
15
16
|
load
|
16
17
|
end
|
@@ -22,7 +23,8 @@ module Terraspace::Terraform::RemoteState
|
|
22
23
|
error = output_error(:key_not_found) unless @outputs.key?(@output_key)
|
23
24
|
OutputProxy.new(value, @options.merge(error: error))
|
24
25
|
else
|
25
|
-
|
26
|
+
@error_type ||= :state_not_found # could be set to :bucket_not_found by bucket_not_found_error
|
27
|
+
error = output_error(@error_type)
|
26
28
|
OutputProxy.new(nil, @options.merge(error: error))
|
27
29
|
end
|
28
30
|
end
|
@@ -39,6 +41,8 @@ module Terraspace::Terraform::RemoteState
|
|
39
41
|
"Output #{@output_key} was not found for the #{@parent.name} tfvars file. Either #{@child.name} stack has not been deployed yet or it does not have this output: #{@output_key}"
|
40
42
|
when :state_not_found
|
41
43
|
"Output #{@output_key} could not be looked up for the #{@parent.name} tfvars file. #{@child.name} stack needs to be deployed"
|
44
|
+
when :bucket_not_found
|
45
|
+
"The bucket for the backend could not be found"
|
42
46
|
end
|
43
47
|
msg = "(#{msg})"
|
44
48
|
log_message(msg)
|
@@ -52,7 +56,10 @@ module Terraspace::Terraform::RemoteState
|
|
52
56
|
logger.info "Downloading tfstate files for dependencies defined in tfvars..." unless @@download_shown || @options[:quiet]
|
53
57
|
@@download_shown = true
|
54
58
|
logger.debug "Downloading tfstate for stack: #{@child.name}"
|
55
|
-
|
59
|
+
|
60
|
+
success = init # init not yet run. only run .init directly, not .run. init can completely error and early exit.
|
61
|
+
return unless success
|
62
|
+
|
56
63
|
FileUtils.mkdir_p(File.dirname(state_path))
|
57
64
|
command = "cd #{@child.cache_dir} && terraform state pull > #{state_path}"
|
58
65
|
logger.debug "=> #{command}"
|
@@ -67,6 +74,20 @@ module Terraspace::Terraform::RemoteState
|
|
67
74
|
@@pull_successes[cache_key] = success
|
68
75
|
end
|
69
76
|
|
77
|
+
def init
|
78
|
+
Terraspace::CLI::Init.new(mod: @child.name, calling_command: "apply", quiet: true, suppress_error_color: true).init
|
79
|
+
true
|
80
|
+
rescue Terraspace::BucketNotFoundError # from Terraspace::Shell
|
81
|
+
bucket_not_found_error
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
# mimic pull error
|
86
|
+
def bucket_not_found_error
|
87
|
+
@@pull_successes[cache_key] = false
|
88
|
+
@error_type = :bucket_not_found
|
89
|
+
end
|
90
|
+
|
70
91
|
def load
|
71
92
|
return self unless pull_success?
|
72
93
|
|
data/lib/terraspace/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terraspace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
@@ -520,6 +520,7 @@ files:
|
|
520
520
|
- lib/terraspace/compiler/builder.rb
|
521
521
|
- lib/terraspace/compiler/cleaner.rb
|
522
522
|
- lib/terraspace/compiler/cleaner/backend_change.rb
|
523
|
+
- lib/terraspace/compiler/commands_concern.rb
|
523
524
|
- lib/terraspace/compiler/dirs_concern.rb
|
524
525
|
- lib/terraspace/compiler/dsl/base.rb
|
525
526
|
- lib/terraspace/compiler/dsl/meta/local.rb
|