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 +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
|