DEV Community

Aparna Krishnamoorthy
Aparna Krishnamoorthy

Posted on

Stop hardcoding AWS Lambda layer ARNs: use public parameters for the AWS Parameters and Secrets Lambda Extension

To add the AWS Parameters and Secrets Lambda Extension to an AWS Lambda function, you can open the documentation, find the ARN table, locate your AWS Region and architecture, copy the ARN, and paste it into your template. This approach works, but the version number at the end of that ARN changes every time AWS releases an update. If you hardcode that number, your deployment stays pinned to an older version, which you might not notice for months.

There's a better approach that uses public parameters in AWS Systems Manager Parameter Store (Parameter Store).

What is the AWS Parameters and Secrets Lambda Extension?

The AWS Parameters and Secrets Lambda Extension is a Lambda layer that retrieves and caches values from Parameter Store and AWS Secrets Manager. It runs as a companion process alongside your function, and serves cached parameter values over a local HTTP endpoint. The use of this extension reduces latency, reduces API call costs, and simplifies your function code: you make a local HTTP call instead of configuring an SDK client and managing your own caching logic.

If you're new to the extension, the AWS Compute Blog post covers the full setup, and provides a walkthrough with load test results showing ~98% fewer API calls.

The problem with hardcoded layer ARNs

The extension is distributed as a Lambda layer. To attach it, you need its ARN:

arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:122
Enter fullscreen mode Exit fullscreen mode

The version number at the end (122 at the time of writing) changes with each release. If you hardcode it, it'll keep working, but you won't get bug fixes, performance improvements, or new features until someone manually checks the docs and updates it.

The Lambda console makes this easy for a single function. You pick "AWS-Parameters-and-Secrets-Lambda-Extension" from a dropdown and choose the latest version. But that doesn't help your CloudFormation templates, CDK stacks, or Terraform configurations, where the ARN is a static string that someone has to maintain.

For a team managing many functions across multiple AWS Regions, it becomes a maintenance chore that's easy to forget.

A better approach: resolve at deploy time

AWS publishes the latest extension layer ARN as a public parameter in every commercial AWS Region. The paths are:

Architecture Parameter path
x86_64 /aws/service/aws-parameters-and-secrets-lambda-extension/x86/latest
ARM64 /aws/service/aws-parameters-and-secrets-lambda-extension/arm64/latest

When you reference these parameters in infrastructure code, the ARN resolves at deploy time. Each deployment picks up the latest version automatically.

The only IAM permission you need is ssm:GetParameter. The parameters are public and readable from any AWS account.

Retrieving the ARN from the CLI

To see the latest layer ARN for your AWS Region, run the following command:

aws ssm get-parameter \
  --name "/aws/service/aws-parameters-and-secrets-lambda-extension/x86/latest" \
  --query "Parameter.Value" \
  --output text
Enter fullscreen mode Exit fullscreen mode

For ARM64:

aws ssm get-parameter \
  --name "/aws/service/aws-parameters-and-secrets-lambda-extension/arm64/latest" \
  --query "Parameter.Value" \
  --output text
Enter fullscreen mode Exit fullscreen mode

You can use these commands in a script, a CI pipeline, or to check what version is the latest before deploying.

Using the parameter in CloudFormation

CloudFormation supports dynamic references that resolve SSM parameters during stack operations. If you reference the public parameter directly, your template won't need a version-specific ARN:

Resources:
  MyFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: my-function
      Runtime: python3.12
      Handler: index.handler
      Architectures:
        - x86_64
      Code:
        ZipFile: |
          import json
          import os
          import urllib.request

          def handler(event, context):
              token = os.environ['AWS_SESSION_TOKEN']

              req = urllib.request.Request(
                  'http://localhost:2773/systemsmanager/parameters/get?name=%2Fmy%2Fparameter'
              )
              req.add_header('X-Aws-Parameters-Secrets-Token', token)
              config = urllib.request.urlopen(req).read()
              return json.loads(config)
      Layers:
        - !Sub '{{resolve:ssm:/aws/service/aws-parameters-and-secrets-lambda-extension/x86/latest}}'
      Role: !GetAtt MyFunctionRole.Arn
Enter fullscreen mode Exit fullscreen mode

The {{resolve:ssm:...}} syntax tells CloudFormation to fetch the parameter value during stack creation or update. The resolved value is fixed until the next stack operation. To pick up a new extension version, update the stack. (The template itself doesn't change.)

For ARM64 functions, swap the path:

Layers:
  - !Sub '{{resolve:ssm:/aws/service/aws-parameters-and-secrets-lambda-extension/arm64/latest}}'
Enter fullscreen mode Exit fullscreen mode

Using the parameter in CDK

CDK resolves the parameter at deploy time using the same underlying SSM resolution:

import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class ParameterCacheStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const extensionArn = ssm.StringParameter.valueForStringParameter(
      this,
      '/aws/service/aws-parameters-and-secrets-lambda-extension/x86/latest'
    );

    new lambda.Function(this, 'MyFunction', {
      runtime: lambda.Runtime.PYTHON_3_12,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
      layers: [
        lambda.LayerVersion.fromLayerVersionArn(this, 'ParamsSecretsExt', extensionArn),
      ],
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Under the hood, CDK synthesizes this into a CloudFormation template parameter of type AWS::SSM::Parameter::Value<String>, so the layer ARN is resolved from the public parameter at deploy time.

Using the parameter in Terraform

data "aws_ssm_parameter" "params_secrets_extension" {
  name = "/aws/service/aws-parameters-and-secrets-lambda-extension/x86/latest"
}

resource "aws_lambda_function" "my_function" {
  function_name = "my-function"
  runtime       = "python3.12"
  handler       = "index.handler"
  filename      = "lambda.zip"
  role          = aws_iam_role.lambda_exec.arn

  architectures = ["x86_64"]

  layers = [
    data.aws_ssm_parameter.params_secrets_extension.value
  ]
}
Enter fullscreen mode Exit fullscreen mode

Each terraform apply resolves the parameter. If a new version was published since your last deploy, you'd see it in the plan.

A common mistake: parameter ARN vs. parameter value

Because it's an AWS resource, the SSM public parameter has its own ARN, and it contains a value that is the Lambda layer ARN. These are not the same thing:

  • Parameter ARN (the address): arn:aws:ssm:us-east-1::parameter/aws/service/aws-parameters-and-secrets-lambda-extension/x86/latest
  • Parameter value (the content): arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:122 (version number at the time of writing)

If you paste the parameter ARN into the Lambda layer field in the console, you'll get a validation error. Lambda expects a layer ARN, not a parameter ARN. The dynamic references in CloudFormation and Terraform handle this resolution automatically. However, if you copy manually from the console, make sure you're copying the value.

One more detail the parameters save you from: the x86_64 and ARM64 layers have different names, not just different version numbers. The x86_64 value resolves to a layer named AWS-Parameters-and-Secrets-Lambda-Extension, while the ARM64 value resolves to AWS-Parameters-and-Secrets-Lambda-Extension-Arm64. Reference the right architecture's parameter and you never have to track that distinction yourself.

Why it matters for teams

Public parameters reduce maintenance work. Every team's deployment pipeline resolves the latest version independently. You don't need shared spreadsheets of ARNs, Slack messages asking what the latest version is, or pull requests that just bump a version number.

When AWS publishes an update with a bug fix or performance improvement, your next deployment picks it up automatically without the need for coordination.

Learn more

Top comments (0)