Lambda函数的SSM环境变量未更新。

huangapple go评论59阅读模式
英文:

Lambda functions SSM environment variables are not updated

问题

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-parameters but it didn't work, any idea on what should I do ?

我创建了一个新的Cognito堆栈。我可以在参数存储中看到变量已更新为新的Cognito堆栈的新ID。然而,在我的Lambda函数中,环境变量仍然指向已删除的旧Cognito堆栈的ID,看起来像是缓存问题。我尝试使用 --no-previous-parameters 部署,但没有效果,您有什么建议吗?

英文:

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 ?

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

export class SSMParameterReader extends AwsCustomResource {
    constructor(scope: Construct, name: string, props: SSMParameterReaderProps) {
        const { parameterName, region } = props;

        const ssmAwsSdkCall: AwsSdkCall = {
            service: &#39;SSM&#39;,
            action: &#39;getParameter&#39;,
            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: [&#39;*&#39;],
                        actions: [&#39;ssm:GetParameter&#39;],
                        effect: iam.Effect.ALLOW,
                    }),
                ],
            },
        });
    }

    public getParameterValue(): string {
        return this.getResponseField(&#39;Parameter.Value&#39;).toString();
    }
}

<!-- end snippet -->

And then I call this function to get my parameter

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

export function getFromSSM(scope: Construct, paramName: string, env?: any): string {
    return new SSMParameterReader(scope, scope.node.id + paramName + &#39;Reader&#39;, {
        parameterName: paramName,
        region: env?.region || &#39;eu-central-1&#39;,
    }).getParameterValue();
}

<!-- end snippet -->

答案1

得分: 1

您需要随机化physicalResourceId,以便自定义资源会收到更新事件并始终调用SDK调用,即:

physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString())

考虑以下代码:

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()), // 更新物理标识以始终获取最新版本
      };

      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();
  }
}

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()});

在初始部署时,您将获得bar作为初始值:

Outputs:
SSMCreator.Value = bar

现在,让我们使用AWS CLI进行更新:

aws ssm put-parameter --name foo --value $(date +%s) --overwrite

再次部署,您将获得新的值:

Outputs:
SSMCreator.Value = 1680733424

请告诉我是否对您有帮助。

英文:

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:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

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: &#39;SSM&#39;,
          action: &#39;getParameter&#39;,
          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: [&#39;*&#39;],
                      actions: [&#39;ssm:GetParameter&#39;],
                      effect: iam.Effect.ALLOW,
                  }),
              ],
          },
      });
  }

  public getParameterValue(): string {
      return this.getResponseField(&#39;Parameter.Value&#39;).toString();
  }
}

<!-- end snippet -->

And app.ts

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

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, &#39;SSMCreator&#39;, { env })
new ssm.StringParameter(stack, &#39;Foo&#39;, { parameterName: &#39;foo&#39;, stringValue: &#39;bar&#39; });

const reader = new SSMParameterReader(stack, &#39;SSMReader&#39;, {
  parameterName: &#39;foo&#39;,
  region: process.env.CDK_DEFAULT_REGION || &#39;us-east-1&#39;,
});
new cdk.CfnOutput(stack, &#39;Value&#39;, { value: reader.getParameterValue()});

<!-- end snippet -->

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.

huangapple
  • 本文由 发表于 2023年3月31日 22:11:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75899514.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定