检查是否在aws实例上运行了python脚本

时间:2015-04-11 01:39:33

标签: python amazon-web-services boto

我尝试设置python记录器,以便在记录错误时发送错误电子邮件,如果实例有标记集。然后我很快就遇到了不在aws上的本地开发计算机的问题。有没有一种简单快捷的方法来检查脚本是否在aws上运行?

我正在加载实例数据:

import boto.utils
from boto.ec2.connection import EC2Connection
metadata = boto.utils.get_instance_metadata()
conn = EC2Connection()
instance = conn.get_only_instances(instance_ids=metadata['instance-id'])[0]

我当然可以在get_instance_metadata上使用超时,但是现在有一段时间的紧张关系让开发人员等待,而不是在生产中不发送错误电子邮件的可能性。

有人能想到一个很好的解决方案吗?

4 个答案:

答案 0 :(得分:3)

AWS实例具有元数据,因此您可以调用元数据服务并获得响应,如果响应有效,则您是@ AWS,否则您不是。

例如:

import urllib2
meta = 'http://169.254.169.254/latest/meta-data/ami-id'
req = urllib2.Request(meta)
try:
    response = urllib2.urlopen(req).read()
    if 'ami' in response:
        _msg = 'I am in AWS running on {}'.format(response)
    else:
        _msg = 'I am in dev - no AWS AMI'
except Exception as nometa:
    _msg = 'no metadata, not in AWS'

print _msg

这只是一个刺 - 有可能更好的检查,但这一个会让你感觉它,你可以在你认为合适的情况下改进它。如果您在本地使用OpenStack或其他云服务,您当然会得到元数据响应,因此您必须相应地调整支票...

(如果您正在使用某种启动工具或管理员,如厨师,木偶,本土等,您也可以使用cloud-init的东西。如果在AWS中将/ ec2文件放在文件系统中,或者更好但如果本地放弃盒子上的/ DEV)

答案 1 :(得分:1)

我认为这不是一个真正的问题。 EC2(反过来又是boto)不关心或了解您在服务器上运行的脚本。

如果您的脚本有特定的签名 - 例如听一个端口 - 这将是最好的检查方式,但不好意思,你可以在操作系统中寻找它的签名 - 它的过程。

使用子流程模块和您的preferred bash magic to check if it's running

command = ["ssh", "{user}@{server}", "pgrep", "-fl", "{scriptname}"]
try:
    is_running = bool(subprocess.check_output(command))
except subprocess.CalledProcessError:
    log.exception("Checking for script failed")
    is_running = False

答案 2 :(得分:1)

与@cgseller类似,假设使用python3,则可以执行以下操作:

from urllib.request import urlopen

def is_ec2_instance():
    """Check if an instance is running on AWS."""
    result = False
    meta = 'http://169.254.169.254/latest/meta-data/public-ipv4'
    try:
        result = urlopen(meta).status == 200
    except ConnectionError:
        return result
    return result

答案 3 :(得分:1)

或者,您可以检查您的环境是否包含任何AWS environmental variables

is_aws = True if os.environ.get("AWS_DEFAULT_REGION") else False

我选择检查我的用户名是否为ec2实例:(不是一个很好的解决方案,但是可以工作)

my_user = os.environ.get("USER")
is_aws = True if "ec2" in my_user else False