TerraformDevKit 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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 +10 -10
  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 +194 -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
10
- end
1
+ module TerraformDevKit
2
+ class TerraformProjectConfig
3
+ attr_reader :name, :acronym
4
+
5
+ def initialize(project_name, project_acronym = nil)
6
+ @name = project_name.tr(' ', '-').downcase
7
+ @acronym = project_acronym || project_name.scan(/\b[a-z]/i).join.upcase
8
+ end
9
+ end
10
+ end
File without changes
@@ -1,3 +1,3 @@
1
- module TerraformDevKit
2
- VERSION = '0.3.2'.freeze
3
- end
1
+ module TerraformDevKit
2
+ VERSION = '0.3.3'.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,194 @@
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
+ TDK::Configuration.get('project-acronym')
72
+ )
73
+ TDK::TerraformConfigManager.setup(env, project_config)
74
+
75
+ unless env.local_backend?
76
+ puts '== Initializing remote state'
77
+ remote_state.init(env, project_config)
78
+ end
79
+
80
+ invoke('custom_prepare', task, args.env, safe_invoke: true)
81
+
82
+ if File.exist?(File.join(env.working_dir, '.terraform'))
83
+ get_cmd = 'terraform get'
84
+ get_cmd += ' -update=true' if TDK::TerraformConfigManager.update_modules?
85
+ TDK::Command.run(get_cmd, directory: env.working_dir)
86
+ else
87
+ init_cmd = 'terraform init'
88
+ init_cmd += ' -upgrade=false' unless TDK::TerraformConfigManager.update_modules?
89
+
90
+ TDK::Command.run(init_cmd, directory: env.working_dir)
91
+ end
92
+ end
93
+
94
+ desc 'Shows the plan to create the infrastructure'
95
+ task :plan, [:env] => :prepare do |_, args|
96
+ env = TDK::Environment.new(args.env)
97
+ Dir.chdir(env.working_dir) do
98
+ system("terraform plan -out=#{PLAN_FILE}")
99
+ end
100
+ end
101
+
102
+ desc 'Creates the infrastructure'
103
+ task :apply, [:env] => :prepare do |task, args|
104
+ invoke('pre_apply', task, args.env, safe_invoke: true)
105
+
106
+ env = TDK::Environment.new(args.env)
107
+
108
+ invoke('plan', task, env.name)
109
+
110
+ unless env.local_backend?
111
+ puts Rainbow("Are you sure you want to apply the above plan?\n" \
112
+ "Only 'yes' will be accepted.").green
113
+ response = STDIN.gets.strip
114
+ unless response == 'yes'
115
+ raise "Apply cancelled because response was not 'yes'.\n" \
116
+ "Response was: #{response}"
117
+ end
118
+ end
119
+
120
+ destroy_if_fails(env, task) do
121
+ Dir.chdir(env.working_dir) do
122
+ system("terraform apply \"#{PLAN_FILE}\"")
123
+ end
124
+ end
125
+
126
+ invoke('post_apply', task, args.env, safe_invoke: true)
127
+ end
128
+
129
+ desc 'Tests a local environment'
130
+ task :test, [:env] do |task, args|
131
+ env = TDK::Environment.new(args.env)
132
+ env.local_backend? || (raise 'Testing is only allowed for local environments')
133
+
134
+ invoke('apply', task, env.name)
135
+
136
+ destroy_if_fails(env, task) do
137
+ invoke('custom_test', task, args.env, safe_invoke: true)
138
+ end
139
+ end
140
+
141
+ desc 'Creates the infrastructure and runs the tests'
142
+ task :preflight, [:prefix, :teardown] do |task, args|
143
+ args.with_defaults(teardown: 'true')
144
+ args.with_defaults(prefix: TDK::Environment.temp_name)
145
+ env = TDK::Environment.new(args.prefix)
146
+
147
+ invoke('test', task, env.name)
148
+ invoke('clean', task, env.name) if args.teardown == 'true'
149
+ end
150
+
151
+ desc 'Destroys the infrastructure'
152
+ task :destroy, [:env] => :prepare do |task, args|
153
+ invoke('pre_destroy', task, args.env, safe_invoke: true)
154
+
155
+ env = TDK::Environment.new(args.env)
156
+ cmd = 'terraform destroy'
157
+
158
+ unless env.local_backend?
159
+ puts Rainbow("\n\n!!!! WARNING !!!!\n\n" \
160
+ "You are about to destroy #{env.name} and its remote state.\n" \
161
+ "Are you sure you want to proceed?\n" \
162
+ "Only 'yes' will be accepted.").red.bright
163
+ response = STDIN.gets.strip
164
+
165
+ unless response == 'yes'
166
+ raise "Destroy cancelled because response was not 'yes'.\n" \
167
+ "Response was: #{response}"
168
+ end
169
+ end
170
+
171
+ cmd += ' -force'
172
+
173
+ Dir.chdir(env.working_dir) do
174
+ system(cmd)
175
+ end
176
+ invoke('pre_destroy', task, args.env, safe_invoke: true)
177
+
178
+ unless env.local_backend?
179
+ project_config = TDK::TerraformProjectConfig.new(
180
+ TDK::Configuration.get('project-name'),
181
+ TDK::Configuration.get('project-acronym')
182
+ )
183
+ remote_state.destroy(env, project_config)
184
+ end
185
+
186
+ invoke('post_destroy', task, args.env, safe_invoke: true)
187
+ end
188
+
189
+ desc 'Cleans an environment (infrastructure is destroyed too)'
190
+ task :clean, [:env] => :destroy do |_, args|
191
+ env = TDK::Environment.new(args.env)
192
+ puts "Deleting environment #{env.name} in #{env.working_dir}"
193
+ TDK::ExtendedFileUtils.rm_rf(env.working_dir, secure: true)
194
+ end