stack_master 1.14.0 → 1.15.0
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 +40 -1
- data/lib/stack_master.rb +1 -0
- data/lib/stack_master/parameter_resolvers/ejson.rb +48 -0
- data/lib/stack_master/stack_definition.rb +7 -0
- data/lib/stack_master/stack_differ.rb +1 -1
- data/lib/stack_master/version.rb +1 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1acbc281b89ec3188892fac6692c4e885780efd8ba83f746a774557c0e1194ca
|
4
|
+
data.tar.gz: e18cb99eb7f3e99ac0b8fee4b952cb1d21b9f1467a4bbe8dac9250695649f543
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
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
|
data/lib/stack_master/version.rb
CHANGED
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.
|
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-
|
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
|
-
|
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
|