云简历挑战:CI/CD、Python 与安全惊魂

发布: (2026年3月14日 GMT+8 07:11)
6 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您想要翻译的完整文本(除代码块、URL 和标题之外的内容),我将把它翻译成简体中文并保持原有的 Markdown 格式。谢谢!

介绍

理论知识是基础,但工程能力是通过实践来建立的。

我意识到,仅仅了解 S3、Lambda 和 DynamoDB 等服务的理论是不够的——我想展示我能够将它们编排成一个安全、自动化、生产级别的应用。

Cloud Resume Challenge(由 Forrest Brazeal 创建)是弥合架构概念与真实世界 DevOps 实施之间差距的完美框架。

Challenge Accepted

以下是我如何构建无服务器简历网站、使用 GitHub Actions 自动化部署以及在此过程中解决工程难题的过程。

Source:

架构

项目需求很简单:“在线托管简历。”
我实现的架构完全基于云工程:

技术
FrontendHTML/CSS 托管在 S3,通过 CloudFront(HTTPS)进行全球缓存加速
BackendAWS Lambda(Python)处理 API 请求
DatabaseDynamoDB(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层:安全教训 🚨

这是我学习旅程中最关键的部分。

我在机密管理上学到了惨痛的教训。在构建初期,我不小心将凭证提交到了代码库。

Sweating

我立刻识别了风险,撤销了 IAM 中的密钥,并迁移到 GitHub Secrets

关键要点

  • 使用专用的 IAM 用户,并赋予 最小权限
  • 仅在运行时通过 CI/CD 流水线注入密钥。
  • 绝不要在源码控制中存储机密。

第四层:自动化测试与模拟

该挑战需要 Python 单元测试,这实际上是最难的部分之一。

当我在本地运行测试时,boto3 会尝试连接到真实的 DynamoDB。 在 CI/CD 环境中,我不希望测试依赖于网络连接或实时数据库权限。

解决方案:模拟

我使用 unittest.mock 库来模拟 AWS 服务。 通过对 DynamoDB 表资源进行 mock,我可以在不进行任何实际 API 调用的情况下测试函数逻辑。

Hackerman

# 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 pushmain,即可自动更新整个应用。

Success

结论与后续步骤

本项目迫使我触及技术栈的每一层:网络(DNS/Route53)、安全(IAM)、计算(Lambda)、数据库(DynamoDB)以及前端逻辑(JavaScript)。

我的下一个里程碑是继续在此基础上构建——具体来说,将更深入地使用 Terraform 实现基础设施即代码,并探索使用 Docker/ECS 进行容器化。

如果你在寻找一位通过实践学习、敢于拆除并修复问题的云工程师——欢迎联系我!

线上站点: https://aminetraibi.com
GitHub 仓库: https://github.com/AmineTra/cloud-resume-challenge

成功

0 浏览
Back to Blog

相关文章

阅读更多 »