You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EC2实例未启用元数据标签时,如何用Python获取实例标签?

在未启用元数据标签的EC2实例内用Python获取特定标签的方法

当EC2实例未启用「Tags allowed in metadata」选项时,无法通过元数据直接读取标签,但可以通过调用AWS EC2 API的方式获取,核心步骤如下:

1. 给EC2实例关联的IAM角色添加权限

需要确保实例关联的IAM角色拥有ec2:DescribeInstances权限,否则调用API时会触发权限错误。

创建或更新IAM策略,添加以下内容:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        }
    ]
}

将该策略附加到EC2实例的IAM角色上。

2. 用Python代码实现标签查询

通过元数据获取当前实例ID(该操作不受标签权限限制),再调用EC2 API查询实例的标签信息:

基础版(IMDSv1)

import boto3
import requests

def get_current_instance_id():
    # 从元数据获取实例ID,此路径无需启用标签权限
    try:
        resp = requests.get("http://169.254.169.254/latest/meta-data/instance-id", timeout=2)
        resp.raise_for_status()
        return resp.text
    except requests.exceptions.RequestException as e:
        print(f"获取实例ID失败: {e}")
        return None

def get_specific_tag(tag_key):
    instance_id = get_current_instance_id()
    if not instance_id:
        return None
    
    ec2_client = boto3.client("ec2")
    try:
        resp = ec2_client.describe_instances(InstanceIds=[instance_id])
        # 解析响应中的标签
        for reservation in resp["Reservations"]:
            for instance in reservation["Instances"]:
                for tag in instance.get("Tags", []):
                    if tag["Key"] == tag_key:
                        return tag["Value"]
        return f"未找到标签: {tag_key}"
    except boto3.exceptions.Boto3Error as e:
        print(f"查询标签失败: {e}")
        return None

# 示例:获取Name标签的值
name_tag_value = get_specific_tag("Name")
print(f"Name标签值: {name_tag_value}")

适配IMDSv2的版本

如果实例启用了IMDSv2,需要先获取元数据令牌再请求实例ID,修改get_current_instance_id函数即可:

def get_current_instance_id():
    try:
        # 获取IMDSv2令牌
        token_resp = requests.put(
            "http://169.254.169.254/latest/api/token",
            headers={"X-aws-ec2-metadata-token-ttl-seconds": "21600"},
            timeout=2
        )
        token_resp.raise_for_status()
        token = token_resp.text
        
        # 携带令牌请求实例ID
        id_resp = requests.get(
            "http://169.254.169.254/latest/meta-data/instance-id",
            headers={"X-aws-ec2-metadata-token": token},
            timeout=2
        )
        id_resp.raise_for_status()
        return id_resp.text
    except requests.exceptions.RequestException as e:
        print(f"获取实例ID失败: {e}")
        return None

关键说明

  • 此方法不依赖元数据中的标签配置,仅需EC2实例能正常访问EC2 API(默认VPC实例通常无需额外配置网络)。
  • 必须确保IAM角色权限正确,否则会返回AccessDenied错误。

内容的提问来源于stack exchange,提问作者Ankan Das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:39:51