I created a new cognito stack. I can see in the parameter store that the variables are updated to have the new ids of the new Cognito stack.
However, in my lambdas the env variables are still pointing to the old cognito stack ids which is now deleted. It looks like a cache issue..
I tried deploy with --no-previous-paremeters
but it didn't work, any idea on what should I do ?
export class SSMParameterReader extends AwsCustomResource {
constructor(scope: Construct, name: string, props: SSMParameterReaderProps) {
const { parameterName, region } = props;
const ssmAwsSdkCall: AwsSdkCall = {
service: 'SSM',
action: 'getParameter',
parameters: {
Name: parameterName,
},
region,
physicalResourceId: { id: name }, // Update physical id to always fetch the latest version
};
super(scope, name, {
onUpdate: ssmAwsSdkCall,
policy: {
statements: [
new iam.PolicyStatement({
resources: ['*'],
actions: ['ssm:GetParameter'],
effect: iam.Effect.ALLOW,
}),
],
},
});
}
public getParameterValue(): string {
return this.getResponseField('Parameter.Value').toString();
}
}
And then I call this function to get my parameter
export function getFromSSM(scope: Construct, paramName: string, env?: any): string {
return new SSMParameterReader(scope, scope.node.id + paramName + 'Reader', {
parameterName: paramName,
region: env?.region || 'eu-central-1',
}).getParameterValue();
}
You need to randomize the physicalResourceId
so the custom resource will recieve the Update event and always invoke the SDK call, i.e.
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString())
Consider the following code:
export interface SSMParameterReaderProps {
readonly parameterName: string;
readonly region: string;
};
export class SSMParameterReader extends cr.AwsCustomResource {
constructor(scope: Construct, name: string, props: SSMParameterReaderProps) {
const { parameterName, region } = props;
const ssmAwsSdkCall: cr.AwsSdkCall = {
service: 'SSM',
action: 'getParameter',
parameters: {
Name: parameterName,
},
region,
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()), // Update physical id to always fetch the latest version
};
super(scope, name, {
onUpdate: ssmAwsSdkCall,
policy: {
statements: [
new iam.PolicyStatement({
resources: ['*'],
actions: ['ssm:GetParameter'],
effect: iam.Effect.ALLOW,
}),
],
},
});
}
public getParameterValue(): string {
return this.getResponseField('Parameter.Value').toString();
}
}
And app.ts
const app = new cdk.App();
const env = { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION };
const stack = new cdk.Stack(app, 'SSMCreator', { env })
new ssm.StringParameter(stack, 'Foo', { parameterName: 'foo', stringValue: 'bar' });
const reader = new SSMParameterReader(stack, 'SSMReader', {
parameterName: 'foo',
region: process.env.CDK_DEFAULT_REGION || 'us-east-1',
});
new cdk.CfnOutput(stack, 'Value', { value: reader.getParameterValue()});
On initial deployment, you get bar
as the initial value:
Outputs:
SSMCreator.Value = bar
Now, let's update it with AWS CLI:
aws ssm put-parameter --name foo --value $(date +%s) --overwrite
deploy again and you get the new value:
Outputs:
SSMCreator.Value = 1680733424
Let me know if it works for you.