GitHub Actions工作流遇botocore异常失败(DynamoDB Local环境)
问题描述
我在GitHub工作流中尝试多种方式运行pytest测试,却一直碰到AWS boto相关错误,包括:
botocore.exceptions.ClientError: An error occurred (UnrecognizedClientException) when calling the CreateTable operation: The security token included in the request is invalid.
或者:
botocore.exceptions.NoRegionError: You must specify a region.
现在我已经简化了工作流,但还是出现这个错误:
botocore.exceptions.ClientError: An error occurred (UnrecognizedClientException) when calling the CreateTable operation: The security token included in the request is invalid.
我的工作流配置如下:
name: Automated Tests permissions: read-all on: workflow_dispatch: push: branches: - main - develop pull_request: branches: - main - develop - "*" jobs: pytest-tests: name: Run Pytest Tests runs-on: ubuntu-latest env: ENV: "local" REDIS_HOST: "127.0.0.1" REDIS_PORT: "6379" REDIS_SSL_ENABLED: "False" AWS_ACCESS_KEY_ID: "dummy" AWS_SECRET_ACCESS_KEY: "dummy" AWS_DEFAULT_REGION: "us-west-2" AWS_REGION: "us-west-2" DYNAMO_ENDPOINT: "http://localhost:8001" services: dynamodb: image: amazon/dynamodb-local ports: - 8001:8000 # my API runs on port 8000 so DynamoDB runs on 8001 steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.x" - name: Install Poetry run: pip install poetry - name: Install dependencies with Poetry run: poetry install --no-root - name: Run Tests with Pytest run: poetry run pytest -k test_update_customer
请问我的工作流编写是否正确?如何修复本地DynamoDB以在CI环境中正常运行,使pytest测试顺利通过?
问题分析与修复方案
工作流配置的核心问题
你的工作流整体结构没问题,但和DynamoDB本地实例交互的部分存在几个关键疏漏:
- 网络寻址问题:GitHub Actions的service容器和作业主机通过内部网络通信,
localhost寻址可能存在延迟或解析错误 - 凭证优先级问题:boto3会优先读取系统默认凭证链,你的dummy凭证可能被覆盖
- 客户端配置缺失:测试代码可能未明确指定DynamoDB端点、区域等参数,导致走默认逻辑出错
具体修复步骤
1. 调整DynamoDB服务与端点配置
改用服务名作为DynamoDB主机地址(GitHub Actions会自动解析服务名到容器),同时优化端口映射:
services: dynamodb: image: amazon/dynamodb-local ports: - 8000:8000 # 保持默认端口映射,避免冲突 options: >- --name dynamodb-local env: # 用服务名替代localhost,确保内部网络可访问 DYNAMO_ENDPOINT: "http://dynamodb:8000" AWS_ACCESS_KEY_ID: "dummy" AWS_SECRET_ACCESS_KEY: "dummy" AWS_DEFAULT_REGION: "us-west-2" AWS_REGION: "us-west-2" # 禁用EC2元数据服务,避免boto3尝试读取默认凭证 AWS_EC2_METADATA_DISABLED: "true"
2. 强制测试代码显式配置boto3客户端
在测试代码初始化DynamoDB客户端时,明确指定所有必要参数,不依赖环境变量自动读取:
import boto3 def init_dynamodb_client(): return boto3.client( 'dynamodb', endpoint_url="http://dynamodb:8000", aws_access_key_id="dummy", aws_secret_access_key="dummy", region_name="us-west-2" ) # 如果使用DynamoDB资源 def init_dynamodb_resource(): return boto3.resource( 'dynamodb', endpoint_url="http://dynamodb:8000", aws_access_key_id="dummy", aws_secret_access_key="dummy", region_name="us-west-2" )
3. 添加DynamoDB服务健康检查
在运行测试前,确保DynamoDB实例完全启动,避免因服务未就绪导致的错误:
在工作流的Run Tests with Pytest步骤前添加:
- name: Wait for DynamoDB Local to be ready run: | until curl -s $DYNAMO_ENDPOINT/healthcheck; do echo "Waiting for DynamoDB Local..." sleep 2 done
4. 验证调整后的完整工作流
最终工作流配置如下:
name: Automated Tests permissions: read-all on: workflow_dispatch: push: branches: - main - develop pull_request: branches: - main - develop - "*" jobs: pytest-tests: name: Run Pytest Tests runs-on: ubuntu-latest env: ENV: "local" REDIS_HOST: "127.0.0.1" REDIS_PORT: "6379" REDIS_SSL_ENABLED: "False" AWS_ACCESS_KEY_ID: "dummy" AWS_SECRET_ACCESS_KEY: "dummy" AWS_DEFAULT_REGION: "us-west-2" AWS_REGION: "us-west-2" DYNAMO_ENDPOINT: "http://dynamodb:8000" AWS_EC2_METADATA_DISABLED: "true" services: dynamodb: image: amazon/dynamodb-local ports: - 8000:8000 steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.x" - name: Install Poetry run: pip install poetry - name: Install dependencies with Poetry run: poetry install --no-root - name: Wait for DynamoDB Local to be ready run: | until curl -s $DYNAMO_ENDPOINT/healthcheck; do echo "Waiting for DynamoDB Local..." sleep 2 done - name: Run Tests with Pytest run: poetry run pytest -k test_update_customer
内容的提问来源于stack exchange,提问作者AugustusCaesar

