Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to consume Parameter Store value in AWS CDK

I am having problems using SSM valueForStringParameter method in CDK. It's working the first time I deploy the stack, but it is not picking up updates to the parameter value when I redeploy the stack because CloudFormation template hasn't changed and so CloudFormation thinks there were no updates, even if SSM parameter has changed.

For the context, I am deploying stack via CodePipeline, where I run cdk synth first, and then use CloudFormationCreateUpdateStackAction action to deploy template.

Anyone knows how to work around that? The only other option that I know will work is to switch to a custom resource lambda that calls SSM and returns value using aws-sdk, but that feels like a overly complicated option.

Update 1 I cannot use ValueFromLookupbecause value is only updated at runtime as part of cloudformation deployment by another stack (I deploy both stacks in CodePipeline, in 2 different regions), so synthesis time lookup would result in stale value.

like image 705
Tofig Hasanov Avatar asked Apr 22 '20 15:04

Tofig Hasanov


People also ask

How do you find the value of parameter store?

To read a value from the Systems Manager parameter store at synthesis time, use the valueFromLookup method (Python: value_from_lookup ). This method returns the actual value of the parameter as a Runtime context value. If the value is not already cached in cdk.

What is the difference between AWS secrets manager and parameter store?

Parameter Store only allows one version of the parameter to be active at any given time. Secrets Manager, on the other hand, allows multiple versions to exist at the same time when you are performing a secret rotation. Secrets Manager distinguishes between different versions by the staging labels.

How do you encrypt a parameter store?

To encrypt a standard secure string parameter value, the user needs kms:Encrypt permission. To encrypt an advanced secure string parameter value, the user needs kms:GenerateDataKey permission. To decrypt either type of secure string parameter value, the user needs kms:Decrypt permission.


2 Answers

Since you cannot use lookup functions and the most common way to pass config to cdk is through context variables, I can only suggest dirty workarounds.

For example, you could create a dummy parameter in your stack to bump every time there's deployment.

var deploymentId = new CfnParameter(this, "deploymentId", new CfnParameterProps() { Type = "String", Description = "Deployment Id" });
SetParameterValue(deploymentId, this.Node.GetContext("deploymentId").ToString());

and when you synthesize the CF, you could generate an ID:

cdk synth -c deploymentId=$(uuidgen)

If you can avoid the "environment agnostic" syth and you really need an immutable artifact to deploy across multiple environments, you could use the built package from your cdk, for example, the npm package containing your cdk. Therefore, you could deploy it in each environment by overwriting the context parameters instead of using ssm parameters store.

like image 133
Pedreiro Avatar answered Oct 24 '22 01:10

Pedreiro


All the valueOf* and from* methods work by adding a CloudFormation parameter. As you figured out already, changing the parameter value does not change the template and no change will be triggered.

What you probably want to use instead is the method valueFromLookup. Lookups are executed during synth and the result is put into the generated CFN template.

ssm.StringParameter.valueFromLookup(this, 'param-name');

But be aware, lookups are stored in the cdk.context.json. If you have commited that file to your repo, you need to erase that key via cdk context -e ... before synth/diff/deploy.

like image 32
udondan Avatar answered Oct 24 '22 01:10

udondan