在 AWS Fargate 中运行的容器任务默认处于某个可用区内,任务元数据只暴露可用区名称(例如 us-east-1a),而不会直接给出 AZ ID(例如 use1-az1)。AZ ID 是区域下可用区的唯一逻辑标识,跨账号保持不变,在构建多账号容灾或对齐故障域时往往需要它。我们可以通过任务元数据拿到可用区名称,再调用 EC2 的 DescribeAvailabilityZones 接口完成名称到 AZ ID 的映射。

实现思路
Fargate 任务开启元数据版本 4 后,可以从 169.254.170.2/v4/metadata 读取自身可用区名称。拿到名称后,使用 AWS SDK 调用 EC2 的 DescribeAvailabilityZones 接口,返回结果中包含 ZoneName 与 ZoneId 的对应关系,筛选即可。
所需权限
- ecs:DescribeTasks(若需任务信息)
- ec2:DescribeAvailabilityZones(核心权限)
Python 示例代码
以下代码在 Fargate 任务内执行,先读取元数据再查询 AZ ID:
import requests
import boto3
# 从 Fargate 元数据服务获取可用区名称
meta_url = 'http://169.254.170.2/v4/metadata'
resp = requests.get(meta_url, timeout=2)
zone_name = resp.json()['AvailabilityZone']
# 调用 EC2 接口获取可用区列表
ec2 = boto3.client('ec2')
zones = ec2.describe_availability_zones()['AvailabilityZones']
# 匹配名称对应的 AZ ID
az_id = None
for z in zones:
if z['ZoneName'] == zone_name:
az_id = z['ZoneId']
break
print('ZoneName:', zone_name)
print('AZ ID:', az_id)
使用命令行快速获取
如果任务内已安装 AWS CLI 且拥有权限,也可直接执行:
# 获取当前任务可用区名称(需元数据支持) ZONE_NAME=$(curl -s http://169.254.170.2/v4/metadata | python3 -c 'import sys,json;print(json.load(sys.stdin)["AvailabilityZone"])') # 查询 AZ ID aws ec2 describe-availability-zones --query "AvailabilityZones[?ZoneName==`$ZONE_NAME`].ZoneId" --output text
注意事项
元数据服务地址 169.254.170.2 仅在任务网络模式为 awsvpc 时可用,且需在任务定义中设置 MetadataOptions 为 v4。若使用桥接网络则无法使用该地址。此外,EC2 接口返回的 AZ ID 与控制台显示一致,不会因为任务重启而变化。
在编写自动化脚本时,建议将 AZ ID 映射结果缓存到环境变量或本地文件,避免每次执行都发起接口调用。
常见错误
| 现象 | 原因 |
|---|---|
| 连接 169.254.170.2 超时 | 未开启 v4 元数据或网络模式不对 |
| 权限拒绝 | 任务角色缺少 ec2:DescribeAvailabilityZones |
通过上述方式,Fargate 任务可以在运行期稳定地将可用区名称转换为 AZ ID,满足跨账号对齐与自动化运维需要。
AWS_Fargate可用区名称AZ_ID修改时间:2026-07-28 05:09:20