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
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
For ARM64:
aws ssm get-parameter \
--name "/aws/service/aws-parameters-and-secrets-lambda-extension/arm64/latest" \
--query "Parameter.Value" \
--output text
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
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}}'
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),
],
});
}
}
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
]
}
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.
Top comments (0)