如何解决AWS Lambda调用Parameter Store扩展时的URLError(Errno97)问题?
问题
我尝试从AWS Lambda中获取存储在AWS Parameter Store中的secure string变量,按照官方文档部署了Lambda Layer中的代码。
Layer中的代码parameter_store_extension.py:
# parameter_store_extension.py import urllib import json import os from urllib.parse import urlencode aws_session_token = os.environ.get('AWS_SESSION_TOKEN') port = '2773' def get_param(name: str): """ Get SALT form systems manager/parameter store """ params = dict(name=name) req = urllib.request.Request( f"http://localhost:{port}/systemsmanager/parameters/get/?{urlencode(params)}&withDecryption=true") req.add_header('X-Aws-Parameters-Secrets-Token', aws_session_token) config = urllib.request.urlopen(req).read() return json.loads(config)
在lambda_function.py的lambda_handler中调用:
from parameter_store_extension import get_param SALT = get_param('SALT')
测试时出现以下错误:
{ "errorMessage": "<urlopen error [Errno 97] Address family not supported by protocol>", "errorType": "URLError", "requestId": "", "stackTrace": [ " File \"/var/lang/lib/python3.10/importlib/__init__.py\", line 126, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n", " File \"<frozen importlib._bootstrap>\", line 1050, in _gcd_import\n", " File \"<frozen importlib._bootstrap>\", line 1027, in _find_and_load\n", " File \"<frozen importlib._bootstrap>\", line 1006, in _find_and_load_unlocked\n", " File \"<frozen importlib._bootstrap>\", line 688, in _load_unlocked\n", " File \"<frozen importlib._bootstrap_external>\", line 883, in exec_module\n", " File \"<frozen importlib._bootstrap>\", line 241, in _call_with_frames_removed\n", " File \"/var/task/lambda_function.py\", line 9, in <module>\n SALT = get_param('SALT')\n", " File \"/opt/python/lib/python3.10/site-packages/parameter_store_extension.py\", line 19, in get_param\n config = urllib.request.urlopen(req).read()\n", " File \"/var/lang/lib/python3.10/urllib/request.py\", line 216, in urlopen\n return opener.open(url, data, timeout)\n", " File \"/var/lang/lib/python3.10/urllib/request.py\", line 519, in open\n response = self._open(req, data)\n", " File \"/var/lang/lib/python3.10/urllib/request.py\", line 536, in _open\n result = self._call_chain(self.handle_open, protocol, protocol +\n", " File \"/var/lang/lib/python3.10/urllib/request.py\", line 496, in _call_chain\n result = func(*args)\n", " File \"/var/lang/lib/python3.10/urllib/request.py\", line 1377, in http_open\n return self.do_open(http.client.HTTPConnection, req)\n", " File \"/var/lang/lib/python3.10/urllib/request.py\", line 1351, in do_open\n raise URLError(err)\n" ] }
函数日志:
[ERROR] URLError: <urlopen error [Errno 97] Address family not supported by protocol> Traceback (most recent call last): File "/var/lang/lib/python3.10/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1050, in _gcd_import File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/var/task/lambda_function.py", line 9, in <module> SALT = get_param('SALT') File "/opt/python/lib/python3.10/site-packages/parameter_store_extension.py", line 19, in get_param config = urllib.request.urlopen(req).read() File "/var/lang/lib/python3.10/urllib/request.py", line 216, in urlopen return opener.open(url, data, timeout) File "/var/lang/lib/python3.10/urllib/request.py", line 519, in open response = self._open(req, data) File "/var/lang/lib/python3.10/urllib/request.py", line 536, in _open result = self._call_chain(self.handle_open, protocol, protocol + File "/var/lang/lib/python3.10/urllib/request.py", line 496, in _call_chain result = func(*args) File "/var/lang/lib/python3.10/urllib/request.py", line 1377, in http_open return self.do_open(http.client.HTTPConnection, req) File "/var/lang/lib/python3.10/urllib/request.py", line 1351, in do_open raise URLError(err)[ERROR] URLError: <urlopen error [Errno 97] Address family not supported by protocol> Traceback (most recent call last): File "/var/lang/lib/python3.10/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1050, in _gcd_import File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/var/task/lambda_function.py", line 9, in <module> SALT = get_param('SALT') File "/opt/python/lib/python3.10/site-packages/parameter_store_extension.py", line 19, in get_param config = urllib.request.urlopen(req).read() File "/var/lang/lib/python3.10/urllib/request.py", line 216, in urlopen return opener.open(url, data, timeout) File "/var/lang/lib/python3.10/urllib/request.py", line 519, in open response = self._open(req, data) File "/var/lang/lib/python3.10/urllib/request.py", line 536, in _open result = self._call_chain(self.handle_open, protocol, protocol + File "/var/lang/lib/python3.10/urllib/request.py", line 496, in _call_chain result = func(*args) File "/var/lang/lib/python3.10/urllib/request.py", line 1377, in http_open return self.do_open(http.client.HTTPConnection, req) File "/var/lang/lib/python3.10/urllib/request.py", line 1351, in do_open raise URLError(err)START RequestId: 41f27d03-65ab-4130-a5e9-2db8ed47e8e2 Version: $LATEST Unknown application error occurred Runtime.Unknown END RequestId: 41f27d03-65ab-4130-a5e9-2db8ed47e8e2 REPORT RequestId: 41f27d03-65ab-4130-a5e9-2db8ed47e8e2 Duration: 5031.52 ms Billed Duration: 5032 ms Memory Size: 128 MB Max Memory Used: 27 MB
解决方案
1. 替换localhost为127.0.0.1
Lambda执行环境中localhost默认解析为IPv6地址,但SSM Parameter Store Extension仅监听IPv4的127.0.0.1,导致地址族不兼容。修改请求URL:
req = urllib.request.Request( f"http://127.0.0.1:{port}/systemsmanager/parameters/get/?{urlencode(params)}&withDecryption=true")
2. 确认SSM Extension部署和权限配置
- 检查Lambda函数是否已添加AWS Systems Manager Parameter Store Extension层,层ARN格式为
arn:aws:lambda:<区域>:015030872274:layer:AWS-Parameters-and-Secrets-Lambda-Extension:<版本号>,选择最新稳定版本。 - 确保Lambda执行角色拥有
ssm:GetParameter权限,且权限范围覆盖目标参数SALT。
3. 调整参数获取的执行时机
模块导入阶段Lambda Extension可能未完成初始化,将参数获取逻辑移至lambda_handler内部:
from parameter_store_extension import get_param def lambda_handler(event, context): SALT = get_param('SALT') # 后续业务逻辑
4. 强制urllib使用IPv4(可选)
若坚持使用localhost,可通过自定义socket强制IPv4连接:
import socket def get_param(name: str): params = dict(name=name) req = urllib.request.Request( f"http://localhost:{port}/systemsmanager/parameters/get/?{urlencode(params)}&withDecryption=true") req.add_header('X-Aws-Parameters-Secrets-Token', aws_session_token) # 创建IPv4 socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) config = urllib.request.urlopen(req, timeout=5, socket=sock).read() return json.loads(config)
内容的提问来源于stack exchange,提问作者UMR
相关产品推荐
相关产品推荐

