【问题标题】:boto3 searching unused security groupsboto3 搜索未使用的安全组
【发布时间】:2017-04-29 23:46:29
【问题描述】:

我正在使用 AWS Python SDK Boto3,我想知道哪些安全组未使用。用 boto2 我做到了,但我不知道如何用 boto3 做同样的事情。

from boto.ec2.connection import EC2Connection
from boto.ec2.regioninfo import RegionInfo
import boto.sns
import sys
import logging
from security_groups_config import config

# Get settings from config.py
aws_access_key = config['aws_access_key']
aws_secret_key = config['aws_secret_key']    
ec2_region_name = config['ec2_region_name']
ec2_region_endpoint = config['ec2_region_endpoint']

region = RegionInfo(name=ec2_region_name, endpoint=ec2_region_endpoint)

if aws_access_key:
    conn = EC2Connection(aws_access_key, aws_secret_key, region=region)
else:
    conn = EC2Connection(region=region)

sgs = conn.get_all_security_groups()

## Searching unused SG if the instances number is 0
def search_unused_sg(event, context):
    for sg in sgs:
        print sg.name, len(sg.instances())

【问题讨论】:

  • 在boto3中,你可以从describe_instancesdescribe_security_groups收集信息,将两个安全组名称值存储到各自的集合中,然后进行推断。
  • 是的,当然,但我想知道是否有提供此信息的函数。在boto2中有get_all_security_groups()
  • 不幸的是,没有。 Boto3 是一个重写 API,它有很好的文档记录和良好的维护,与 boto2 相比不那么令人惊讶。
  • Boto3 有很多强大的方法来得到你想要的。检查我的答案并根据您的需要进行调整。
  • 这需要找到所有使用安全组(ec2s、负载均衡器、lambda 等等?)的答案。实际上,boto3 需要一种调用方式来查找对给定安全组的所有引用。

标签: python amazon-web-services amazon-ec2 aws-sdk boto3


【解决方案1】:

首先,我建议你重新审视一下 boto3 是如何处理凭证的。更好地使用通用 AWS 凭证文件,因此在将来需要时,您可以切换到 IAM 角色基础凭证或 AWS STS,而无需更改您的代码。

import boto3 
# You should use the credential profile file 
ec2 = boto3.client("ec2")

# In boto3, if you have more than 1000 entries, you need to handle the pagination
# using the NextToken parameter, which is not shown here.

all_instances = ec2.describe_instances() 
all_sg = ec2.describe_security_groups()

instance_sg_set = set()
sg_set = set()

for reservation in all_instances["Reservations"] :
  for instance in reservation["Instances"]: 
    for sg in instance["SecurityGroups"]:
      instance_sg_set.add(sg["GroupName"]) 


for security_group in all_sg["SecurityGroups"] :
  sg_set.add(security_group ["GroupName"])

idle_sg = sg_set - instance_sg_set

注意:代码未经测试。请根据需要进行调试。

【讨论】:

  • 为什么人们还要投票呢? AttributeError:“ec2.ServiceResource”对象没有属性“describe_instances”
  • @buildmaestro 检查您自己的代码。上面的代码使用boto3.clent("ec2"),而不是boto3.resource("ec2")
  • @buildmaestro 请将您的代码作为一个新问题发布以证明这一点。 AttributeError: 'ec2.ServiceResource' object has no attribute 'describe_instances' 是 boto3.resource 抛出的异常。检查您的代码,看看您是否不小心将对象重新声明为 ServiceResource
【解决方案2】:

使用 Boto3 和 Python 的列表推导和集合的强大功能,只需 7 行代码即可获得所需的内容:

import boto3

ec2 = boto3.resource('ec2') #You have to change this line based on how you pass AWS credentials and AWS config

sgs = list(ec2.security_groups.all())
insts = list(ec2.instances.all())

all_sgs = set([sg.group_name for sg in sgs])
all_inst_sgs = set([sg['GroupName'] for inst in insts for sg in inst.security_groups])
unused_sgs = all_sgs - all_inst_sgs

调试信息

print 'Total SGs:', len(all_sgs)
print 'SGS attached to instances:', len(all_inst_sgs)
print 'Orphaned SGs:', len(unused_sgs)
print 'Unattached SG names:', unused_sgs

输出

Total SGs: 289
SGS attached to instances: 129
Orphaned SGs: 160
Unattached SG names: set(['mysg', '...

【讨论】:

  • 感谢您的解决方案,但它引发了错误,因为{ "stackTrace": [ [ "/var/task/lambda_function.py", 81, "unused_sg", "sgs = list(ec2.security_groups.all())" ] ], "errorType": "AttributeError", "errorMessage": "'EC2' object has no attribute 'security_groups'" }
  • @Robert,你确定你在使用ec2 = boto3.resource('ec2') 吗?
  • 我正在创建客户端:client = boto3.client( 'ec2', aws_access_key_id = AWS_ACCESS_KEY, aws_secret_access_key = AWS_SECRET_KEY , region_name = REGION_NAME )
  • @Robert, client 没有那个方法。我的代码使用resource
  • 但在创建或请求 ec2 资源之前,我是否需要通过凭证配置。 client.resource('ec2'...) 不返回同一个对象?
【解决方案3】:

注意:如果您有处于空状态(count=0)的 ASG(Autoscaling group),当 ASG 开始添加安全组时,它将采用孤立安全组。请记住,您还需要检查 ASG 安全组

【讨论】:

    【解决方案4】:

    我使用了另一种方法。如果我们跳过凭证讨论并回到主要问题“boto3 搜索未使用的安全组”,这里有一个选项: 你去枚举资源,在我的例子中是网络接口,因为如果你考虑一下,安全组必须与资源相关联才能使用。 我的例子:

    client = boto3.client('ec2', region_name=region, aws_access_key_id=newsession_id, aws_secret_access_key=newsession_key, aws_session_token=newsession_token)
    response = client.describe_network_interfaces()
    for i in response["NetworkInterfaces"]:
        #Check if the security group is attached
        if 'Attachment' in i and i['Attachment']['Status'] == 'attached':
            #Create a list with the attached SGs
            groups = [g['GroupId'] for g in i['Groups']]
    

    我使用了网络接口资源,因为我需要为帐户获取公共 IP。

    【讨论】:

      猜你喜欢
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 2016-04-11
      • 2017-03-08
      • 2017-04-29
      • 2016-04-08
      • 1970-01-01
      相关资源
      最近更新 更多