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 ValueFromLookup
because 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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With