TerraformDevKit 0.3.1 → 0.3.2

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.appveyor.yml +0 -0
  3. data/.gitignore +0 -0
  4. data/.rspec +2 -2
  5. data/.travis.yml +8 -8
  6. data/Gemfile +4 -4
  7. data/LICENSE +0 -0
  8. data/README.md +206 -206
  9. data/Rakefile +6 -6
  10. data/TerraformDevKit.gemspec +36 -36
  11. data/bin/console +14 -14
  12. data/bin/setup +8 -8
  13. data/exe/wait_for_url +0 -0
  14. data/lib/TerraformDevKit.rb +21 -21
  15. data/lib/TerraformDevKit/aws/aws.rb +65 -65
  16. data/lib/TerraformDevKit/aws/cloudfront.rb +20 -20
  17. data/lib/TerraformDevKit/aws/dynamodb.rb +46 -46
  18. data/lib/TerraformDevKit/aws/s3.rb +44 -44
  19. data/lib/TerraformDevKit/aws/terraform_remote_state.rb +67 -67
  20. data/lib/TerraformDevKit/backup_state.rb +18 -18
  21. data/lib/TerraformDevKit/command.rb +0 -0
  22. data/lib/TerraformDevKit/config.rb +0 -0
  23. data/lib/TerraformDevKit/download.rb +0 -0
  24. data/lib/TerraformDevKit/environment.rb +0 -0
  25. data/lib/TerraformDevKit/extended_file_utils.rb +14 -14
  26. data/lib/TerraformDevKit/os.rb +0 -0
  27. data/lib/TerraformDevKit/request.rb +0 -0
  28. data/lib/TerraformDevKit/retry.rb +0 -0
  29. data/lib/TerraformDevKit/terraform_config_manager.rb +0 -0
  30. data/lib/TerraformDevKit/terraform_env_manager.rb +0 -0
  31. data/lib/TerraformDevKit/terraform_installer.rb +0 -0
  32. data/lib/TerraformDevKit/terraform_log_filter.rb +0 -0
  33. data/lib/TerraformDevKit/terraform_project_config.rb +9 -9
  34. data/lib/TerraformDevKit/terraform_template_config_file.rb +0 -0
  35. data/lib/TerraformDevKit/url.rb +0 -0
  36. data/lib/TerraformDevKit/version.rb +3 -3
  37. data/lib/TerraformDevKit/zip_file_generator.rb +47 -47
  38. data/tasks/devkit.rake +192 -192
  39. metadata +3 -3
@@ -1,67 +1,67 @@
1
- require 'aws-sdk-dynamodb'
2
- require 'aws-sdk-s3'
3
-
4
- module TerraformDevKit
5
- module Aws
6
- class TerraformRemoteState
7
- ATTRIBUTES = [
8
- {
9
- attribute_name: 'LockID',
10
- attribute_type: 'S'
11
- }
12
- ]
13
- KEYS = [
14
- {
15
- attribute_name: 'LockID',
16
- key_type: 'HASH'
17
- }
18
- ]
19
-
20
- def initialize(dynamodb, s3)
21
- @dynamodb = dynamodb
22
- @s3 = s3
23
- end
24
-
25
- def init(environment, project)
26
- table_name = table_name(environment, project)
27
- return if lock_table_exists_and_is_active(table_name)
28
-
29
- @dynamodb.create_table(table_name, ATTRIBUTES, KEYS, 1, 1)
30
-
31
- begin
32
- @s3.create_bucket(state_bucket_name(environment, project))
33
- rescue Aws::S3::Errors::BucketAlreadyOwnedByYou
34
- return
35
- end
36
-
37
- sleep(0.2) until lock_table_exists_and_is_active(table_name)
38
- end
39
-
40
- def destroy(environment, project)
41
- table_name = table_name(environment, project)
42
-
43
- @dynamodb.delete_table(table_name)
44
- @s3.delete_bucket(state_bucket_name(environment, project))
45
- end
46
-
47
- private_class_method
48
- def lock_table_exists_and_is_active(table_name)
49
- begin
50
- return @dynamodb.get_table_status(table_name) == 'ACTIVE'
51
- rescue Aws::DynamoDB::Errors::ResourceNotFoundException
52
- return false
53
- end
54
- end
55
-
56
- private_class_method
57
- def table_name(environment, project)
58
- "#{project.acronym}-#{environment.name}-lock-table"
59
- end
60
-
61
- private_class_method
62
- def state_bucket_name(environment, project)
63
- "#{project.name}-#{environment.name}-state"
64
- end
65
- end
66
- end
67
- end
1
+ require 'aws-sdk-dynamodb'
2
+ require 'aws-sdk-s3'
3
+
4
+ module TerraformDevKit
5
+ module Aws
6
+ class TerraformRemoteState
7
+ ATTRIBUTES = [
8
+ {
9
+ attribute_name: 'LockID',
10
+ attribute_type: 'S'
11
+ }
12
+ ]
13
+ KEYS = [
14
+ {
15
+ attribute_name: 'LockID',
16
+ key_type: 'HASH'
17
+ }
18
+ ]
19
+
20
+ def initialize(dynamodb, s3)
21
+ @dynamodb = dynamodb
22
+ @s3 = s3
23
+ end
24
+
25
+ def init(environment, project)
26
+ table_name = table_name(environment, project)
27
+ return if lock_table_exists_and_is_active(table_name)
28
+
29
+ @dynamodb.create_table(table_name, ATTRIBUTES, KEYS, 1, 1)
30
+
31
+ begin
32
+ @s3.create_bucket(state_bucket_name(environment, project))
33
+ rescue ::Aws::S3::Errors::BucketAlreadyOwnedByYou
34
+ return
35
+ end
36
+
37
+ sleep(0.2) until lock_table_exists_and_is_active(table_name)
38
+ end
39
+
40
+ def destroy(environment, project)
41
+ table_name = table_name(environment, project)
42
+
43
+ @dynamodb.delete_table(table_name)
44
+ @s3.delete_bucket(state_bucket_name(environment, project))
45
+ end
46
+
47
+ private_class_method
48
+ def lock_table_exists_and_is_active(table_name)
49
+ begin
50
+ return @dynamodb.get_table_status(table_name) == 'ACTIVE'
51
+ rescue ::Aws::DynamoDB::Errors::ResourceNotFoundException
52
+ return false
53
+ end
54
+ end
55
+
56
+ private_class_method
57
+ def table_name(environment, project)
58
+ "#{project.acronym}-#{environment.name}-lock-table"
59
+ end
60
+
61
+ private_class_method
62
+ def state_bucket_name(environment, project)
63
+ "#{project.name}-#{environment.name}-state"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,18 +1,18 @@
1
- require 'fileutils'
2
-
3
- require_relative 'zip_file_generator'
4
-
5
- module TerraformDevKit
6
- class BackupState
7
- def self.backup(prefix)
8
- backup_path = ENV['TM_STATE_BACKUP_PATH']
9
- return if backup_path.nil?
10
-
11
- filename = "#{prefix}failure_state.zip"
12
- ZipFileGenerator.new('.', filename).write
13
-
14
- FileUtils.cp(filename, backup_path)
15
- puts "Copied state to #{File.join(backup_path, filename)}"
16
- end
17
- end
18
- end
1
+ require 'fileutils'
2
+
3
+ require_relative 'zip_file_generator'
4
+
5
+ module TerraformDevKit
6
+ class BackupState
7
+ def self.backup(prefix)
8
+ backup_path = ENV['TM_STATE_BACKUP_PATH']
9
+ return if backup_path.nil?
10
+
11
+ filename = "#{prefix}failure_state.zip"
12
+ ZipFileGenerator.new('.', filename).write
13
+
14
+ FileUtils.cp(filename, backup_path)
15
+ puts "Copied state to #{File.join(backup_path, filename)}"
16
+ end
17
+ end
18
+ end
File without changes
File without changes
File without changes
File without changes
@@ -1,14 +1,14 @@
1
- require 'fileutils'
2
- require 'TerraformDevKit/command'
3
- require 'TerraformDevKit/os'
4
-
5
- module TerraformDevKit::ExtendedFileUtils
6
- def self.rm_rf(list, options = {})
7
- if TerraformDevKit::OS.host_os == 'windows'
8
- windows_path = TerraformDevKit::OS.convert_to_local_path(list)
9
- TerraformDevKit::Command.run("rmdir /s/q \"#{windows_path}\"")
10
- else
11
- FileUtils.rm_rf(list, options)
12
- end
13
- end
14
- end
1
+ require 'fileutils'
2
+ require 'TerraformDevKit/command'
3
+ require 'TerraformDevKit/os'
4
+
5
+ module TerraformDevKit::ExtendedFileUtils
6
+ def self.rm_rf(list, options = {})
7
+ if TerraformDevKit::OS.host_os == 'windows'
8
+ windows_path = TerraformDevKit::OS.convert_to_local_path(list)
9
+ TerraformDevKit::Command.run("rmdir /s/q \"#{windows_path}\"")
10
+ else
11
+ FileUtils.rm_rf(list, options)
12
+ end
13
+ end
14
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,10 +1,10 @@
1
- module TerraformDevKit
2
- class TerraformProjectConfig
3
- attr_reader :name, :acronym
4
-
5
- def initialize(project_name)
6
- @name = project_name.gsub(' ', '-').downcase
7
- @acronym = project_name.scan(/\b[a-z]/i).join.upcase
8
- end
9
- end
1
+ module TerraformDevKit
2
+ class TerraformProjectConfig
3
+ attr_reader :name, :acronym
4
+
5
+ def initialize(project_name)
6
+ @name = project_name.gsub(' ', '-').downcase
7
+ @acronym = project_name.scan(/\b[a-z]/i).join.upcase
8
+ end
9
+ end
10
10
  end
File without changes
@@ -1,3 +1,3 @@
1
- module TerraformDevKit
2
- VERSION = '0.3.1'.freeze
3
- end
1
+ module TerraformDevKit
2
+ VERSION = '0.3.2'.freeze
3
+ end
@@ -1,47 +1,47 @@
1
- require 'zip'
2
-
3
- module TerraformDevKit
4
- class ZipFileGenerator
5
- def initialize(input_dir, output_file)
6
- @input_dir = input_dir
7
- @output_file = output_file
8
- end
9
-
10
- def write
11
- entries = Dir.entries(@input_dir)
12
- entries.delete('.')
13
- entries.delete('..')
14
- Zip::File.open(@output_file, Zip::File::CREATE) do |zipfile|
15
- write_entries(entries, '', zipfile)
16
- end
17
- end
18
-
19
- private
20
-
21
- def write_entries(entries, path, zipfile)
22
- entries.each do |e|
23
- zip_file_path = path == '' ? e : File.join(path, e)
24
- disk_file_path = File.join(@input_dir, zip_file_path)
25
- if File.directory?(disk_file_path)
26
- write_directory(disk_file_path, zip_file_path, zipfile)
27
- else
28
- write_file(disk_file_path, zip_file_path, zipfile)
29
- end
30
- end
31
- end
32
-
33
- def write_directory(disk_file_path, zip_file_path, zipfile)
34
- zipfile.mkdir(zip_file_path)
35
- subdir = Dir.entries(disk_file_path)
36
- subdir.delete('.')
37
- subdir.delete('..')
38
- write_entries(subdir, zip_file_path, zipfile)
39
- end
40
-
41
- def write_file(disk_file_path, zip_file_path, zipfile)
42
- zipfile.get_output_stream(zip_file_path) do |f|
43
- f.puts(File.open(disk_file_path, 'rb').read)
44
- end
45
- end
46
- end
47
- end
1
+ require 'zip'
2
+
3
+ module TerraformDevKit
4
+ class ZipFileGenerator
5
+ def initialize(input_dir, output_file)
6
+ @input_dir = input_dir
7
+ @output_file = output_file
8
+ end
9
+
10
+ def write
11
+ entries = Dir.entries(@input_dir)
12
+ entries.delete('.')
13
+ entries.delete('..')
14
+ Zip::File.open(@output_file, Zip::File::CREATE) do |zipfile|
15
+ write_entries(entries, '', zipfile)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def write_entries(entries, path, zipfile)
22
+ entries.each do |e|
23
+ zip_file_path = path == '' ? e : File.join(path, e)
24
+ disk_file_path = File.join(@input_dir, zip_file_path)
25
+ if File.directory?(disk_file_path)
26
+ write_directory(disk_file_path, zip_file_path, zipfile)
27
+ else
28
+ write_file(disk_file_path, zip_file_path, zipfile)
29
+ end
30
+ end
31
+ end
32
+
33
+ def write_directory(disk_file_path, zip_file_path, zipfile)
34
+ zipfile.mkdir(zip_file_path)
35
+ subdir = Dir.entries(disk_file_path)
36
+ subdir.delete('.')
37
+ subdir.delete('..')
38
+ write_entries(subdir, zip_file_path, zipfile)
39
+ end
40
+
41
+ def write_file(disk_file_path, zip_file_path, zipfile)
42
+ zipfile.get_output_stream(zip_file_path) do |f|
43
+ f.puts(File.open(disk_file_path, 'rb').read)
44
+ end
45
+ end
46
+ end
47
+ end
data/tasks/devkit.rake CHANGED
@@ -1,192 +1,192 @@
1
- require 'rainbow'
2
- require 'TerraformDevKit'
3
-
4
- TDK = TerraformDevKit
5
-
6
- raise 'ROOT_PATH is not defined' if defined?(ROOT_PATH).nil?
7
- BIN_PATH = File.join(ROOT_PATH, 'bin')
8
- CONFIG_FILE ||= File.join(ROOT_PATH, 'config', 'config-%s.yml')
9
-
10
- # Ensure terraform is in the PATH
11
- ENV['PATH'] = TDK::OS.join_env_path(
12
- TDK::OS.convert_to_local_path(BIN_PATH),
13
- ENV['PATH']
14
- )
15
-
16
- PLAN_FILE = 'plan.tfplan'.freeze
17
-
18
- def destroy_if_fails(env, task)
19
- yield
20
- rescue Exception => e
21
- puts "ERROR: #{e.message}"
22
- puts e.backtrace.join("\n")
23
- invoke('destroy', task, env.name) if env.local_backend?
24
- raise
25
- end
26
-
27
- def invoke(task_name, task_context, env, safe_invoke: false)
28
- task_in_context = task_in_current_namespace(task_name, task_context)
29
- should_invoke = !safe_invoke || Rake::Task.task_defined?(task_in_context)
30
- Rake::Task[task_in_context].invoke(env) if should_invoke
31
- end
32
-
33
- def task_in_current_namespace(task_name, current_task)
34
- namespace = current_task.scope.path.to_s
35
- if namespace.empty?
36
- return task_name
37
- end
38
-
39
- return "#{namespace}:#{task_name}"
40
- end
41
-
42
- def remote_state
43
- aws_config = TDK::Aws::AwsConfig.new(TDK::Configuration.get('aws'))
44
- dynamo_db = TDK::Aws::DynamoDB.new(
45
- aws_config.credentials,
46
- aws_config.region
47
- )
48
- s3 = TDK::Aws::S3.new(
49
- aws_config.credentials,
50
- aws_config.region
51
- )
52
- TDK::Aws::TerraformRemoteState.new(dynamo_db, s3)
53
- end
54
-
55
- desc 'Prepares the environment to create the infrastructure'
56
- task :prepare, [:env] do |_, args|
57
- puts "== Configuring environment #{args.env}"
58
- env = TDK::Environment.new(args.env)
59
-
60
- config_file = CONFIG_FILE % env.config
61
- puts "== Loading configuration from #{config_file}"
62
- TDK::Configuration.init(config_file)
63
-
64
- TDK::TerraformInstaller.install_local(
65
- TDK::Configuration.get('terraform-version'),
66
- directory: BIN_PATH
67
- )
68
-
69
- project_config = TDK::TerraformProjectConfig.new(
70
- TDK::Configuration.get('project-name')
71
- )
72
- TDK::TerraformConfigManager.setup(env, project_config)
73
-
74
- unless env.local_backend?
75
- puts '== Initializing remote state'
76
- remote_state.init(env, project_config)
77
- end
78
-
79
- invoke('custom_prepare', task, args.env, safe_invoke: true)
80
-
81
- if File.exist?(File.join(env.working_dir, '.terraform'))
82
- get_cmd = 'terraform get'
83
- get_cmd += ' -update=true' if TDK::TerraformConfigManager.update_modules?
84
- TDK::Command.run(get_cmd, directory: env.working_dir)
85
- else
86
- init_cmd = 'terraform init'
87
- init_cmd += ' -upgrade=false' unless TDK::TerraformConfigManager.update_modules?
88
-
89
- TDK::Command.run(init_cmd, directory: env.working_dir)
90
- end
91
- end
92
-
93
- desc 'Shows the plan to create the infrastructure'
94
- task :plan, [:env] => :prepare do |_, args|
95
- env = TDK::Environment.new(args.env)
96
- Dir.chdir(env.working_dir) do
97
- system("terraform plan -out=#{PLAN_FILE}")
98
- end
99
- end
100
-
101
- desc 'Creates the infrastructure'
102
- task :apply, [:env] => :prepare do |task, args|
103
- invoke('pre_apply', task, args.env, safe_invoke: true)
104
-
105
- env = TDK::Environment.new(args.env)
106
-
107
- invoke('plan', task, env.name)
108
-
109
- unless env.local_backend?
110
- puts Rainbow("Are you sure you want to apply the above plan?\n" \
111
- "Only 'yes' will be accepted.").green
112
- response = STDIN.gets.strip
113
- unless response == 'yes'
114
- raise "Apply cancelled because response was not 'yes'.\n" \
115
- "Response was: #{response}"
116
- end
117
- end
118
-
119
- destroy_if_fails(env, task) do
120
- Dir.chdir(env.working_dir) do
121
- system("terraform apply \"#{PLAN_FILE}\"")
122
- end
123
- end
124
-
125
- invoke('post_apply', task, args.env, safe_invoke: true)
126
- end
127
-
128
- desc 'Tests a local environment'
129
- task :test, [:env] do |task, args|
130
- env = TDK::Environment.new(args.env)
131
- env.local_backend? || (raise 'Testing is only allowed for local environments')
132
-
133
- invoke('apply', task, env.name)
134
-
135
- destroy_if_fails(env, task) do
136
- invoke('custom_test', task, args.env, safe_invoke: true)
137
- end
138
- end
139
-
140
- desc 'Creates the infrastructure and runs the tests'
141
- task :preflight, [:prefix, :teardown] do |task, args|
142
- args.with_defaults(teardown: 'true')
143
- args.with_defaults(prefix: TDK::Environment.temp_name)
144
- env = TDK::Environment.new(args.prefix)
145
-
146
- invoke('test', task, env.name)
147
- invoke('clean', task, env.name) if args.teardown == 'true'
148
- end
149
-
150
- desc 'Destroys the infrastructure'
151
- task :destroy, [:env] => :prepare do |task, args|
152
- invoke('pre_destroy', task, args.env, safe_invoke: true)
153
-
154
- env = TDK::Environment.new(args.env)
155
- cmd = 'terraform destroy'
156
-
157
- unless env.local_backend?
158
- puts Rainbow("\n\n!!!! WARNING !!!!\n\n" \
159
- "You are about to destroy #{env.name} and its remote state.\n" \
160
- "Are you sure you want to proceed?\n" \
161
- "Only 'yes' will be accepted.").red.bright
162
- response = STDIN.gets.strip
163
-
164
- unless response == 'yes'
165
- raise "Destroy cancelled because response was not 'yes'.\n" \
166
- "Response was: #{response}"
167
- end
168
- end
169
-
170
- cmd += ' -force'
171
-
172
- Dir.chdir(env.working_dir) do
173
- system(cmd)
174
- end
175
- invoke('pre_destroy', task, args.env, safe_invoke: true)
176
-
177
- unless env.local_backend?
178
- project_config = TDK::TerraformProjectConfig.new(
179
- TDK::Configuration.get('project-name')
180
- )
181
- remote_state.destroy(env, project_config)
182
- end
183
-
184
- invoke('post_destroy', task, args.env, safe_invoke: true)
185
- end
186
-
187
- desc 'Cleans an environment (infrastructure is destroyed too)'
188
- task :clean, [:env] => :destroy do |_, args|
189
- env = TDK::Environment.new(args.env)
190
- puts "Deleting environment #{env.name} in #{env.working_dir}"
191
- TDK::ExtendedFileUtils.rm_rf(env.working_dir, secure: true)
192
- end
1
+ require 'rainbow'
2
+ require 'TerraformDevKit'
3
+
4
+ TDK = TerraformDevKit
5
+
6
+ raise 'ROOT_PATH is not defined' if defined?(ROOT_PATH).nil?
7
+ BIN_PATH = File.join(ROOT_PATH, 'bin')
8
+ CONFIG_FILE ||= File.join(ROOT_PATH, 'config', 'config-%s.yml')
9
+
10
+ # Ensure terraform is in the PATH
11
+ ENV['PATH'] = TDK::OS.join_env_path(
12
+ TDK::OS.convert_to_local_path(BIN_PATH),
13
+ ENV['PATH']
14
+ )
15
+
16
+ PLAN_FILE = 'plan.tfplan'.freeze
17
+
18
+ def destroy_if_fails(env, task)
19
+ yield
20
+ rescue Exception => e
21
+ puts "ERROR: #{e.message}"
22
+ puts e.backtrace.join("\n")
23
+ invoke('destroy', task, env.name) if env.local_backend?
24
+ raise
25
+ end
26
+
27
+ def invoke(task_name, task_context, env, safe_invoke: false)
28
+ task_in_context = task_in_current_namespace(task_name, task_context)
29
+ should_invoke = !safe_invoke || Rake::Task.task_defined?(task_in_context)
30
+ Rake::Task[task_in_context].invoke(env) if should_invoke
31
+ end
32
+
33
+ def task_in_current_namespace(task_name, current_task)
34
+ namespace = current_task.scope.path.to_s
35
+ if namespace.empty?
36
+ return task_name
37
+ end
38
+
39
+ return "#{namespace}:#{task_name}"
40
+ end
41
+
42
+ def remote_state
43
+ aws_config = TDK::Aws::AwsConfig.new(TDK::Configuration.get('aws'))
44
+ dynamo_db = TDK::Aws::DynamoDB.new(
45
+ aws_config.credentials,
46
+ aws_config.region
47
+ )
48
+ s3 = TDK::Aws::S3.new(
49
+ aws_config.credentials,
50
+ aws_config.region
51
+ )
52
+ TDK::Aws::TerraformRemoteState.new(dynamo_db, s3)
53
+ end
54
+
55
+ desc 'Prepares the environment to create the infrastructure'
56
+ task :prepare, [:env] do |_, args|
57
+ puts "== Configuring environment #{args.env}"
58
+ env = TDK::Environment.new(args.env)
59
+
60
+ config_file = CONFIG_FILE % env.config
61
+ puts "== Loading configuration from #{config_file}"
62
+ TDK::Configuration.init(config_file)
63
+
64
+ TDK::TerraformInstaller.install_local(
65
+ TDK::Configuration.get('terraform-version'),
66
+ directory: BIN_PATH
67
+ )
68
+
69
+ project_config = TDK::TerraformProjectConfig.new(
70
+ TDK::Configuration.get('project-name')
71
+ )
72
+ TDK::TerraformConfigManager.setup(env, project_config)
73
+
74
+ unless env.local_backend?
75
+ puts '== Initializing remote state'
76
+ remote_state.init(env, project_config)
77
+ end
78
+
79
+ invoke('custom_prepare', task, args.env, safe_invoke: true)
80
+
81
+ if File.exist?(File.join(env.working_dir, '.terraform'))
82
+ get_cmd = 'terraform get'
83
+ get_cmd += ' -update=true' if TDK::TerraformConfigManager.update_modules?
84
+ TDK::Command.run(get_cmd, directory: env.working_dir)
85
+ else
86
+ init_cmd = 'terraform init'
87
+ init_cmd += ' -upgrade=false' unless TDK::TerraformConfigManager.update_modules?
88
+
89
+ TDK::Command.run(init_cmd, directory: env.working_dir)
90
+ end
91
+ end
92
+
93
+ desc 'Shows the plan to create the infrastructure'
94
+ task :plan, [:env] => :prepare do |_, args|
95
+ env = TDK::Environment.new(args.env)
96
+ Dir.chdir(env.working_dir) do
97
+ system("terraform plan -out=#{PLAN_FILE}")
98
+ end
99
+ end
100
+
101
+ desc 'Creates the infrastructure'
102
+ task :apply, [:env] => :prepare do |task, args|
103
+ invoke('pre_apply', task, args.env, safe_invoke: true)
104
+
105
+ env = TDK::Environment.new(args.env)
106
+
107
+ invoke('plan', task, env.name)
108
+
109
+ unless env.local_backend?
110
+ puts Rainbow("Are you sure you want to apply the above plan?\n" \
111
+ "Only 'yes' will be accepted.").green
112
+ response = STDIN.gets.strip
113
+ unless response == 'yes'
114
+ raise "Apply cancelled because response was not 'yes'.\n" \
115
+ "Response was: #{response}"
116
+ end
117
+ end
118
+
119
+ destroy_if_fails(env, task) do
120
+ Dir.chdir(env.working_dir) do
121
+ system("terraform apply \"#{PLAN_FILE}\"")
122
+ end
123
+ end
124
+
125
+ invoke('post_apply', task, args.env, safe_invoke: true)
126
+ end
127
+
128
+ desc 'Tests a local environment'
129
+ task :test, [:env] do |task, args|
130
+ env = TDK::Environment.new(args.env)
131
+ env.local_backend? || (raise 'Testing is only allowed for local environments')
132
+
133
+ invoke('apply', task, env.name)
134
+
135
+ destroy_if_fails(env, task) do
136
+ invoke('custom_test', task, args.env, safe_invoke: true)
137
+ end
138
+ end
139
+
140
+ desc 'Creates the infrastructure and runs the tests'
141
+ task :preflight, [:prefix, :teardown] do |task, args|
142
+ args.with_defaults(teardown: 'true')
143
+ args.with_defaults(prefix: TDK::Environment.temp_name)
144
+ env = TDK::Environment.new(args.prefix)
145
+
146
+ invoke('test', task, env.name)
147
+ invoke('clean', task, env.name) if args.teardown == 'true'
148
+ end
149
+
150
+ desc 'Destroys the infrastructure'
151
+ task :destroy, [:env] => :prepare do |task, args|
152
+ invoke('pre_destroy', task, args.env, safe_invoke: true)
153
+
154
+ env = TDK::Environment.new(args.env)
155
+ cmd = 'terraform destroy'
156
+
157
+ unless env.local_backend?
158
+ puts Rainbow("\n\n!!!! WARNING !!!!\n\n" \
159
+ "You are about to destroy #{env.name} and its remote state.\n" \
160
+ "Are you sure you want to proceed?\n" \
161
+ "Only 'yes' will be accepted.").red.bright
162
+ response = STDIN.gets.strip
163
+
164
+ unless response == 'yes'
165
+ raise "Destroy cancelled because response was not 'yes'.\n" \
166
+ "Response was: #{response}"
167
+ end
168
+ end
169
+
170
+ cmd += ' -force'
171
+
172
+ Dir.chdir(env.working_dir) do
173
+ system(cmd)
174
+ end
175
+ invoke('pre_destroy', task, args.env, safe_invoke: true)
176
+
177
+ unless env.local_backend?
178
+ project_config = TDK::TerraformProjectConfig.new(
179
+ TDK::Configuration.get('project-name')
180
+ )
181
+ remote_state.destroy(env, project_config)
182
+ end
183
+
184
+ invoke('post_destroy', task, args.env, safe_invoke: true)
185
+ end
186
+
187
+ desc 'Cleans an environment (infrastructure is destroyed too)'
188
+ task :clean, [:env] => :destroy do |_, args|
189
+ env = TDK::Environment.new(args.env)
190
+ puts "Deleting environment #{env.name} in #{env.working_dir}"
191
+ TDK::ExtendedFileUtils.rm_rf(env.working_dir, secure: true)
192
+ end