TerraformDevKit 0.1.9 → 0.1.10
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.
- checksums.yaml +4 -4
- data/README.md +11 -10
- data/TerraformDevKit.gemspec +2 -1
- data/lib/TerraformDevKit.rb +3 -0
- data/lib/TerraformDevKit/environment.rb +47 -0
- data/lib/TerraformDevKit/terraform_config_manager.rb +67 -0
- data/lib/TerraformDevKit/terraform_template_config_file.rb +26 -0
- data/lib/TerraformDevKit/version.rb +1 -1
- data/tasks/devkit.rake +106 -0
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e92fbd82b70265947a9eb3db56bad0c5b85d78f
|
4
|
+
data.tar.gz: 9048f6a2ea5e8ff08181d87515050ccf10e0931e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ebef969303e8fc2f00e1911a04990d3f3abbf790277f3a863788cdd57ea00bb848c25d5bdb346bd9a931375e3dcd7bbfbdb06a708a83067d950235d77ec6490
|
7
|
+
data.tar.gz: 294017e43b6b007d2c0fc23e93ab7bbed995e65c011eaeda6062ca8a6381f28d1361575ce7cc2ff15e3175d292bd48b7a72570571786f925eccbf6ccf28cfb8b
|
data/README.md
CHANGED
@@ -1,22 +1,24 @@
|
|
1
1
|
# TerraformDevKit
|
2
2
|
|
3
|
-
[](https://travis-ci.org/vistaprint/TerraformDevKit) [](https://ci.appveyor.com/project/betabandido/terraformdevkit/branch/master)
|
4
4
|
|
5
5
|
Set of scripts to ease development and testing with [Terraform](https://www.terraform.io/).
|
6
6
|
|
7
|
-
The script collection
|
7
|
+
The script collection includes support for:
|
8
8
|
|
9
9
|
* Managing AWS credentials
|
10
|
-
* Simple reading and writing to AWS DynamoDB
|
11
|
-
* Polling an AWS ApiGateway endpoint until it becomes ready
|
12
|
-
* Executing commands
|
13
|
-
* Locally installing Terraform and [Terragrunt](https://github.com/gruntwork-io/terragrunt)
|
14
10
|
* Backing up the state from a failed Terraform execution
|
15
|
-
*
|
11
|
+
* Executing external commands
|
16
12
|
* Simple configuration management
|
13
|
+
* Simple reading and writing to AWS DynamoDB
|
14
|
+
* Multiplatform tools
|
15
|
+
* Making simple HTTP requests
|
16
|
+
* Retrying a block of code
|
17
17
|
* Terraform environment management
|
18
|
+
* Locally installing Terraform and [Terragrunt](https://github.com/gruntwork-io/terragrunt)
|
19
|
+
* Filtering Terraform logging messages
|
18
20
|
|
19
|
-
Most of these scripts exist to provide support to a module development and testing environment for Terraform: [TerraformModules](https://github.com/
|
21
|
+
Most of these scripts exist to provide support to a module development and testing environment for Terraform: [TerraformModules](https://github.com/vistaprint/TerraformModules). But, they might be useful for other purposes too.
|
20
22
|
|
21
23
|
## Installation
|
22
24
|
|
@@ -50,8 +52,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
50
52
|
|
51
53
|
## Contributing
|
52
54
|
|
53
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
54
|
-
|
55
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/vistaprint/TerraformDevKit.
|
55
56
|
|
56
57
|
## License
|
57
58
|
|
data/TerraformDevKit.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ['vjimenez@vistaprint.com']
|
12
12
|
|
13
13
|
spec.summary = 'Set of scripts to ease development and testing with Terraform.'
|
14
|
-
spec.homepage = 'https://github.com/
|
14
|
+
spec.homepage = 'https://github.com/vistaprint/TerraformDevKit'
|
15
15
|
spec.license = 'Apache-2.0'
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency 'webmock', '~> 3.0.1'
|
28
28
|
|
29
29
|
spec.add_runtime_dependency 'aws-sdk', '~> 2.9.37'
|
30
|
+
spec.add_runtime_dependency 'mustache', '~> 1.0.2'
|
30
31
|
spec.add_runtime_dependency 'rubyzip', '~> 1.2.1'
|
31
32
|
end
|
data/lib/TerraformDevKit.rb
CHANGED
@@ -3,12 +3,15 @@ require 'TerraformDevKit/backup_state'
|
|
3
3
|
require 'TerraformDevKit/command'
|
4
4
|
require 'TerraformDevKit/config'
|
5
5
|
require 'TerraformDevKit/dynamodb'
|
6
|
+
require 'TerraformDevKit/environment'
|
6
7
|
require 'TerraformDevKit/os'
|
7
8
|
require 'TerraformDevKit/request'
|
8
9
|
require 'TerraformDevKit/retry'
|
10
|
+
require 'TerraformDevKit/terraform_config_manager'
|
9
11
|
require 'TerraformDevKit/terraform_env_manager'
|
10
12
|
require 'TerraformDevKit/terraform_installer'
|
11
13
|
require 'TerraformDevKit/terraform_log_filter'
|
14
|
+
require 'TerraformDevKit/terraform_template_config_file'
|
12
15
|
require 'TerraformDevKit/terragrunt_installer'
|
13
16
|
require 'TerraformDevKit/url'
|
14
17
|
require 'TerraformDevKit/version'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module TerraformDevKit
|
4
|
+
class Environment
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
raise 'Environment must not be null' if name.nil?
|
9
|
+
raise "Invalid environment name: #{name}" unless /^[0-9a-zA-Z]+$/ =~ name
|
10
|
+
@name = name.downcase
|
11
|
+
end
|
12
|
+
|
13
|
+
def config
|
14
|
+
case @name
|
15
|
+
when 'prod'
|
16
|
+
'prod'
|
17
|
+
when 'test'
|
18
|
+
'test'
|
19
|
+
else
|
20
|
+
'dev'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def local_backend?
|
25
|
+
case @name
|
26
|
+
when 'prod', 'test'
|
27
|
+
false
|
28
|
+
else
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def working_dir
|
34
|
+
"envs/#{@name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.temp_name
|
38
|
+
hostname = Socket.gethostname
|
39
|
+
date = Time.now.strftime('%y%m%d%H%M')
|
40
|
+
"#{hostname}#{date}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.running_on_jenkins?
|
44
|
+
ENV.key?('JENKINS_URL') && ENV.key?('BUILD_ID')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'TerraformDevKit/terraform_template_config_file'
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module TerraformDevKit
|
6
|
+
class TerraformConfigManager
|
7
|
+
def self.setup(env, extra_vars: {})
|
8
|
+
fix_configuration(env)
|
9
|
+
create_environment_directory(env)
|
10
|
+
render_template_config_files(env, extra_vars)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.update_modules?
|
14
|
+
skip_update = ENV.fetch('TF_DEV_KIT_SKIP_MODULE_UPDATE', 'false')
|
15
|
+
.strip
|
16
|
+
.downcase
|
17
|
+
skip_update != 'true'
|
18
|
+
end
|
19
|
+
|
20
|
+
private_class_method
|
21
|
+
def self.fix_configuration(env)
|
22
|
+
raise 'No AWS section in the config file' if Configuration.get('aws').nil?
|
23
|
+
if Environment.running_on_jenkins?
|
24
|
+
Configuration.get('aws').delete('profile')
|
25
|
+
elsif Configuration.get('aws').key?('profile')
|
26
|
+
unless env.local_backend?
|
27
|
+
raise "AWS credentials for environment #{env.name} must not be stored!"
|
28
|
+
end
|
29
|
+
else
|
30
|
+
profile = request_profile(env)
|
31
|
+
Configuration.get('aws')['profile'] = profile
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private_class_method
|
36
|
+
def self.create_environment_directory(env)
|
37
|
+
FileUtils.makedirs(env.working_dir)
|
38
|
+
end
|
39
|
+
|
40
|
+
private_class_method
|
41
|
+
def self.render_template_config_files(env, extra_vars)
|
42
|
+
aws_config = Configuration.get('aws')
|
43
|
+
file_list = Dir['*.tf.mustache'] + Dir['*.tfvars.mustache']
|
44
|
+
file_list.each do |fname|
|
45
|
+
template_file = TerraformTemplateConfigFile.new(
|
46
|
+
File.read(fname),
|
47
|
+
env,
|
48
|
+
aws_config,
|
49
|
+
extra_vars: extra_vars
|
50
|
+
)
|
51
|
+
config_fname = File.basename(fname, File.extname(fname))
|
52
|
+
Dir.chdir(env.working_dir) do
|
53
|
+
File.open(config_fname, 'w') { |f| f.write(template_file.render) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private_class_method
|
59
|
+
def self.request_profile(env)
|
60
|
+
puts "Environment #{env.name} requires manual input of AWS credentials"
|
61
|
+
print 'Enter the profile to use: '
|
62
|
+
profile = $stdin.gets.tr("\r\n", '')
|
63
|
+
raise 'Invalid profile name' unless /^\w+$/ =~ profile
|
64
|
+
profile
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
|
3
|
+
module TerraformDevKit
|
4
|
+
class TerraformTemplateConfigFile
|
5
|
+
def initialize(content, env, aws_config, extra_vars: {})
|
6
|
+
@content = content
|
7
|
+
@env = env
|
8
|
+
@aws_config = aws_config
|
9
|
+
@extra_vars = extra_vars
|
10
|
+
end
|
11
|
+
|
12
|
+
def render
|
13
|
+
args = {
|
14
|
+
Profile: @aws_config.fetch('profile', ''),
|
15
|
+
Region: @aws_config.fetch('region'),
|
16
|
+
Environment: @env.name,
|
17
|
+
LocalBackend: @env.local_backend?
|
18
|
+
}
|
19
|
+
args.merge!(@extra_vars)
|
20
|
+
Mustache.render(
|
21
|
+
@content,
|
22
|
+
args
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/tasks/devkit.rake
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'fileutils'
|
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
|
+
|
9
|
+
# Ensure terraform and terragrunt are in the PATH
|
10
|
+
ENV['PATH'] = TDK::OS.join_env_path(
|
11
|
+
TDK::OS.convert_to_local_path(BIN_PATH),
|
12
|
+
ENV['PATH']
|
13
|
+
)
|
14
|
+
|
15
|
+
TF_CONFIG_EXTRA_VARS = {}.freeze unless defined?(TF_CONFIG_EXTRA_VARS)
|
16
|
+
|
17
|
+
def destroy_if_fails(env)
|
18
|
+
yield
|
19
|
+
rescue StandardError => e
|
20
|
+
puts "ERROR: #{e.message}"
|
21
|
+
puts e.backtrace.join("\n")
|
22
|
+
task('destroy').invoke(env.name) if env.local_backend?
|
23
|
+
raise
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Prepares the environment to create the infrastructure'
|
27
|
+
task :prepare, [:env] do |_, args|
|
28
|
+
puts "== Configuring environment #{args.env}"
|
29
|
+
env = TDK::Environment.new(args.env)
|
30
|
+
|
31
|
+
config_file = "config/config-#{env.config}.yml"
|
32
|
+
puts "== Loading configuration from #{config_file}"
|
33
|
+
TDK::Configuration.init(config_file)
|
34
|
+
|
35
|
+
TDK::TerraformInstaller.install_local(
|
36
|
+
TDK::Configuration.get('terraform-version'),
|
37
|
+
directory: BIN_PATH
|
38
|
+
)
|
39
|
+
TDK::TerragruntInstaller.install_local(
|
40
|
+
TDK::Configuration.get('terragrunt-version'),
|
41
|
+
directory: BIN_PATH
|
42
|
+
)
|
43
|
+
|
44
|
+
TDK::TerraformConfigManager.setup(env, extra_vars: TF_CONFIG_EXTRA_VARS)
|
45
|
+
|
46
|
+
task('custom_prepare').invoke(args.env) if Rake::Task.task_defined?('custom_prepare')
|
47
|
+
|
48
|
+
TDK::Command.run(
|
49
|
+
'terragrunt init',
|
50
|
+
directory: env.working_dir,
|
51
|
+
close_stdin: false
|
52
|
+
)
|
53
|
+
|
54
|
+
cmd = 'terragrunt get'
|
55
|
+
cmd += ' -update=true' if TDK::TerraformConfigManager.update_modules?
|
56
|
+
TDK::Command.run(cmd, directory: env.working_dir)
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'Shows the plan to create the infrastructure'
|
60
|
+
task :plan, [:env] => :prepare do |_, args|
|
61
|
+
env = TDK::Environment.new(args.env)
|
62
|
+
TDK::Command.run('terragrunt plan', directory: env.working_dir)
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'Creates the infrastructure'
|
66
|
+
task :apply, [:env] => :prepare do |_, args|
|
67
|
+
env = TDK::Environment.new(args.env)
|
68
|
+
destroy_if_fails(env) do
|
69
|
+
TDK::Command.run('terragrunt apply', directory: env.working_dir)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
desc 'Tests a local environment'
|
74
|
+
task :test, [:env] do |_, args|
|
75
|
+
env = TDK::Environment.new(args.env)
|
76
|
+
raise 'Testing is only allowed for local environments' unless env.local_backend?
|
77
|
+
|
78
|
+
task('apply').invoke(env.name)
|
79
|
+
|
80
|
+
destroy_if_fails(env) do
|
81
|
+
task('custom_test').invoke(args.env) if Rake::Task.task_defined?('custom_test')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
desc 'Creates the infrastructure and run the tests'
|
86
|
+
task :preflight, [:teardown] do |_, args|
|
87
|
+
args.with_defaults(teardown: 'true')
|
88
|
+
env = TDK::Environment.new(TDK::Environment.temp_name)
|
89
|
+
task('test').invoke(env.name)
|
90
|
+
task('clean').invoke(env.name) if args.teardown == 'true'
|
91
|
+
end
|
92
|
+
|
93
|
+
desc 'Destroys the infrastructure'
|
94
|
+
task :destroy, [:env] => :prepare do |_, args|
|
95
|
+
env = TDK::Environment.new(args.env)
|
96
|
+
cmd = 'terragrunt destroy'
|
97
|
+
cmd += ' -force' if env.local_backend?
|
98
|
+
TDK::Command.run(cmd, directory: env.working_dir, close_stdin: false)
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'Cleans an environment (infrastructure is destroyed too)'
|
102
|
+
task :clean, [:env] => :destroy do |_, args|
|
103
|
+
env = TDK::Environment.new(args.env)
|
104
|
+
puts "Deleting environment #{env.name}"
|
105
|
+
FileUtils.rm_rf(env.working_dir, secure: true)
|
106
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: TerraformDevKit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Jimenez
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 2.9.37
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mustache
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.0.2
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.0.2
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rubyzip
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,17 +135,21 @@ files:
|
|
121
135
|
- lib/TerraformDevKit/config.rb
|
122
136
|
- lib/TerraformDevKit/download.rb
|
123
137
|
- lib/TerraformDevKit/dynamodb.rb
|
138
|
+
- lib/TerraformDevKit/environment.rb
|
124
139
|
- lib/TerraformDevKit/os.rb
|
125
140
|
- lib/TerraformDevKit/request.rb
|
126
141
|
- lib/TerraformDevKit/retry.rb
|
142
|
+
- lib/TerraformDevKit/terraform_config_manager.rb
|
127
143
|
- lib/TerraformDevKit/terraform_env_manager.rb
|
128
144
|
- lib/TerraformDevKit/terraform_installer.rb
|
129
145
|
- lib/TerraformDevKit/terraform_log_filter.rb
|
146
|
+
- lib/TerraformDevKit/terraform_template_config_file.rb
|
130
147
|
- lib/TerraformDevKit/terragrunt_installer.rb
|
131
148
|
- lib/TerraformDevKit/url.rb
|
132
149
|
- lib/TerraformDevKit/version.rb
|
133
150
|
- lib/TerraformDevKit/zip_file_generator.rb
|
134
|
-
|
151
|
+
- tasks/devkit.rake
|
152
|
+
homepage: https://github.com/vistaprint/TerraformDevKit
|
135
153
|
licenses:
|
136
154
|
- Apache-2.0
|
137
155
|
metadata: {}
|