terragov 0.2.1 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +15 -3
- data/lib/terragov/cli.rb +75 -38
- data/lib/terragov/git.rb +25 -0
- data/lib/terragov/terraform.rb +7 -7
- data/lib/terragov/version.rb +1 -1
- data/terragov.gemspec +5 -2
- metadata +52 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 852f92a97a49b1ed2bab8f9636c6633df8622915
|
4
|
+
data.tar.gz: 15f60c7f8b84f9c3983c01acf67ee27cfa1e85f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e13c77232c52712968e1d39a972f0c7f85459cf9aa0ccf2460604b51968c08fc889643d2de6ff79ede4b5571ca997f8527d6d30f0ac615d04aa68e5ee443278
|
7
|
+
data.tar.gz: 586525da558af934a8f455dce68cce8032e84293abacd21382757674aa61e24261c46bf1c38a57573e588add6ac5ab2c0d4407e0f2f496f78686e38e176c1b61
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Terragov
|
2
2
|
|
3
|
-
](https://travis-ci.org/surminus/terragov) [](https://badge.fury.io/rb/terragov) [](https://coveralls.io/github/surminus/terragov?branch=master)
|
4
|
+
|
5
|
+

|
4
6
|
|
5
7
|
GOV.UK use [Terraform](https://terraform.io) to deploy infrastructure. Originally a lightweight bash script was built to support our opinionated Terraform project structure, but it quickly added further functionality and I decided it would be nicer to use a tool written in a more complete language.
|
6
8
|
|
@@ -18,7 +20,7 @@ This tool is only meant to be used specifically against the project structure [d
|
|
18
20
|
|
19
21
|
Run `--help` for details.
|
20
22
|
|
21
|
-
There are several arguments to pass when running `apply`, `plan` or `destroy`:
|
23
|
+
There are several **required** arguments to pass when running `apply`, `plan` or `destroy`:
|
22
24
|
|
23
25
|
Argument | Description
|
24
26
|
--- | ---
|
@@ -38,7 +40,7 @@ Use command line flags to pass the relevant argument. This has **highest** prece
|
|
38
40
|
|
39
41
|
### Environment variables
|
40
42
|
|
41
|
-
Every command has an environment variable which can also be set. This has second
|
43
|
+
Every command has an environment variable which can also be set. This has **second highest** precedence. The value is the name, in upper case, and prefixed with `TERRAGOV`. For example, to set `environment`:
|
42
44
|
|
43
45
|
`export TERRAGOV_ENVIRONMENT=integration`
|
44
46
|
|
@@ -58,6 +60,16 @@ repo_dir: '~/govuk/govuk-aws'
|
|
58
60
|
data_dir: '~/govuk/govuk-aws-data/data'
|
59
61
|
```
|
60
62
|
|
63
|
+
## Optional global arguments
|
64
|
+
|
65
|
+
These may be set in the same way as described above, with the same precedence, but they are not required.
|
66
|
+
|
67
|
+
Argument | Description
|
68
|
+
--- | ---
|
69
|
+
`verbose` | Be more noisy
|
70
|
+
`dryrun` | CLI option is `--dry-run`, but config file and env var is `dryrun` and `TERRAGOV_DRYRUN` respectively
|
71
|
+
`skip_git_check` | Do not compare branches between the repo and data directories
|
72
|
+
|
61
73
|
## Development
|
62
74
|
|
63
75
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/terragov/cli.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'commander'
|
2
2
|
require 'yaml'
|
3
|
+
require 'highline'
|
3
4
|
require_relative 'buildpaths'
|
4
5
|
require_relative 'terraform'
|
5
6
|
require_relative 'cleaner'
|
6
7
|
require_relative 'version'
|
8
|
+
require_relative 'git'
|
7
9
|
|
8
10
|
module Terragov
|
9
11
|
class Cli
|
@@ -14,11 +16,11 @@ module Terragov
|
|
14
16
|
program :version, Terragov::VERSION
|
15
17
|
program :description, 'Wrapper for GOV.UK Terraform deployments.'
|
16
18
|
|
17
|
-
global_option('-c', "--config-file FILE", 'Specify a config file. Has less precedence than environment variables, which in turn have
|
19
|
+
global_option('-c', "--config-file FILE", 'Specify a config file. Has less precedence than environment variables, which in turn have less precedence than CLI options') do |config_file|
|
18
20
|
$config_file = config_file
|
19
21
|
end
|
20
22
|
|
21
|
-
global_option('-d', "--data-dir DIRECTORY", 'Location of the data directory') do |data_dir|
|
23
|
+
global_option('-d', "--data-dir DIRECTORY", String, 'Location of the data directory') do |data_dir|
|
22
24
|
$data_dir = data_dir
|
23
25
|
end
|
24
26
|
|
@@ -42,14 +44,17 @@ module Terragov
|
|
42
44
|
$extra = extra
|
43
45
|
end
|
44
46
|
|
45
|
-
global_option('--verbose',
|
47
|
+
global_option('--verbose', 'Verbose mode') do |verbose|
|
46
48
|
$verbose = verbose
|
47
49
|
end
|
48
50
|
|
49
|
-
global_option('--dry-run',
|
51
|
+
global_option('--dry-run', 'Dry run mode', 'Output the commands to run, but do not run them') do |dryrun|
|
50
52
|
$dryrun = dryrun
|
51
53
|
end
|
52
54
|
|
55
|
+
global_option('--skip-git-check', 'Skip git check', 'Do not check the status of git repositories') do |skip_git_check|
|
56
|
+
$skip_git_check = skip_git_check
|
57
|
+
end
|
53
58
|
end
|
54
59
|
|
55
60
|
def data_dir
|
@@ -76,6 +81,18 @@ module Terragov
|
|
76
81
|
return $extra if $extra
|
77
82
|
end
|
78
83
|
|
84
|
+
def verbose
|
85
|
+
return true ? $verbose : false
|
86
|
+
end
|
87
|
+
|
88
|
+
def dryrun
|
89
|
+
return true ? $dryrun : false
|
90
|
+
end
|
91
|
+
|
92
|
+
def skip_git_check
|
93
|
+
return true ? $skip_git_check : false
|
94
|
+
end
|
95
|
+
|
79
96
|
def load_config_file
|
80
97
|
if $config_file || ENV['TERRAGOV_CONFIG_FILE']
|
81
98
|
file = $config_file || ENV['TERRAGOV_CONFIG_FILE']
|
@@ -84,10 +101,9 @@ module Terragov
|
|
84
101
|
end
|
85
102
|
end
|
86
103
|
|
87
|
-
def config(option, file=false)
|
104
|
+
def config(option, file=false, required=true)
|
88
105
|
env_var = "TERRAGOV_#{option.upcase}"
|
89
106
|
error_message = "Must set #{option}. Use --help for details."
|
90
|
-
#require 'pry'; binding.pry
|
91
107
|
if public_send(option)
|
92
108
|
if file
|
93
109
|
return File.expand_path(public_send(option))
|
@@ -108,10 +124,18 @@ module Terragov
|
|
108
124
|
return load_config_file[option]
|
109
125
|
end
|
110
126
|
else
|
111
|
-
|
127
|
+
if required
|
128
|
+
abort(error_message)
|
129
|
+
else
|
130
|
+
return false
|
131
|
+
end
|
112
132
|
end
|
113
133
|
else
|
114
|
-
|
134
|
+
if required
|
135
|
+
abort(error_message)
|
136
|
+
else
|
137
|
+
return false
|
138
|
+
end
|
115
139
|
end
|
116
140
|
end
|
117
141
|
|
@@ -127,15 +151,56 @@ module Terragov
|
|
127
151
|
return cmd_options_hash
|
128
152
|
end
|
129
153
|
|
154
|
+
def git_compare_repo_and_data(skip=false)
|
155
|
+
git_helper = Terragov::Git.new
|
156
|
+
# FIXME this is confusing as we want to check the repository git status from
|
157
|
+
# the root, but the "data" directory is one level down in the repository
|
158
|
+
repo_dir_root = cmd_options['repo_dir']
|
159
|
+
data_dir_root = File.expand_path(File.join(cmd_options['data_dir'], '../'))
|
160
|
+
|
161
|
+
repo_dir_branch = git_helper.branch_name(repo_dir_root)
|
162
|
+
data_dir_branch = git_helper.branch_name(data_dir_root)
|
163
|
+
|
164
|
+
branches = {
|
165
|
+
"repo_dir" => repo_dir_branch,
|
166
|
+
"data_dir" => data_dir_branch,
|
167
|
+
}
|
168
|
+
|
169
|
+
unless skip
|
170
|
+
branches.each do |name, branch|
|
171
|
+
unless branch =~ /^master$/
|
172
|
+
exit unless HighLine.agree("#{name} not on 'master' branch, continue on branch '#{branch}'?")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
unless git_helper.compare_branch(repo_dir_root, data_dir_root)
|
177
|
+
puts "Warning: repo_dir(#{repo_dir_branch}) and data_dir(#{data_dir_branch}) on different branches"
|
178
|
+
exit unless HighLine.agree("Do you wish to continue?")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
130
183
|
def run_terraform_cmd(cmd, opt = nil)
|
131
184
|
paths = Terragov::BuildPaths.new.base(cmd_options)
|
132
185
|
varfiles = Terragov::BuildPaths.new.build_command(cmd_options)
|
133
186
|
backend = paths[:backend_file]
|
134
187
|
project_dir = paths[:project_dir]
|
188
|
+
|
189
|
+
be_verbose = config('verbose', false, false)
|
190
|
+
|
191
|
+
do_dryrun = config('dryrun', false, false)
|
192
|
+
|
193
|
+
skip_check = config('skip_git_check', false, false)
|
194
|
+
git_compare_repo_and_data(skip_check)
|
195
|
+
|
196
|
+
if be_verbose
|
197
|
+
puts cmd_options.to_yaml
|
198
|
+
end
|
199
|
+
|
135
200
|
if opt
|
136
201
|
cmd = "#{cmd} #{opt}"
|
137
202
|
end
|
138
|
-
Terragov::Terraform.new.execute(cmd, varfiles, backend, project_dir)
|
203
|
+
Terragov::Terraform.new.execute(cmd, varfiles, backend, project_dir, do_dryrun, be_verbose)
|
139
204
|
end
|
140
205
|
|
141
206
|
def run
|
@@ -143,15 +208,6 @@ module Terragov
|
|
143
208
|
c.syntax = 'terragov plan'
|
144
209
|
c.description = 'Runs a plan of your code'
|
145
210
|
c.action do |args, options|
|
146
|
-
if options.verbose
|
147
|
-
ENV['TERRAGOV_VERBOSE'] = "true"
|
148
|
-
puts "Planning..."
|
149
|
-
puts cmd_options.to_yaml
|
150
|
-
end
|
151
|
-
|
152
|
-
if options.dry_run
|
153
|
-
ENV['TERRAGOV_DRYRUN'] = "true"
|
154
|
-
end
|
155
211
|
|
156
212
|
run_terraform_cmd(c.name)
|
157
213
|
end
|
@@ -161,15 +217,6 @@ module Terragov
|
|
161
217
|
c.syntax = 'terragov apply'
|
162
218
|
c.description = 'Apply your code'
|
163
219
|
c.action do |args, options|
|
164
|
-
if options.verbose
|
165
|
-
ENV['TERRAGOV_VERBOSE'] = "true"
|
166
|
-
puts "Applying..."
|
167
|
-
puts cmd_options.to_yaml
|
168
|
-
end
|
169
|
-
|
170
|
-
if options.dry_run
|
171
|
-
ENV['TERRAGOV_DRYRUN'] = "true"
|
172
|
-
end
|
173
220
|
|
174
221
|
run_terraform_cmd(c.name)
|
175
222
|
end
|
@@ -180,16 +227,6 @@ module Terragov
|
|
180
227
|
c.description = 'Destroy your selected project'
|
181
228
|
c.option '--force', 'Force destroy'
|
182
229
|
c.action do |args, options|
|
183
|
-
if options.verbose
|
184
|
-
ENV['TERRAGOV_VERBOSE'] = "true"
|
185
|
-
puts "Destroying..."
|
186
|
-
puts cmd_options.to_yaml
|
187
|
-
end
|
188
|
-
|
189
|
-
if options.dry_run
|
190
|
-
ENV['TERRAGOV_DRYRUN'] = "true"
|
191
|
-
end
|
192
|
-
|
193
230
|
if options.force
|
194
231
|
run_terraform_cmd("#{c.name} -force")
|
195
232
|
else
|
@@ -203,7 +240,7 @@ module Terragov
|
|
203
240
|
c.description = 'Clean your directory of any files terraform may have left lying around'
|
204
241
|
c.option '--force', 'Force removal of files'
|
205
242
|
c.action do |args, options|
|
206
|
-
if
|
243
|
+
if config('verbose', false, false)
|
207
244
|
puts "Selecting directory #{repo_dir}"
|
208
245
|
end
|
209
246
|
|
data/lib/terragov/git.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
module Terragov
|
5
|
+
class Git
|
6
|
+
def branch_name(directory)
|
7
|
+
unless File.exist?(File.join(directory, '.git'))
|
8
|
+
exit unless HighLine.agree("#{directory} not a git repository, do you wish to continue?")
|
9
|
+
end
|
10
|
+
|
11
|
+
branch = ::Git.open(directory).current_branch
|
12
|
+
|
13
|
+
return branch
|
14
|
+
end
|
15
|
+
|
16
|
+
def compare_branch(dir_a, dir_b)
|
17
|
+
if branch_name(dir_a) == branch_name(dir_b)
|
18
|
+
return true
|
19
|
+
else
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/terragov/terraform.rb
CHANGED
@@ -11,7 +11,7 @@ module Terragov
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def execute(command, vars, backend, directory)
|
14
|
+
def execute(command, vars, backend, directory, dryrun=false, verbose=false)
|
15
15
|
package_check
|
16
16
|
|
17
17
|
if command == 'init'
|
@@ -20,24 +20,24 @@ module Terragov
|
|
20
20
|
end
|
21
21
|
|
22
22
|
Dir.chdir directory
|
23
|
-
init(backend)
|
23
|
+
init(backend, dryrun, verbose)
|
24
24
|
|
25
25
|
full_command = "bash -c 'terraform #{command} #{vars}'"
|
26
26
|
|
27
|
-
if
|
27
|
+
if dryrun
|
28
28
|
puts full_command
|
29
29
|
else
|
30
|
-
puts "#{command} command: #{full_command}" if
|
30
|
+
puts "#{command} command: #{full_command}" if verbose
|
31
31
|
abort("There was an issue running the command") unless system(full_command)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def init(backend_file)
|
35
|
+
def init(backend_file, dryrun=false, verbose=false)
|
36
36
|
init_cmd = "terraform init -backend-config #{backend_file}"
|
37
|
-
if
|
37
|
+
if dryrun
|
38
38
|
puts init_cmd
|
39
39
|
else
|
40
|
-
puts "init command: #{init_cmd}" if
|
40
|
+
puts "init command: #{init_cmd}" if verbose
|
41
41
|
abort("Issue running: terraform init -backend-config #{backend_file}") unless system(init_cmd)
|
42
42
|
end
|
43
43
|
end
|
data/lib/terragov/version.rb
CHANGED
data/terragov.gemspec
CHANGED
@@ -23,9 +23,12 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
25
|
spec.add_runtime_dependency "commander"
|
26
|
+
spec.add_runtime_dependency "git"
|
26
27
|
|
27
28
|
spec.add_development_dependency "bundler"
|
28
|
-
spec.add_development_dependency "rake"
|
29
|
-
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.5"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.6"
|
30
31
|
spec.add_development_dependency "pry"
|
32
|
+
spec.add_development_dependency "simplecov", ">= 0.8.2"
|
33
|
+
spec.add_development_dependency 'coveralls', '>= 0.7.0'
|
31
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terragov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laura Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: commander
|
@@ -25,13 +25,13 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: git
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
|
-
type: :
|
34
|
+
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -52,8 +52,36 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.5'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - ">="
|
@@ -67,19 +95,33 @@ dependencies:
|
|
67
95
|
- !ruby/object:Gem::Version
|
68
96
|
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
98
|
+
name: simplecov
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
101
|
- - ">="
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
103
|
+
version: 0.8.2
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - ">="
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
110
|
+
version: 0.8.2
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: coveralls
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.7.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.7.0
|
83
125
|
description: GOV.UK deploy infrastructure using Terraform. This is a wrapper to help
|
84
126
|
deployments.
|
85
127
|
email:
|
@@ -106,6 +148,7 @@ files:
|
|
106
148
|
- lib/terragov/buildpaths.rb
|
107
149
|
- lib/terragov/cleaner.rb
|
108
150
|
- lib/terragov/cli.rb
|
151
|
+
- lib/terragov/git.rb
|
109
152
|
- lib/terragov/terraform.rb
|
110
153
|
- lib/terragov/version.rb
|
111
154
|
- terragov.gemspec
|
@@ -129,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
172
|
version: '0'
|
130
173
|
requirements: []
|
131
174
|
rubyforge_project:
|
132
|
-
rubygems_version: 2.
|
175
|
+
rubygems_version: 2.5.1
|
133
176
|
signing_key:
|
134
177
|
specification_version: 4
|
135
178
|
summary: Wrapper for GOV.UK Terraform deployments.
|