stack_master 1.14.0 → 1.15.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
  SHA256:
3
- metadata.gz: c6272dd327e82ec747c26129191c4c8e262a4350d6634941f14035746399cb77
4
- data.tar.gz: 6dc8058810bee48a3aed457669ffdda94e9d88fdc2ab1e1c12b9a689a3799c46
3
+ metadata.gz: 1acbc281b89ec3188892fac6692c4e885780efd8ba83f746a774557c0e1194ca
4
+ data.tar.gz: e18cb99eb7f3e99ac0b8fee4b952cb1d21b9f1467a4bbe8dac9250695649f543
5
5
  SHA512:
6
- metadata.gz: 6dad4bcffbc40f9a45377625ef7769f122b5880bbcc61bead8a9ffdd75ee063001f322f9e62079aa00b370f791afd2f76c7acb9b668f6d4f7f41128c63954b65
7
- data.tar.gz: a12c14c9024e187a5b734020cda2adc1c40d7983f58450022ea5f2301412968a167f4ebd6233f02097b8341541dc5ae50b213b6b59730f540594df90b327fd5f
6
+ metadata.gz: bcc6882c647189f6f758896da7cd8084638b707af26faeb234435b99a1e5cd466c0ca90e2f30a67b4414f21f38d899414d7935e49d2a7355ccd84ad700c87ba9
7
+ data.tar.gz: b48a690acadd00aa426084cc3b3b7aeb100b6fbfeaad738cb645df77ca6bd3edce347acf71d2b28ec3ff80833f15e4c55f95f5719922f0d061b2102c0ae1760c
data/README.md CHANGED
@@ -175,7 +175,7 @@ key_name: myapp-us-east-1
175
175
 
176
176
  ### Compile Time Parameters
177
177
 
178
- Compile time parameters can be used for [SparkleFormation](http://www.sparkleformation.io) templates. It conforms and
178
+ Compile time parameters can be used for [SparkleFormation](http://www.sparkleformation.io) templates. It conforms and
179
179
  allows you to use the [Compile Time Parameters](http://www.sparkleformation.io/docs/sparkle_formation/compile-time-parameters.html) feature.
180
180
 
181
181
  A simple example looks like this
@@ -268,6 +268,7 @@ you will likely want to set the parameter to NoEcho in your template.
268
268
  db_password:
269
269
  parameter_store: ssm_parameter_name
270
270
  ```
271
+
271
272
  ### 1Password Lookup
272
273
  An Alternative to the alternative secret store is accessing 1password secrets using the 1password cli (`op`).
273
274
  You declare a 1password lookup with the following parameters in your parameters file:
@@ -286,6 +287,44 @@ Currently we support two types of secrets, `password`s and `secureNote`s. All va
286
287
 
287
288
  For more information on 1password cli please see [here](https://support.1password.com/command-line-getting-started/)
288
289
 
290
+ ### EJSON Store
291
+
292
+ [ejson](https://github.com/Shopify/ejson) is a tool to manage asymmetrically encrypted values in JSON format.
293
+ This allows you to keep secrets securely in git/Github and gives anyone the ability the capability to add new
294
+ secrets without requiring access to the private key. [ejson_wrapper](https://github.com/envato/ejson_wrapper)
295
+ encrypts the underlying EJSON private key with KMS and stores it in the ejson file as `_private_key_enc`. Each
296
+ time an ejson secret is required, the underlying EJSON private key is first decrypted before passing it onto
297
+ ejson to decrypt the file.
298
+
299
+ First, generate an ejson file with ejson_wrapper, specifying the KMS key ID to be used:
300
+
301
+ ```shell
302
+ gem install ejson_wrapper
303
+ ejson_wrapper generate --region us-east-1 --kms-key-id [key_id] --file secrets/production.ejson
304
+ ```
305
+
306
+ Then, add the `ejson_file` argument to your stack in stack_master.yml:
307
+
308
+ ```yaml
309
+ stacks:
310
+ us-east-1:
311
+ my_app:
312
+ template: my_app.json
313
+ ejson_file: production.ejson
314
+ ```
315
+
316
+ finally refer to the secret key in the parameter file, i.e. parameters/my_app.yml:
317
+
318
+ ```yaml
319
+ my_param:
320
+ ejson: "my_secret"
321
+ ```
322
+
323
+ Additional configuration options:
324
+
325
+ - `ejson_file_region` The AWS region to attempt to decrypt private key with
326
+ - `ejson_file_kms` Default: true. Set to false to use ejson without KMS.
327
+
289
328
  ### Security Group
290
329
 
291
330
  Looks up a security group by name and returns the ARN.
data/lib/stack_master.rb CHANGED
@@ -68,6 +68,7 @@ module StackMaster
68
68
  autoload :AcmCertificate, 'stack_master/parameter_resolvers/acm_certificate'
69
69
  autoload :AmiFinder, 'stack_master/parameter_resolvers/ami_finder'
70
70
  autoload :StackOutput, 'stack_master/parameter_resolvers/stack_output'
71
+ autoload :Ejson, 'stack_master/parameter_resolvers/ejson'
71
72
  autoload :Secret, 'stack_master/parameter_resolvers/secret'
72
73
  autoload :SnsTopicName, 'stack_master/parameter_resolvers/sns_topic_name'
73
74
  autoload :SecurityGroup, 'stack_master/parameter_resolvers/security_group'
@@ -0,0 +1,48 @@
1
+ require 'ejson_wrapper'
2
+
3
+ module StackMaster
4
+ module ParameterResolvers
5
+ class Ejson < Resolver
6
+ SecretNotFound = Class.new(StandardError)
7
+
8
+ def initialize(config, stack_definition)
9
+ @config = config
10
+ @stack_definition = stack_definition
11
+ end
12
+
13
+ def resolve(secret_key)
14
+ validate_ejson_file_specified
15
+ secrets = decrypt_ejson_file
16
+ secrets.fetch(secret_key.to_sym) do
17
+ raise SecretNotFound, "Unable to find key #{secret_key} in file #{ejson_file}"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def validate_ejson_file_specified
24
+ if @stack_definition.ejson_file.nil?
25
+ raise ArgumentError, "No ejson_file defined for stack definition #{@stack_definition.stack_name} in #{@stack_definition.region}"
26
+ end
27
+ end
28
+
29
+ def decrypt_ejson_file
30
+ @decrypt_ejson_file ||= EJSONWrapper.decrypt(ejson_file_path,
31
+ use_kms: @stack_definition.ejson_file_kms,
32
+ region: ejson_file_region)
33
+ end
34
+
35
+ def ejson_file_region
36
+ @stack_definition.ejson_file_region || StackMaster.cloud_formation_driver.region
37
+ end
38
+
39
+ def ejson_file_path
40
+ @ejson_file_path ||= File.join(@config.base_dir, secret_path_relative_to_base)
41
+ end
42
+
43
+ def secret_path_relative_to_base
44
+ @secret_path_relative_to_base ||= File.join('secrets', @stack_definition.ejson_file)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -10,6 +10,9 @@ module StackMaster
10
10
  :base_dir,
11
11
  :template_dir,
12
12
  :secret_file,
13
+ :ejson_file,
14
+ :ejson_file_region,
15
+ :ejson_file_kms,
13
16
  :stack_policy_file,
14
17
  :additional_parameter_lookup_dirs,
15
18
  :s3,
@@ -25,6 +28,7 @@ module StackMaster
25
28
  @s3 = {}
26
29
  @files = []
27
30
  @allowed_accounts = nil
31
+ @ejson_file_kms = true
28
32
  super
29
33
  @template_dir ||= File.join(@base_dir, 'templates')
30
34
  @allowed_accounts = Array(@allowed_accounts)
@@ -41,6 +45,9 @@ module StackMaster
41
45
  @notification_arns == other.notification_arns &&
42
46
  @base_dir == other.base_dir &&
43
47
  @secret_file == other.secret_file &&
48
+ @ejson_file == other.ejson_file &&
49
+ @ejson_file_region == other.ejson_file_region &&
50
+ @ejson_file_kms == other.ejson_file_kms &&
44
51
  @stack_policy_file == other.stack_policy_file &&
45
52
  @additional_parameter_lookup_dirs == other.additional_parameter_lookup_dirs &&
46
53
  @s3 == other.s3 &&
@@ -75,7 +75,7 @@ module StackMaster
75
75
 
76
76
  def single_param_update?(param_name)
77
77
  return false if param_name.blank? || @current_stack.blank? || body_different?
78
- differences = HashDiff.diff(@current_stack.parameters_with_defaults, @proposed_stack.parameters_with_defaults)
78
+ differences = Hashdiff.diff(@current_stack.parameters_with_defaults, @proposed_stack.parameters_with_defaults)
79
79
  return false if differences.count != 1
80
80
  diff = differences[0]
81
81
  diff[0] == "~" && diff[1] == param_name
@@ -1,3 +1,3 @@
1
1
  module StackMaster
2
- VERSION = "1.14.0"
2
+ VERSION = "1.15.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stack_master
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Hodgkiss
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-07-03 00:00:00.000000000 Z
12
+ date: 2019-08-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -377,6 +377,20 @@ dependencies:
377
377
  version: '0'
378
378
  - !ruby/object:Gem::Dependency
379
379
  name: hashdiff
380
+ requirement: !ruby/object:Gem::Requirement
381
+ requirements:
382
+ - - "~>"
383
+ - !ruby/object:Gem::Version
384
+ version: '1'
385
+ type: :runtime
386
+ prerelease: false
387
+ version_requirements: !ruby/object:Gem::Requirement
388
+ requirements:
389
+ - - "~>"
390
+ - !ruby/object:Gem::Version
391
+ version: '1'
392
+ - !ruby/object:Gem::Dependency
393
+ name: ejson_wrapper
380
394
  requirement: !ruby/object:Gem::Requirement
381
395
  requirements:
382
396
  - - ">="
@@ -441,6 +455,7 @@ files:
441
455
  - lib/stack_master/parameter_resolver.rb
442
456
  - lib/stack_master/parameter_resolvers/acm_certificate.rb
443
457
  - lib/stack_master/parameter_resolvers/ami_finder.rb
458
+ - lib/stack_master/parameter_resolvers/ejson.rb
444
459
  - lib/stack_master/parameter_resolvers/env.rb
445
460
  - lib/stack_master/parameter_resolvers/latest_ami.rb
446
461
  - lib/stack_master/parameter_resolvers/latest_ami_by_tags.rb
@@ -514,8 +529,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
514
529
  - !ruby/object:Gem::Version
515
530
  version: '0'
516
531
  requirements: []
517
- rubyforge_project:
518
- rubygems_version: 2.7.6
532
+ rubygems_version: 3.0.3
519
533
  signing_key:
520
534
  specification_version: 4
521
535
  summary: StackMaster is a sure-footed way of creating, updating and keeping track