terragov 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![
|
3
|
+
[![Build Status](https://travis-ci.org/surminus/terragov.svg?branch=master)](https://travis-ci.org/surminus/terragov) [![Gem Version](https://badge.fury.io/rb/terragov.svg)](https://badge.fury.io/rb/terragov) [![Coverage Status](https://coveralls.io/repos/github/surminus/terragov/badge.svg?branch=master)](https://coveralls.io/github/surminus/terragov?branch=master)
|
4
|
+
|
5
|
+
![Terragov](https://github.com/surminus/terragov/blob/master/bricktop.jpg "Terrible pun, guv")
|
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.
|