前两年用 AWS Lambda 搭配 API Gateway 使用是为了省钱,因为没有请求时不花钱。又由于是 Rest API, 所以实现部分用了 FastAPI 的装饰器,但不实际启动 FastAPI 的 Web 服务,Lambda 的 handler 方法根据 routeKey 手动映射到 FastAPI 的装饰方法。大概实现是def lambda_handler(event: dict, context):
当时也思考着能不能把 Lambda 的请求与 FastAPI 的 Web 服务桥接起来,却又不能真正启动一个 Web 服务,否则 Lambda 调用不能结束。比如说 AWS Lambda 收到请求时快速启动 FastAPI 服务,该服务绑定到 TCP 端口或 Socket 文件都行,然后 Lambda 请求代理到 FastAPI 服务,最后关闭 FastAPI 服务,但是想来都不那么容易实现。 Read More
fastapi_function = locate_fastapi_function(event['routeKey'])
return fastapi_function(<extract parameters from event>)
OAuth 是 Open Authorization 的缩写,是一种开放的可为 Web 或桌面应用进行用户验证和授权的协议。例如,在互联网上的许多应用,可不用额外注册帐户而采用第三方的帐户(Gmail, Apple Id 等)登陆并完成授权,这就有 OAuth 身影。
当我们提到 OAuth 的时候,常常会碰到 OAuth 1.0, OAuth 2.0, OpenID, 和 Auth0.- OAuth 1.0 于 2007 年 4 月 发布(OAuthCore 1.0),存在严重的安全漏洞,2009 年 6 月发布修正版(OAuthCore 1.0 Revision A). 较少使用了, 每个 token 加密,但不要求 HTTPS/TLS 协议
- OAuth 2.0 于 2012 年 10 月发布,它与 OAuth 1.0 互不兼容,目前多数平台都支持此版本,它强制使用 HTTPS/TLS 协议,更安全,相关的概念有 Access Token, Refresh Token, Bearer Token
- OpenID 侧重于 Authentication, 它是在 OAuth 上层用于鉴定用户是否可以登陆,OAuth 专注在 Authorization。与 OpenID 相对应的有 SAML(Security Assertion Markup Language)
- Auth0 是一个软件产品 -- 身份管理平台(Auth0 Authentication Platform - Identity Access Management),或者说是一套解决方案,这个缺德的命名纯粹是来搅浑水的。前面的 OAuth 1.0, OAuth 2.0 和 OpenID 都是协议规范,Okta 旗下的 Auth0 使用该名字抢了 OAuth 的光芒。
那 Amazon Cognito 是什么呢?它和 Auth0 类似,也是一个身份访问管理平台(Implement secure, frictionless customer identity and access management that scales),提供了用户的登陆验证,权限管理。背后的实现也是 OAuth 2.0, OIDC(OpenID Connection), 和 SAML。因此通过对 Cognito 的学习的另一个目的是由此了解 OAuth 2.0 协议的相关内容。 Read More
AWS SNS(Simple Notification Service) 以消息订阅,推送的方式对组件进行解藕。当有新消息发送到 SNS 主题中,SNS 会向当前所有的订阅者发送一个消息(广播),它本身不像 SQS 那样会存储消息,而只是一个纯粹的消息路由。SNS 消息可以订阅到 Amazon Kinesis Data Firehose, SQS, Lambda, Email, Email-JSON, HTTP, HTTPs, Platform application endpoint, 和 SMS。同邮件列表一样,订阅 SNS 消息也是需要确认的,不然 SNS 消息就可能恶意满天飞。
本文试验如何用 HTTP 端点订阅 SNS 消息,订阅确认,以及发送消息到 SNS 主题后消息推送到 HTTP 端点的细节,重点是了解订阅及被推送过来消息时的 HTTP 报文内容。SNS 的 HTTP 端点订阅需要一个公网上的 HTTP URL, 对 SNS 可见,所以我在本地测试时在家中路由器上加一个端口映射,对 Modem 获得的公有 IP 的 8080 端口访问转发到写此文用所用机器的 8080 端口上。
在本机需要在 8080 端口上启动一个 HTTP 服务以迎接 AWS 消息的到来,比如用 python 3 的话,简单运行命令python -m http.server 8080。如果不想在 API 代码中分析 HTTP 报文数据,只需打开 Wireshark(过滤条件 tcp.port=8080 && http) 抓取 8080 上的 HTTP 数据通信即可。在 API 代码中如何处理 HTTP 请求数据不是本文的重点。 Read More
基于 EC2 的 ECS 服务,要看看容器内的状态,一直以来都是先 SSM(Simple System Manager) 或 SSH 进到 EC2 实例,然后再docker exec -it <container-id> sh, 查看容器的控制台日志则用docker logs <container-id> [--follow]. 但是对使用 Farget 的 ECS 服务就无能为力了,因为找不到 SSM 或 SSH 的主体, 只能通过程序日志来大概了解容器内发生的事了。
Amazon 在 2021-03-15 推出了一个新的特性ECS Exec允许我们直接连接 Fargate 或 EC2 中的容器会话,见 Amazon ECS now allows you to run commands in a container running on Amazon EC2 or AWS Fargate. ECS Exec 支持 Container Agent 版本为 1.50.2 及以上的 ECS Optimized AMI 系列,和 Fargate Platform Version 1.4.0(Linux) 或 1.0.0(Windows) 及以上。
ECS Exec 的实现原理是以往在 EC2 实例上启动的 SSM Agent,也在容器内部启动一份,然后命令aws ecs execute-command直指容器本身。参考本人写过的一篇 AWS Session Manager 管理 EC2 实例,连接过程中唯一的不同就是容器中也运行了一个 SSM Agent, 所以这个容器也就无所谓是在 EC2 实例还是在 Fargate 中。
Read More
CSV 文件是纯文本的,对人阅读和编辑来说是最友好的描述表格数据的格式。虽然当前处理大数据时会用到 JSON, avro, parquet 等数据格式,但是在处理平面数据时 CSV 仍然被广泛使用。
S3 Select 能支持 CSV, JSON 和 parquet 格式数据的直接查询。在 AWS s3 控制台选择一个 CSV 文件,从右上的Object actions下拉选项上选择Query with S3 Select就能直接查询该文件的内容,而无须下载后打开文件。
如 S3 Select 查询语句SELECT * from s3object WHERE Name='Tom' LIMIT 5
如果 CSV 带 Header 的话,请勾选上Exclude the first line of CSV data。当然 S3 Select 查看任意的文本文件也行,只是把它当成一个不规则的 CSV 文件来对待。
S3 Select 只能针对单个 S3 文件查询,如果要对一组 CSV 文件同时进行查询的话就要用到 Athena。把相同 Schema 的一系列 CSV 文件放到 S3 的某一个目录中,我们可为它们创建一个 Athena 表,然后查询该 Athena 表就会从对应 S3 目录中扫描所有的 CSV 文件。 Read More
使用到 AWS 的 EC2 服务时,选择一个基础镜像后,要定制的话需要在 userdata 中写上一堆脚本。如果不想每次重复 userdata,或者要更快速的初始化一个虚拟机,就应该定制自己的 AMI,特别是在 Batch, ECS, EKS 选择的基础镜像还不方便使用 userdata。
定制一个 AMI, 我们可以用aws create-image命令,或是 HashiCorp 提供的 Packer(它不仅支持 AWS, 还能为 阿里云,Azure, Google 云,vmware, docker, Vagrant 等定制镜像)。而我们这里将要介绍的仍然是 HashiCorp 公司的 Terraform 并结合 AWS 的 EC2 Image Builder 服务来构建 AMI 镜像。
EC2 Image Builder 是 2019 年 12 月 1 日推出来的服务,见 Introducing EC2 Image Builder。
构建一个镜像的基本过程是选择一个基础镜像来启动一个实例,然后在该实例中做一系列的操作,再保存操作后的状态为自己的镜像。这和用 Dockerfile 定制自己的 Docker 镜像是类似的。 Read More
因为平常主要是使用 EC2 的 Linux 实例,所以之前写过的一篇关于 UserData 的日志 创建 AWS EC2 实例时 userdata 的一些知识 默认就是讲的有关 Linux 实例的 UserData。本文补充上 Windows 的 EC2 实例 UserData 的基本使用,参考自 AWS 官方文档 Run commands on your Windows instance at launch。
Windows 的 UserData 被谁执行,依据所选择 AMI 的不同有以下三种方式- EC2Launch v2: 最新方式,只是被当前预览版的 AMI 所支持,它支持 YAML 配置的脚本
- EC2Launch: 当前方式,Windows Server 2016 及更新版
- EC2Cofnig: 旧有方式, Windows Sever 2012 R2 及旧版本
通常在 Python 应用中简单的配置使用内置的 logging 是这样的1import logging 2 3logging_format = '%(asctime)s - %(levelname)s - %(module)s(%(funcName)s:%(lineno)d) - %(message)s' 4logging.basicConfig(level=logging.INFO, format=logging_format) 5 6logging.info('hello world')
假如文件名为 test.py, 用 python test.py 执行后输出2022-01-25 21:02:47,231 - INFO - test(<module>:6) - hello world
在 Lambda 中的现象
可是这同样的代码放到 AWS Lambda Python 代码中却不灵验了,logging.info()将得不到任何输出。 Read More
关于 AWS API Gateway V1, 写过一篇笔记 Lambda + API Gateway 创建需 API Key 验证的 API。 AWS 又推出了 API Gateway V2(服务管理/理解层面), 它同样可以用来作 HTTP-PROXY 调用 REST API, WebSocket; AWS-PROXY 调用 Lambda, 还能直接调用 AWS 的其他服务,如 StepFunction, SQS 等。
但是 API Gateway V2 把 V1 中的 API Key 验证功能去掉了,这有点为了赚钱耍无赖了,先前是 API Key 验证不过时不会调用 Lambda, 现在可用 Lambda 来验证 API 调用,也就是不管 API Key 对与不对,都会去调用 Lambda 从而实现从你的帐户上扣钱的功能。
在 V1 中创建整套服务的过程基本是 Resource -> Method -> Integration -> Stage。而在 V2 中的过程是 Integration -> Route -> Stage, 把 Resource 和 Method 合而为一,比如 Route Key 写成
GET /users.下面照旧以 Terraform 的方式来叙述使用 API Gateway V2 如何实现 HTTP 代理,调用 Lambda, 及使用 AWS 服务(以 SQS 为例),或与 VPC 内部的服务集成。首先是一个基本的框架,含 API 本身和 Stage Read More

本人在 AWS 上建立基础架构的时候倾向于用 Terraform, 而不是 AWS 自家的 CloudFormation。倒不是因为 Terraform 支持多种类型的 Provider,而是它能模块化,不同项目共享 AWS 资源时也更方便。而使用 CloudFormation 的话,一不小心就会写出一个超大的 YAML 文件来,要使用共同的 AWS 资源时,谁来创建是个不小的问题。CloudFormation 稍值得称道的地方也就是有一个可视化的 Stack,但把 Terraform 执行的 state 存到 S3 也不差。使用 Terraform 还有一个最享受的地方就是它的官方文档组织的非常清晰。
出品 Terraform 的公司 HashiCorp 秉持着 Infrastructure as Code,近日在忙着 IPO, 估值在 $13B, Ticker 将为 HCP(该链接直接可用时便以上市),介时也值得关注一下。扯远了,回到日常使用 Terraform 的变量上来。
本文直接参考自 Terraform 官网的 Input Variables。不管英文好不好都应该读原文去理解 Terraform 变量的详细使用方法。这里主要是了解各种输入变量的方式,以及验证一下当同时用多种方式输入重复的变量时,以谁为最终的结果。 Read More