kitchen-terraform 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 125efdc0ccfadc12dbc06c1f2d19f94337b7e514
4
- data.tar.gz: f63a2992bfcdb73ecf9a60b0d68752b6d1dcc543
3
+ metadata.gz: fab118f04f2357e74aea7dc6cd9a3d41ce176e86
4
+ data.tar.gz: 1184130c5eb929bb545689877cb6b4d86896be7c
5
5
  SHA512:
6
- metadata.gz: 680b4c300b78faeb2992aa52b7d915dfa5ec573c77f2fa57e6dbc8d3c44f80ef831d17ee30a377ec4c870246936971e7c6192753c3a472b3bfdf5f6d3c3bf0b0
7
- data.tar.gz: ade3ff2a56a9ba6febb281de8257006462680d16540c156804128c8b842b669d9cbf772f057f5bd8cb37334f743aede63ed45f292ed937150cfd7b69dda45ce4
6
+ metadata.gz: 2920103244e6bed6c7679692d86a21770f16cad1f6bf8346ef1db3f8f5afc78eba46105c0a7b444cedc227cce550dff0bba56c32f86dbdae23da647dfa1cbe79
7
+ data.tar.gz: e4656ec4baaf076ba378ff90db2c6972c5e25ed3de91024f72bd826c0257aac91a47c8438db1e223f68a64af19759c49ae22bacbb202153fdbb3944bac9409d9
Binary file
data.tar.gz.sig CHANGED
@@ -1,3 +1 @@
1
- <z nZCZ������-0�~�>a*﹈�e8o� v櫘M���h1�=DԬ��'��X��ø�zIu��ZҪ�廂1K{Cˉ�y0�����M@9WP:�Z��8s��+6�w�4���{E�u�YrX�75ؓ
2
- I����I����N,��'�]�=��
3
- ��& �l�4��u���?3���:�#��z��J��^�Ӄ�w�& @���9�?Ȏ���z'�PLAdR �c�8?��<�}�-j�p�v�s8
1
+ ����B]@JFn(D��队g���2e�,��[�����A��������7�ԯ�/W�'��`��Ѭ���~06'��o�n���prL��ۨX��U\yC2� ("x֝?���ɭ�o����p�ת~��ă�(�Fu"%Š5�w�8� 0� UKT���c(��
data/README.md CHANGED
@@ -13,7 +13,7 @@ kitchen-terraform is a set of [Test Kitchen] plugins for testing
13
13
 
14
14
  - [Bundler] **(~> 1.12)**
15
15
 
16
- - [Terraform] **(~> 0.6)**
16
+ - [Terraform] **(>= 0.6, < 0.8)**
17
17
 
18
18
  [Ruby]: https://www.ruby-lang.org/en/index.html
19
19
 
@@ -36,18 +36,10 @@ source 'https://rubygems.org'
36
36
  gem 'kitchen-terraform', '~> 0.1'
37
37
  ```
38
38
 
39
- Before running `bundle`, the author's public key must be added as a
40
- trusted certificate:
39
+ Then, use Bundler to install the gems:
41
40
 
42
41
  ```sh
43
- gem cert --add <(curl --location --silent \
44
- https://raw.githubusercontent.com/newcontext/kitchen-terraform/master/certs/ncs-alane-public_cert.pem)
45
- ```
46
-
47
- Then, install the bundle and verify all of the gems:
48
-
49
- ```sh
50
- bundle install --trust-policy LowSecurity
42
+ bundle install
51
43
  ```
52
44
 
53
45
  [Ruby Gem]: http://guides.rubygems.org/what-is-a-gem/index.html
@@ -62,6 +54,8 @@ Terraform configuration.
62
54
 
63
55
  [Test Kitchen configuration]: https://docs.chef.io/config_yml_kitchen.html
64
56
 
57
+ Refer to [Getting Started Readme](examples/getting_started/README.md) for a detailed walkthrough of setting up and using kitchen-terraform.
58
+
65
59
  Refer to the [examples directory] for a detailed example project.
66
60
 
67
61
  [examples directory]: examples/
@@ -70,19 +64,22 @@ Refer to the [examples directory] for a detailed example project.
70
64
 
71
65
  ### Driver
72
66
 
73
- The [driver] is responsible for ensuring compatibility with Terraform and
74
- destroying existing [Terraform state].
67
+ The [driver] is a wrapper around the [Terraform command-line interface].
68
+ It is responsible for enforcing Terraform version support and works with
69
+ the provisioner to manage the [Terraform state].
75
70
 
76
71
  [driver]: lib/kitchen/driver/terraform.rb
77
72
 
73
+ [Terraform command-line interface]: https://www.terraform.io/docs/commands/index.html
74
+
78
75
  [Terraform state]: https://www.terraform.io/docs/state/index.html
79
76
 
80
77
  #### Actions
81
78
 
82
79
  ##### kitchen create
83
80
 
84
- The driver validates the installed version of
85
- Terraform against the version supported by kitchen-terraform.
81
+ The driver ensures that the parent directories of the plan and state
82
+ files exist.
86
83
 
87
84
  ##### kitchen destroy
88
85
 
@@ -106,7 +103,10 @@ driver:
106
103
 
107
104
  ### Provisioner
108
105
 
109
- The [provisioner] is responsible for creating Terraform state.
106
+ The [provisioner] is the bridge between Terraform and Test Kitchen. It
107
+ is responsible for managing the Test Kitchen configuration options related to
108
+ the Terraform configuration and works with the driver to manage the
109
+ Terraform state.
110
110
 
111
111
  [provisioner]: lib/kitchen/provisioner/terraform.rb
112
112
 
@@ -114,8 +114,8 @@ The [provisioner] is responsible for creating Terraform state.
114
114
 
115
115
  ##### kitchen converge
116
116
 
117
- The provisioner applies a constructive Terraform plan to the
118
- Terraform state based on the provided Terraform configuration.
117
+ The provisioner uses the driver to apply a constructive Terraform plan
118
+ to the Terraform state based on the provided Terraform configuration.
119
119
 
120
120
  #### Configuration
121
121
 
@@ -235,19 +235,22 @@ The default `variables` collection is empty.
235
235
 
236
236
  ### Verifier
237
237
 
238
- The [verifier] is responsible for verifying the behaviour of any server
239
- instances in the Terraform state.
238
+ The [verifier] is a wrapper around [InSpec]. It is responsible for
239
+ verifying the behaviour of any server instances in the Terraform state.
240
240
 
241
241
  [verifier]: lib/kitchen/verifier/terraform.rb
242
242
 
243
+ [InSpec]: http://inspec.io
244
+
243
245
  #### Actions
244
246
 
245
247
  ##### kitchen verify
246
248
 
247
- The verifier verifies the configured server instances in the Terraform
248
- state using [Inspec profiles].
249
+ The verifier verifies the test suite's configured groups of server
250
+ instances in the Terraform state using an [InSpec profiles] located in
251
+ `<Test Kitchen working directory>/test/integration/<suite name>`.
249
252
 
250
- [Inspec profiles]: https://github.com/chef/inspec/blob/master/docs/profiles.rst
253
+ [InSpec profiles]: http://inspec.io/docs/reference/profiles
251
254
 
252
255
  #### Configuration
253
256
 
@@ -259,20 +262,20 @@ configuration defined by that plugin with the exception of the `port` and
259
262
 
260
263
  ##### groups
261
264
 
262
- A collection of group mappings containing [Inspec control] and
265
+ A collection of group mappings containing [InSpec control] and
263
266
  connection options for the different server instance groups in the
264
267
  Terraform configuration.
265
268
 
266
- [Inspec control]: https://github.com/chef/inspec/blob/master/docs/dsl_inspec.rst
269
+ [InSpec control]: http://inspec.io/docs/reference/dsl_inspec/
267
270
 
268
271
  Each group consists of:
269
272
 
270
273
  - a name to use for logging purposes
271
274
 
272
- - a mapping of Inspec attribute names to Terraform output variable
273
- names to define for the suite's Inspec profile
275
+ - a mapping of InSpec attribute names to Terraform output variable
276
+ names to define for the suite's InSpec profile
274
277
 
275
- - a collection of controls to include from the suite's Inspec profile
278
+ - a collection of controls to include from the suite's InSpec profile
276
279
 
277
280
  - a hostnames output variable name to use for extracting hostnames from
278
281
  the Terraform state; the output value is assumed to be in CSV format
@@ -14,31 +14,47 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
+ require 'fileutils'
17
18
  require 'kitchen'
19
+ require 'terraform/client'
18
20
  require 'terraform/configurable'
19
- require 'terraform/version'
20
21
 
21
22
  module Kitchen
22
23
  module Driver
23
24
  # Terraform state lifecycle activities manager
24
25
  class Terraform < Base
26
+ include ::Terraform::Client
27
+
25
28
  include ::Terraform::Configurable
26
29
 
27
30
  kitchen_driver_api_version 2
28
31
 
29
- plugin_version ::Terraform::VERSION
30
-
31
32
  no_parallel_for
32
33
 
33
34
  def create(_state = nil)
34
- provisioner.validate_version
35
+ %i(plan state)
36
+ .each { |option| FileUtils.mkdir_p File.dirname provisioner[option] }
35
37
  end
36
38
 
37
39
  def destroy(_state = nil)
38
- provisioner.validate_configuration_files
39
- provisioner.download_modules
40
- provisioner.plan_destructive_execution
41
- provisioner.apply_execution_plan
40
+ return if !File.exist?(provisioner[:state]) || current_state.empty?
41
+
42
+ create
43
+ validate_configuration_files
44
+ download_modules
45
+ plan_execution destroy: true
46
+ apply_execution_plan
47
+ end
48
+
49
+ def verify_dependencies
50
+ case version
51
+ when /v0\.7/
52
+ when /v0\.6/
53
+ log_deprecation aspect: 'v0.6', remediation: 'Update to v0.7',
54
+ version: '1.0'
55
+ else
56
+ raise Kitchen::UserError, 'Only Terraform v0.7 and v0.6 are supported'
57
+ end
42
58
  end
43
59
  end
44
60
  end
@@ -15,166 +15,42 @@
15
15
  # limitations under the License.
16
16
 
17
17
  require 'kitchen'
18
- require 'terraform/apply_command'
18
+ require 'terraform/apply_timeout_config'
19
+ require 'terraform/color_config'
19
20
  require 'terraform/configurable'
20
- require 'terraform/get_command'
21
- require 'terraform/group'
22
- require 'terraform/output_command'
23
- require 'terraform/plan_command'
24
- require 'terraform/validate_command'
25
- require 'terraform/version'
26
- require 'terraform/version_command'
21
+ require 'terraform/directory_config'
22
+ require 'terraform/plan_config'
23
+ require 'terraform/state_config'
24
+ require 'terraform/variable_files_config'
25
+ require 'terraform/variables_config'
27
26
 
28
27
  module Kitchen
29
28
  module Provisioner
30
29
  # Terraform configuration applier
31
30
  class Terraform < Base
32
- SUPPORTED_VERSION = /v0.6/
31
+ include ::Terraform::ApplyTimeoutConfig
33
32
 
34
- include ::Terraform::Configurable
35
-
36
- kitchen_provisioner_api_version 2
37
-
38
- plugin_version ::Terraform::VERSION
39
-
40
- required_config :apply_timeout do |_, value, provisioner|
41
- provisioner.coerce_apply_timeout value: value
42
- end
43
-
44
- default_config :apply_timeout, 600
33
+ include ::Terraform::ColorConfig
45
34
 
46
- default_config :color, true
47
-
48
- required_config :color do |_, value, provisioner|
49
- provisioner.coerce_color value: value
50
- end
51
-
52
- default_config(:directory) { |provisioner| provisioner[:kitchen_root] }
53
-
54
- expand_path_for :directory
55
-
56
- default_config :plan do |provisioner|
57
- provisioner.instance_pathname filename: 'terraform.tfplan'
58
- end
59
-
60
- expand_path_for :plan
61
-
62
- default_config :state do |provisioner|
63
- provisioner.instance_pathname filename: 'terraform.tfstate'
64
- end
65
-
66
- expand_path_for :state
35
+ include ::Terraform::Configurable
67
36
 
68
- required_config :variable_files do |_, value, provisioner|
69
- provisioner.coerce_variable_files value: value
70
- end
37
+ include ::Terraform::DirectoryConfig
71
38
 
72
- default_config :variable_files, []
39
+ include ::Terraform::PlanConfig
73
40
 
74
- expand_path_for :variable_files
41
+ include ::Terraform::StateConfig
75
42
 
76
- required_config :variables do |_, value, provisioner|
77
- provisioner.coerce_variables value: value
78
- end
43
+ include ::Terraform::VariableFilesConfig
79
44
 
80
- default_config :variables, {}
45
+ include ::Terraform::VariablesConfig
81
46
 
82
- def apply_execution_plan
83
- ::Terraform::ApplyCommand.execute \
84
- logger: logger, state: config[:state], target: config[:plan],
85
- color: config[:color], timeout: config[:apply_timeout]
86
- end
47
+ kitchen_provisioner_api_version 2
87
48
 
88
49
  def call(_state = nil)
89
- validate_configuration_files
90
- download_modules
91
- plan_constructive_execution
92
- apply_execution_plan
93
- end
94
-
95
- def coerce_apply_timeout(value:)
96
- config[:apply_timeout] = Integer value
97
- rescue ArgumentError, TypeError
98
- config_error attribute: 'apply_timeout', expected: 'an integer'
99
- end
100
-
101
- def coerce_color(value:)
102
- raise TypeError unless [TrueClass, FalseClass].include?(value.class)
103
- config[:color] = value
104
- rescue TypeError
105
- config_error attribute: 'color', expected: 'a boolean'
106
- end
107
-
108
- def coerce_variable_files(value:)
109
- config[:variable_files] = Array value
110
- end
111
-
112
- def coerce_variables(value:)
113
- config[:variables] =
114
- if value.is_a?(Array) || value.is_a?(String)
115
- deprecated_variables_format value: value
116
- else
117
- Hash value
118
- end
119
- rescue ArgumentError, TypeError
120
- config_error attribute: 'variables',
121
- expected: 'a mapping of Terraform variable assignments'
122
- end
123
-
124
- def download_modules
125
- ::Terraform::GetCommand.execute logger: logger,
126
- target: config[:directory]
127
- end
128
-
129
- def each_list_output(name:, &block)
130
- output(name: name).split(',').each(&block)
131
- end
132
-
133
- def instance_pathname(filename:)
134
- File.join config[:kitchen_root], '.kitchen', 'kitchen-terraform',
135
- instance.name, filename
136
- end
137
-
138
- def output(name:)
139
- ::Terraform::OutputCommand
140
- .execute logger: logger, state: config[:state], target: name, &:chomp
141
- end
142
-
143
- def plan_constructive_execution
144
- ::Terraform::PlanCommand
145
- .execute destroy: false, logger: logger, out: config[:plan],
146
- state: config[:state], target: config[:directory],
147
- variables: config[:variables], color: config[:color],
148
- variable_files: config[:variable_files]
149
- end
150
-
151
- def plan_destructive_execution
152
- ::Terraform::PlanCommand
153
- .execute destroy: true, logger: logger, out: config[:plan],
154
- state: config[:state], target: config[:directory],
155
- variables: config[:variables], color: config[:color],
156
- variable_files: config[:variable_files]
157
- end
158
-
159
- def validate_configuration_files
160
- ::Terraform::ValidateCommand.execute logger: logger,
161
- target: config[:directory]
162
- end
163
-
164
- def validate_version
165
- ::Terraform::VersionCommand.execute logger: logger do |output|
166
- raise UserError,
167
- "Terraform version must match #{SUPPORTED_VERSION}" unless
168
- SUPPORTED_VERSION.match output
169
- end
170
- end
171
-
172
- private
173
-
174
- def deprecated_variables_format(value:)
175
- config_deprecated attribute: 'variables',
176
- expected: 'a mapping rather than a list or string'
177
- Hash[Array(value).map { |string| string.split '=' }]
50
+ driver.validate_configuration_files
51
+ driver.download_modules
52
+ driver.plan_execution destroy: false
53
+ driver.apply_execution_plan
178
54
  end
179
55
  end
180
56
  end
@@ -14,10 +14,9 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require 'kitchen'
18
17
  require 'kitchen/verifier/inspec'
19
18
  require 'terraform/configurable'
20
- require 'terraform/version'
19
+ require 'terraform/groups_config'
21
20
 
22
21
  module Kitchen
23
22
  module Verifier
@@ -26,38 +25,52 @@ module Kitchen
26
25
  class Terraform < Inspec
27
26
  include ::Terraform::Configurable
28
27
 
28
+ include ::Terraform::GroupsConfig
29
+
29
30
  kitchen_verifier_api_version 2
30
31
 
31
- plugin_version ::Terraform::VERSION
32
+ def add_targets(runner:)
33
+ collect_tests.each { |test| runner.add_target test }
34
+ end
32
35
 
33
- required_config :groups do |_, value, verifier|
34
- verifier.coerce_groups value: value
36
+ def call(state)
37
+ self.inspec_runner_options = runner_options transport, state
38
+ config[:groups].each { |group| group.evaluate verifier: self }
35
39
  end
36
40
 
37
- default_config :groups, []
41
+ def execute
42
+ ::Terraform::InspecRunner.new(inspec_runner_options)
43
+ .tap do |inspec_runner|
44
+ inspec_runner.evaluate verifier: self
45
+ end
46
+ end
38
47
 
39
- def call(state)
40
- config[:groups].each do |group|
41
- group.verify_each_host options: runner_options(transport, state)
42
- end
48
+ def merge(options:)
49
+ inspec_runner_options.merge! options
43
50
  end
44
51
 
45
- def coerce_groups(value:)
46
- config[:groups] = Array(value).map do |raw_group|
47
- ::Terraform::Group.new value: raw_group, verifier: self
52
+ def resolve_attributes(group:)
53
+ group.each_attribute do |key, output_name|
54
+ group.store_attribute key: key,
55
+ value: driver.output_value(name: output_name)
48
56
  end
49
- rescue UserError
50
- config_error attribute: 'groups',
51
- expected: 'a collection of group mappings'
52
57
  end
53
58
 
54
- def evaluate(exit_code:)
59
+ def resolve_hostnames(group:, &block)
60
+ driver.output_value list: true, name: group.hostnames, &block
61
+ end
62
+
63
+ def verify(exit_code:)
55
64
  raise InstanceFailure, "Inspec Runner returns #{exit_code}" unless
56
65
  exit_code.zero?
57
66
  end
58
67
 
59
- def populate(runner:)
60
- collect_tests.each { |test| runner.add target: test }
68
+ private
69
+
70
+ attr_accessor :inspec_runner_options
71
+
72
+ def load_needed_dependencies!
73
+ require 'terraform/inspec_runner'
61
74
  end
62
75
  end
63
76
  end