第 9 章 · 部署指南
9.1 部署概览
ADAP 采用 AWS CDK(Python) 管理全部云基础设施,基础设施即代码(IaC)覆盖 8 个 CloudFormation Stack。前端独立构建后部署到 EC2 Nginx 或 S3 + CloudFront。
部署架构图
┌─────────────────────────────────────────────────────────────────────┐
│ 开发者本地 / CI 环境 │
│ │
│ git clone → pip install → cdk bootstrap → cdk deploy │
│ │
│ frontend/ → npm build → scp to EC2 Nginx │
│ (或 aws s3 sync + CloudFront invalidate) │
└──────────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AWS 账号(us-east-1) │
│ │
│ ADAP-IAM ─────────────────────────────────────────────────────── │
│ ADAP-S3 ─── adap-prototype-{account_id} │
│ ADAP-Auth ── Cognito User Pool │
│ ADAP-AgentCore ── Bedrock Agent │
│ ADAP-EMR ──── EMR Serverless Application │
│ ADAP-Compute ─ Lambda × 5 + DynamoDB × 4 │
│ ADAP-API ──── REST API Gateway + WebSocket API │
│ ADAP-Logs ─── CloudWatch Log Groups │
│ ADAP-Alarms ─ CloudWatch Alarms + SNS │
│ ADAP-Orchestration ─ Step Functions State Machine │
└─────────────────────────────────────────────────────────────────────┘Stack 部署顺序
| 顺序 | Stack 名称 | 说明 | 依赖 |
|---|---|---|---|
| 1 | ADAP-IAM | IAM 角色(Glue、Lambda 等) | — |
| 2 | ADAP-S3 | 数据湖 S3 Bucket | — |
| 3 | ADAP-Auth | Cognito User Pool + Client | — |
| 4 | ADAP-AgentCore | Bedrock Agent + Alias + Role | IAM, S3 |
| 5 | ADAP-EMR | EMR Serverless Application | IAM, S3 |
| 6 | ADAP-Redshift | Redshift Serverless(可选) | IAM, S3 |
| 7 | ADAP-Compute | Lambda × 5 + DynamoDB × 4 | IAM, AgentCore |
| 8 | ADAP-API | REST + WebSocket API Gateway | Auth, Compute |
| 9 | ADAP-Logs | CloudWatch Log Groups | — |
| 10 | ADAP-Alarms | CloudWatch 告警 + SNS | — |
| 11 | ADAP-Orchestration | Step Functions 状态机 | Compute |
9.2 前置条件
9.2.1 AWS 账号准备
Bedrock 模型访问权限
在目标 Region(us-east-1)的 Bedrock 控制台,开通以下模型访问:
模型 用途 Claude Sonnet 4.6 主执行 Agent(大部分任务) Claude Opus 4(可选) 决策层,更复杂的分析任务 路径:Bedrock Console → Model Access → Request model access
Bedrock AgentCore 权限(如使用 AgentCore Runtime)
确认账号有
bedrock:CreateAgent、bedrock:CreateAgentAlias等 Agent 管理权限。AWS CLI 配置
bashaws configure # AWS Access Key ID: <your-access-key> # AWS Secret Access Key: <your-secret-key> # Default region name: us-east-1 # Default output format: json或使用 IAM Role(推荐生产环境):
bashaws sts get-caller-identity # 验证凭证有效
9.2.2 本地环境要求
| 工具 | 最低版本 | 安装方式 |
|---|---|---|
| Python | 3.11+ | pyenv install 3.11 |
| Node.js | 18+ | nvm install 18 |
| AWS CDK | 2.130+ | npm install -g aws-cdk |
| AWS CLI | 2.x | 官方文档 |
| Git | 2.x | 系统包管理器 |
验证:
python3 --version # Python 3.11.x
node --version # v18.x.x 或 v20.x.x
cdk --version # 2.130.0 (build xxxx)
aws --version # aws-cli/2.x.x9.3 获取代码
git clone <repo-url>
cd agentic-data-platform9.4 Python 环境配置
9.4.1 创建虚拟环境
python3 -m venv .venv
source .venv/bin/activate # Linux / macOS
# .venv\Scripts\activate # Windows
pip install -r requirements.txtrequirements.txt 核心依赖说明:
strands-agents>=0.1.0 # Strands Agents SDK(Agent 执行框架)
boto3>=1.34.0 # AWS SDK
pymysql>=1.1.0 # MySQL 数据源连接
pandas>=2.0.0 # 数据处理
pyarrow>=14.0.0 # Parquet 格式(S3 ODS 写入)
aws-cdk-lib>=2.130.0 # CDK 基础设施定义
pydantic>=2.0.0 # 数据模型校验9.4.2 环境变量配置
在项目根目录创建 .env 文件(本地开发用):
cp .env.example .env # 如果有示例文件
# 或手动创建:
cat > .env << 'EOF'
# AWS 配置
AWS_REGION=us-east-1
AWS_ACCOUNT_ID=123456789012
# 数据库(本地测试用,生产用 SSM Parameter Store)
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=adap_user
MYSQL_PASSWORD=your_password
# Bedrock Agent(部署后从 CDK Output 获取)
BEDROCK_AGENT_ID=XXXXXXXXXX
BEDROCK_AGENT_ALIAS_ID=YYYYYYYYYY
# API Gateway(部署后从 CDK Output 获取)
API_BASE_URL=https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod
WS_URL=wss://yyyyyyyyyy.execute-api.us-east-1.amazonaws.com/prod
# Cognito(部署后从 CDK Output 获取)
COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
COGNITO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
EOF⚠️
.env已加入.gitignore,请勿提交到代码仓库。
9.5 CDK 部署
9.5.1 CDK Bootstrap(首次部署必须)
cd infra/cdk
cdk bootstrap aws://<account_id>/us-east-1Bootstrap 会在账号中创建:
- S3 Bucket(存放 CloudFormation 资产)
- IAM Role(CDK 部署所用)
- ECR Repository(如使用容器资产)
成功输出示例:
✅ Environment aws://123456789012/us-east-1 bootstrapped.9.5.2 部署所有 Stack
cd infra/cdk
# 查看将要创建的所有资源(dry-run)
cdk diff
# 一键部署全部 Stack
cdk deploy --all --require-approval neverCDK 会按依赖顺序自动编排 Stack 的部署顺序。总耗时约 15~25 分钟(主要等待 Cognito、Bedrock Agent 创建)。
9.5.3 按需部署单个 Stack
# 只部署基础层(首次推荐)
cdk deploy ADAP-IAM ADAP-S3
# 部署认证层
cdk deploy ADAP-Auth
# 部署 Bedrock AgentCore
cdk deploy ADAP-AgentCore
# 部署计算层(Lambda + DynamoDB)
cdk deploy ADAP-Compute
# 部署 API 层
cdk deploy ADAP-API
# 部署编排层
cdk deploy ADAP-Orchestration
# 部署日志和告警
cdk deploy ADAP-Logs ADAP-Alarms9.5.4 查看 CDK 输出
部署完成后,CDK 会在终端输出关键参数(同时写入 CloudFormation Stack Outputs):
# 查看所有 Stack 的 Output
aws cloudformation describe-stacks \
--query 'Stacks[?starts_with(StackName, `ADAP`)].{Name:StackName,Outputs:Outputs}' \
--output json | python3 -c "
import json, sys
stacks = json.load(sys.stdin)
for stack in stacks:
print(f\"\\n=== {stack['Name']} ===\")
for o in stack.get('Outputs', []):
print(f\" {o['OutputKey']}: {o['OutputValue']}\")
"关键输出参数:
| Stack | 输出参数 | 用途 |
|---|---|---|
| ADAP-S3 | BucketName | 数据湖 Bucket 名称 |
| ADAP-Auth | UserPoolId | Cognito User Pool ID |
| ADAP-Auth | UserPoolClientId | Cognito App Client ID |
| ADAP-AgentCore | AgentId | Bedrock Agent ID |
| ADAP-AgentCore | AgentAliasId | Bedrock Agent Alias ID |
| ADAP-API | RestApiUrl | REST API 端点 |
| ADAP-API | WebSocketUrl | WebSocket API 端点 |
9.6 Bedrock Agent 版本管理
9.6.1 为什么需要手动操作
由于 AWS boto3 SDK 暂不支持 create_agent_version API(需要 Bedrock Console 手动操作),AgentCore 的版本管理需要在 CDK 部署之外手动完成。
9.6.2 创建新版本流程
- 进入 Bedrock Console → Agents → ADAP-Agent
- 点击右上角 「Create version」
- 填写版本说明(如
v3 - 新增数据治理 Agent) - 点击 「Create」,等待
PREPARED状态 - 点击 「Aliases」→「prod」→「Edit」
- 将 prod alias 指向新创建的版本
- 点击 「Save」
9.6.3 验证 Agent 版本
aws bedrock-agent get-agent \
--agent-id <AgentId> \
--query 'agent.{id:agentId,status:agentStatus,version:agentVersion}'9.7 前端部署
9.7.1 配置前端环境变量
cd frontend
cat > .env.production << EOF
VITE_API_BASE_URL=https://<rest-api-id>.execute-api.us-east-1.amazonaws.com/prod
VITE_WS_URL=wss://<ws-api-id>.execute-api.us-east-1.amazonaws.com/prod
VITE_COGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
VITE_COGNITO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
VITE_REGION=us-east-1
EOF9.7.2 构建前端
cd frontend
npm install
npm run build
# 构建产物位于 dist/9.7.3 方案 A:部署到 EC2 Nginx(开发/测试)
# 使用部署脚本
EC2_HOST=<ec2-public-ip> \
EC2_KEY=~/.ssh/your-key.pem \
./scripts/deploy_frontend.sh脚本执行流程:
npm run build构建 React 应用scp将dist/上传到 EC2 的 Nginx web 目录nginx -s reload重载 Nginx 配置
Nginx 配置参考(/etc/nginx/conf.d/adap.conf):
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# React Router 支持(SPA 路由回退)
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存(Vite 生成 hash 文件名,可永久缓存)
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}9.7.4 方案 B:部署到 S3 + CloudFront(生产推荐)
# 1. 创建 S3 Bucket(启用静态网站托管)
aws s3 mb s3://adap-frontend-<account_id>
aws s3 website s3://adap-frontend-<account_id> \
--index-document index.html \
--error-document index.html
# 2. 上传构建产物
aws s3 sync frontend/dist/ s3://adap-frontend-<account_id>/ \
--delete \
--cache-control "public,max-age=31536000,immutable" \
--exclude "index.html"
# index.html 不能永久缓存(需要及时更新)
aws s3 cp frontend/dist/index.html s3://adap-frontend-<account_id>/index.html \
--cache-control "no-cache"
# 3. CloudFront 失效缓存(每次更新后执行)
aws cloudfront create-invalidation \
--distribution-id <CloudFront-Distribution-ID> \
--paths "/*"9.8 Cognito 用户初始化
9.8.1 创建管理员账号
USER_POOL_ID="us-east-1_XXXXXXXXX" # 从 CDK Output 获取
ADMIN_EMAIL="admin@example.com"
TEMP_PASSWORD="Admin@Temp123" # 首次登录后强制修改
# 创建用户
aws cognito-idp admin-create-user \
--user-pool-id "$USER_POOL_ID" \
--username "$ADMIN_EMAIL" \
--temporary-password "$TEMP_PASSWORD" \
--user-attributes \
Name=email,Value="$ADMIN_EMAIL" \
Name=email_verified,Value=true \
--message-action SUPPRESS
# 永久设置密码(跳过强制修改流程)
aws cognito-idp admin-set-user-password \
--user-pool-id "$USER_POOL_ID" \
--username "$ADMIN_EMAIL" \
--password "$TEMP_PASSWORD" \
--permanent9.8.2 验证登录(获取 JWT Token)
CLIENT_ID="xxxxxxxxxxxxxxxxxxxxxxxxxx" # 从 CDK Output 获取
aws cognito-idp initiate-auth \
--auth-flow USER_PASSWORD_AUTH \
--auth-parameters \
USERNAME="$ADMIN_EMAIL",PASSWORD="$TEMP_PASSWORD" \
--client-id "$CLIENT_ID" \
--query 'AuthenticationResult.IdToken' \
--output text9.9 SSM Parameter Store 配置
部分运行时参数(如 MySQL 凭证)通过 SSM 注入 Lambda,需要手动写入:
REGION="us-east-1"
# MySQL 默认连接参数(可被每个项目的请求覆盖)
aws ssm put-parameter \
--name "/adap/mysql/default_host" \
--value "your-mysql-host.rds.amazonaws.com" \
--type "SecureString" \
--region "$REGION"
aws ssm put-parameter \
--name "/adap/mysql/default_port" \
--value "3306" \
--type "String" \
--region "$REGION"
# (可选)存放 Bedrock Agent ID,避免硬编码
aws ssm put-parameter \
--name "/adap/bedrock/agent_id" \
--value "<AgentId>" \
--type "String" \
--region "$REGION"
aws ssm put-parameter \
--name "/adap/bedrock/agent_alias_id" \
--value "<AgentAliasId>" \
--type "String" \
--region "$REGION"9.10 部署验证
9.10.1 逐层验证
① 验证 S3 Bucket
aws s3 ls s3://adap-prototype-<account_id>/
# 预期:空 Bucket,无报错② 验证 DynamoDB 表
aws dynamodb list-tables --query 'TableNames[?contains(@, `adap`)]'
# 预期输出:
# ["adap-projects", "adap-events", "adap-hitl-responses", "adap-ws-connections"]③ 验证 Lambda 函数
aws lambda list-functions \
--query 'Functions[?starts_with(FunctionName, `adap`)].FunctionName' \
--output text
# 预期包含(不限于)以下函数:
# adap-agent-runner adap-project-create adap-project-query
# adap-ws-sender adap-cost-reporter adap-analytics-advisor
# adap-project-logs adap-warmup adap-ws-authorizer④ 验证 API Gateway
API_URL="https://<rest-api-id>.execute-api.us-east-1.amazonaws.com/prod"
# 健康检查(无需认证)
curl -s "$API_URL/health"
# 预期:{"status": "ok"}⑤ 验证 WebSocket
# 安装 wscat(Node.js WebSocket 测试工具)
npm install -g wscat
TOKEN=$(aws cognito-idp initiate-auth ... --query '...' --output text)
wscat -c "wss://<ws-api-id>.execute-api.us-east-1.amazonaws.com/prod?token=$TOKEN"
# 连接成功表示 WebSocket API 正常⑥ 验证 Step Functions
aws stepfunctions list-state-machines \
--query 'stateMachines[?contains(name, `adap`)].{name:name,arn:stateMachineArn}'
# 预期:adap-orchestration-pipeline9.10.2 端到端冒烟测试
# 激活虚拟环境
source .venv/bin/activate
# 执行冒烟测试(仅创建项目 + 验证状态变更)
python3 -m pytest tests/ -k "smoke" -v
# 执行完整 E2E 测试(需要真实 MySQL 数据源)
# 参考 docs/e2e-test-guide.md9.11 CDK 常用运维命令
# 查看 diff(对比当前部署和代码变化)
cdk diff ADAP-Compute
# 仅更新某个 Stack
cdk deploy ADAP-Compute --require-approval never
# 查看生成的 CloudFormation 模板
cdk synth ADAP-API > /tmp/adap-api-template.json
# 列出所有 Stack
cdk list
# 销毁所有资源(⚠️ 不可逆,谨慎使用!)
cdk destroy --all
# 注意:S3 Bucket 有 DeletionPolicy=Retain,需要手动删除数据9.12 更新 Lambda 代码
CDK 会在每次 cdk deploy 时自动重新打包 Lambda 代码。如果只是更新 Lambda 代码而不变更基础设施,可以单独更新:
# 打包并更新单个 Lambda(不需要完整 CDK deploy)
FUNCTION_NAME="adap-agent-runner"
zip -r /tmp/lambda.zip . -x "*.pyc" -x ".venv/*" -x "tests/*"
aws lambda update-function-code \
--function-name "$FUNCTION_NAME" \
--zip-file fileb:///tmp/lambda.zip推荐做法:通过
cdk deploy ADAP-Compute统一管理,避免代码和 CDK 状态不一致。
9.13 故障排查
9.13.1 常见错误及解决方案
| 错误 | 可能原因 | 解决方案 |
|---|---|---|
CREATE_FAILED: ADAP-AgentCore | Bedrock 模型访问未开通 | Bedrock Console → Model Access → 开通 Claude Sonnet/Opus |
| Lambda timeout | Bedrock Agent 响应慢 | 调大 Lambda timeout(当前 15min),或检查 Agent 状态 |
403 Forbidden (API) | JWT Token 失效 | 重新登录获取新 Token |
DynamoDB ProvisionedThroughputExceededException | 并发请求过多 | 检查表配置(当前按需模式,应自动扩容) |
ResourceNotFoundException (SSM) | SSM 参数未写入 | 按 9.9 节执行 SSM 参数写入 |
| Glue Job 失败 | S3 路径不存在 / IAM 权限不足 | 检查 Glue Job 日志:CloudWatch Logs → /aws-glue/jobs/error |
9.13.2 查看 Lambda 日志
# 实时查看最新 100 条日志
aws logs tail /aws/lambda/adap-agent-runner --follow --format short
# 查询特定时间段的错误日志
aws logs filter-log-events \
--log-group-name /aws/lambda/adap-agent-runner \
--start-time $(date -d '1 hour ago' +%s)000 \
--filter-pattern "ERROR"9.13.3 Step Functions 执行历史
STATE_MACHINE_ARN="arn:aws:states:us-east-1:<account_id>:stateMachine:adap-orchestration-pipeline"
# 查看最近 5 次执行
aws stepfunctions list-executions \
--state-machine-arn "$STATE_MACHINE_ARN" \
--max-results 5 \
--query 'executions[].{name:name,status:status,start:startDate}'
# 查看某次执行的详细步骤历史
EXECUTION_ARN="<execution-arn>"
aws stepfunctions get-execution-history \
--execution-arn "$EXECUTION_ARN" \
--query 'events[-20:].{type:type,timestamp:timestamp}' \
--output table9.14 环境分离(多套部署)
ADAP 通过 CDK Context 支持 dev / staging / prod 多套环境:
# 部署 dev 环境(使用不同 Stack 前缀)
cdk deploy --all \
--context env=dev \
--context stack_prefix=ADAP-Dev
# 部署 prod 环境
cdk deploy --all \
--context env=prod \
--context stack_prefix=ADAP-Prod \
--require-approval any-change # prod 环境任何变更都需要确认原型阶段:当前只维护单套环境(无前缀),部署在 us-east-1。
本章参考来源:infra/cdk/app.py、s3_stack.py、iam_stack.py、agentcore_stack.py、compute_stack.py、api_stack.py、auth_stack.py、orchestration_stack.py、scripts/deploy_frontend.sh