按我说的做,不按我的做:在不破坏基础架构的情况下获取EC2实例名称

Python代码段逐步指南

我第一次将EC2实例名称记录到PagerDutyAirbrake的尝试破坏了我们的大多数基础架构。 我无法解释未发布的AWS速率限制,并且当意外数量的错误导致我的代码达到这些速率限制时,错误处理不足会导致在异常记录器中引发错误时发生无限循环。

我希望本教程可以使您免于头痛。 我将向您介绍如何使用boto3 Python客户端从该实例访问正在运行的EC2实例的名称,并一路包括警告和陷阱,以帮助您避免一些错误。

先决条件

  • Boto3 。 本教程假定您熟悉使用AWS的boto3 Python客户端,并且已按照AWS的说明配置AWS凭证。
  • Requests ,一个Python HTTP库。

获取实例ID和区域

boto3实例资源可访问有关实例的大多数信息。 要创建该资源,我们首先需要检索实例ID和实例区域。

AWS通过URL http://169.254.169.254提供了实例元数据和用户数据 ,您可以从任何运行的EC2实例中请求。 特别是,我们对实例身份文档感兴趣,该文档可从http://169.254.169.254/latest/dynamic/instance-identity/document访问。

import requests
r = requests.get("http://169.254.169.254/latest/dynamic/instance-identity/document")
response_json = r.json()
region = response_json.get('region')
instance_id = response_json.get('instanceId')

如果您不熟悉requests库,建议您检出“ 响应状态代码” ,尤其是raise_for_status函数,作为错误处理的起点。

获取实例资源

然后,我们可以使用实例ID和区域来检索boto3实例资源

import boto3
ec2 = boto3.resource('ec2', region_name=region)
instance = ec2.Instance(instance_id)
在将它们传递给boto3之前验证regioninstance_id

boto3错误处理的第一步是捕获同时在botocore.exceptions包中找到的ClientErrorBotoCoreError

以我的经验, boto3客户端对无效或“ None区域或实例ID的错误处理非常混乱。 除了上述错误外, None一个字段中的None值都将引发Python内置的ValueError 。 如果region && instance_id为false,我建议您不要尝试使用boto3客户端。

取得名字

实例的“名称”实际上是带有键“名称”的实例标签。 您可以从实例资源中检索标签,并过滤Name标签。

tags = instance.tags or []
names = [tag.get('Value') for tag in tags if tag.get('Key') == 'Name']
name = names[0] if names else None
由于属性是延迟加载的,因此某些无效的实例ID会在此处引发错误

根据boto3文档 ,资源属性是延迟加载的,这意味着在首次访问该属性时会进行第一个API调用。 这意味着,虽然在创建ec2.Instance资源时会验证None或空字符串,但将使用第一个DescribeInstances调用在此处验证类型正确但值错误的非空字符串ID。 为了解决这个问题,您将尝试捕获上一节中的botocore.exceptions异常。

知道了!

在关于EC2陷阱和限制的 AWS开放指南部分中:

❗如果EC2 API本身是基础架构的关键依赖项(例如,用于自动服务器更换,自定义扩展算法等)并且您正在大规模运行或进行许多EC2 API调用,请确保您了解它们何时可能失败(对它的调用受到速率的限制,并且不会发布限制,并且可能会更改),并针对这种可能性进行编码和测试。

boto3客户端使用DescribeInstances API调用加载有关实例的信息。 例如,如果您每次登录错误时都进行此API调用以检索实例名称,则可以轻松达到DescribeInstances速率限制。

除了上述错误处理之外,您还需要合并对AWS API的调用,以避免达到未发布的AWS速率限制。 我们的解决方案是在API服务器启动时一次获取实例名称,并将结果缓存在全局数据结构中。 现在,我们无需在每次需要记录错误时都调用EC2 API,而仅在将新代码部署到计算机时才调用一次。

放在一起

这是最终的get_instance_name函数的外观示例。

From: https://hackernoon.com/do-as-i-say-not-as-i-do-get-your-ec2-instance-name-without-breaking-your-infrastructure-1da4a0963af0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值