云简历挑战:CI/CD、Python 与安全惊魂
Source: Dev.to
请提供您想要翻译的完整文本(除代码块、URL 和标题之外的内容),我将把它翻译成简体中文并保持原有的 Markdown 格式。谢谢!
介绍
理论知识是基础,但工程能力是通过实践来建立的。
我意识到,仅仅了解 S3、Lambda 和 DynamoDB 等服务的理论是不够的——我想展示我能够将它们编排成一个安全、自动化、生产级别的应用。
Cloud Resume Challenge(由 Forrest Brazeal 创建)是弥合架构概念与真实世界 DevOps 实施之间差距的完美框架。
以下是我如何构建无服务器简历网站、使用 GitHub Actions 自动化部署以及在此过程中解决工程难题的过程。
Source: …
架构
项目需求很简单:“在线托管简历。”
我实现的架构完全基于云工程:
| 层 | 技术 |
|---|---|
| Frontend | HTML/CSS 托管在 S3,通过 CloudFront(HTTPS)进行全球缓存加速 |
| Backend | AWS Lambda(Python)处理 API 请求 |
| Database | DynamoDB(NoSQL)用于存储访客计数 |
| Infrastructure | 使用 GitHub Actions 的全自动 CI/CD 流水线 |
Level 1: 前端粘合层 (JavaScript)
网站本身是静态的 HTML/CSS,但要实现动态效果就需要 JavaScript。我编写了一个脚本,从我的 API Gateway 触发器获取访客计数。
最大的问题是 CORS(跨域资源共享)。我的 JavaScript 在 aminetraibi.com 上运行时,尝试访问 AWS Lambda 的 URL,浏览器因安全原因阻止了请求。
解决方案: 配置 Python Lambda 函数返回头部 Access-Control-Allow-Origin: *,使浏览器接受响应。
// Fetching the view count
fetch(apiUrl)
.then(response => response.json())
.then(data => {
document.getElementById('counter').innerText = data.views;
});Level 2: The Backend Logic (Python & DynamoDB)
我需要一个原子计数器,每次页面加载时递增一次。于是我编写了一个使用 boto3 与 DynamoDB 交互的 Python 脚本。
一个具体的挑战是处理 DynamoDB 的保留字。由于 views 是保留关键字,我使用 ExpressionAttributeNames 对其进行正确映射。
# Atomic update using UpdateExpression
response = table.update_item(
Key={'id': 'page_view'},
UpdateExpression='SET #v = #v + :val',
ExpressionAttributeNames={'#v': 'views'},
ExpressionAttributeValues={':val': 1},
ReturnValues='UPDATED_NEW'
)第3层:安全教训 🚨
这是我学习旅程中最关键的部分。
我在机密管理上学到了惨痛的教训。在构建初期,我不小心将凭证提交到了代码库。

我立刻识别了风险,撤销了 IAM 中的密钥,并迁移到 GitHub Secrets。
关键要点
- 使用专用的 IAM 用户,并赋予 最小权限。
- 仅在运行时通过 CI/CD 流水线注入密钥。
- 绝不要在源码控制中存储机密。
第四层:自动化测试与模拟
该挑战需要 Python 单元测试,这实际上是最难的部分之一。
当我在本地运行测试时,boto3 会尝试连接到真实的 DynamoDB。 在 CI/CD 环境中,我不希望测试依赖于网络连接或实时数据库权限。
解决方案:模拟
我使用 unittest.mock 库来模拟 AWS 服务。 通过对 DynamoDB 表资源进行 mock,我可以在不进行任何实际 API 调用的情况下测试函数逻辑。

# Using MagicMock to fake the database response
mock_table = MagicMock()
mock_table.update_item.return_value = {'Attributes': {'views': 123}}
lambda_function.table = mock_table这使得流水线保持快速、稳健,并且在测试期间无需承担 AWS 成本。
Level 5: CI/CD(“绿色勾号”)
最终目标是摆脱 AWS 控制台(“ClickOps”)并采用正式的 DevOps 实践。
我构建了两个独立的 GitHub Actions 工作流:
| 工作流 | 触发条件 | 操作 |
|---|---|---|
| 前端流水线 | HTML/CSS 变更 | 同步到 S3,刷新 CloudFront 缓存 |
| 后端流水线 | Python 代码变更 | 运行单元测试,打包代码,更新 Lambda 函数 |
现在,只需一次 git push 到 main,即可自动更新整个应用。

结论与后续步骤
本项目迫使我触及技术栈的每一层:网络(DNS/Route53)、安全(IAM)、计算(Lambda)、数据库(DynamoDB)以及前端逻辑(JavaScript)。
我的下一个里程碑是继续在此基础上构建——具体来说,将更深入地使用 Terraform 实现基础设施即代码,并探索使用 Docker/ECS 进行容器化。
如果你在寻找一位通过实践学习、敢于拆除并修复问题的云工程师——欢迎联系我!
线上站点: https://aminetraibi.com
GitHub 仓库: https://github.com/AmineTra/cloud-resume-challenge

