Skip to content

parameter_store parameter resolver.#211

Merged
andrewjhumphrey merged 11 commits intomasterfrom
andrewjhumphrey-parameter-store-parameter-resolver
Feb 23, 2018
Merged

parameter_store parameter resolver.#211
andrewjhumphrey merged 11 commits intomasterfrom
andrewjhumphrey-parameter-store-parameter-resolver

Conversation

@andrewjhumphrey
Copy link
Copy Markdown
Contributor

@andrewjhumphrey andrewjhumphrey commented Feb 21, 2018

Resolves parameters from the AWS SSM parameter store service as alternative
to the dotgpg malarky. (which is great for large teams but is overkill for single
person/small team use)

This is the inital cut, just uses default AWS managed encryption keys.

Format is pretty simple
parameter.yml:

foo:
  parameter_store: ssm_name

Fetches the SecureString parameter ssm_name from the AWS SSM store using the prevailing
aws credentials.

DONE:

  1. Add ability to specify KMS key_id to use to decrypt
    (to make it useful for storing things like database passwords) (Can't get_parameter doesn't let you specify the key to use, it's stored with the parameter at encryption time)

  2. Add ability to specify version to use to decrypt (Can't retrieve a particular version so of limited utility so not going to do)

  3. Make it work with parameter arrays (Not required, 1 parameter 1 value and it can be a comma separated list if required)

TODO:
Nothing

Copy link
Copy Markdown
Contributor

@ejoubaud ejoubaud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what little understanding I have of stack_master, this looks good to me. And I ❤️ the idea!

Copy link
Copy Markdown
Contributor

@patrobinson patrobinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far

describe '#resolve' do

let(:config) { double(base_dir: '/base') }
let(:stack_definition) { double(stack_name: 'mystack', region: 'us-east-1') }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be an instance_double, which validates any methods called on it actually exist on an instance of the StackDefinition class

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nod Probably but dunno it's worth rejigging everything in this PR, it's done this way in:

  • parameter_resolvers/latest_ami_by_tags_spec
  • parameter_resolvers/latest_ami_spec
  • stack_master/parameter_resolvers/env_spec
    ...etc
    and I'd prefer to address this in a separate PR if we want to change the approach across a bunch of resolvers...

end
it 'should raise and error' do
expect { resolver.resolve(unknown_parameter_name) }
.to raise_error(Aws::SSM::Errors::ParameterNotFound, "Parameter #{unknown_parameter_name} not found")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should catch and re-raise this exception with a different exception class we define. That's at least what all the other parameter resolvers do.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 8e729dd following pattern found in parameter_resolvers/secret

@@ -0,0 +1,15 @@
Given(/^(?:a|the) SSM parameter(?: named)? "([^"]*)" with value "([^"]*)" in region "([^"]*)"$/) do |parameter_name, parameter_value, parameter_region|
File.open("/tmp/humpy-log", 'a') { |file| file.write("In Here name: #{parameter_name} value: #{parameter_value} \n") }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming this was in here for debugging? Can it be removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, has been 17501ef Was debugging why everything appeared to be stubbed, before I discovered lib/stack_master/testing.rb

Copy link
Copy Markdown
Contributor

@petervandoros petervandoros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking very nice! I added a question around the StringList parameter store type.

I'm guessing that you're still planning on adding documentation for this parameter resolver?

name: value,
with_decryption: true
)
resp.parameter.value
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know how array parameter values are handled by StackMaster? Does a StringList parameter type need to be transformed into an Array or will it be handled just fine by StackMaster?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea, I'll add that to the todo list to figure out.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't actually thing it's an issue here, there is only ever one parameter with the same name, so you can only get one value, so iterating and fetching isn't sensible. (which is how the other array_parameters work)
That said if you need to you could store "1,2,3,4,5" as the value for the parameter and it will just work as all stackmaster does is concatenate with comma separators (at least according to my reading of https://github.com/envato/stack_master/blob/master/lib/stack_master/resolver_array.rb#L9-L13)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's my understanding also.

Copy link
Copy Markdown
Contributor

@stevehodgkiss stevehodgkiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Useful feature. Looks good so far!

vpc_cidr:
parameter_store: CUCUMBER_TEST_VPC_CIDR
"""
And a SSM parameter named "CUCUMBER_TEST_VPC_CIDR" with value "10.0.0.0/16" in region "us-east-2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameters wouldn't usually be upper case. Maybe change this to something like /cucumber-test-vpc-cidr or /myapp/prod/something-api-key?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall do, the uppercase was a hangover where I was actually creating the parameter in SSM parameter store (before I realised that all aws calls are stubbed in test mode) and I didn't want to trip over real parameters.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: acd7f6f

@andrewjhumphrey andrewjhumphrey changed the title WIP: parameter_store parameter resolver. parameter_store parameter resolver. Feb 22, 2018
begin
resp = ssm.get_parameter(
name: value,
with_decryption: true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this fail if the parameter is not encrypted?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it's ignored for anything except a SecureString

Comment thread README.md Outdated
An alternative to the secrets store, uses the AWS SSM Parameter store to protect
secrets. Expects a parameter of either `String` or `SecureString` type to be present in the
same region as the stack. You can store the parameter using a command like this
`aws-vault exec <whatever> -- aws ssm put-parameter --region <region> --name <parameter name> --value <secret> --type (String|SecureString)`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should reference aws-vault here, as many people use different authentication methods.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some more white space to avoid being included on the same line

module ParameterResolvers
class ParameterStore < Resolver

SecretNotFound = Class.new(StandardError)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ParameterNotFound would be more appropriate here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SecretNotFound was already used, but sure naming is hard :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 4d9ae15

Copy link
Copy Markdown
Contributor

@patrobinson patrobinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewjhumphrey andrewjhumphrey merged commit f9b2d0c into master Feb 23, 2018
@andrewjhumphrey andrewjhumphrey deleted the andrewjhumphrey-parameter-store-parameter-resolver branch February 23, 2018 01:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants