如果您对IAC的经验略有扩展,更具体地在Terraform上,您可能会遇到以下问题:
当我们试图删除放置在VPC中的lambda函数时,这通常会发生。这样做的原因是,删除安全组被一个或多个网络接口暂时阻止。
在即将到来的线路中,我们将看到当似乎无法删除我们的安全组时,我们该如何处理案件。我们将讨论导致这些障碍的原因,以及我们如何优雅地处理它们。
为什么安全小组无法删除?
安全组是一个stateful firewall,其目的是控制VPC中资源可以允许哪种入站和出站流量。安全组始终分配给ENI(Elastic network interface)。这是事实,即使AWS Consol使我们似乎似乎将安全组分配给各种资源,例如EC2实例,负载平衡器,Lambda功能,数据库等。将其放置在我们的VPC中,将向其分配安全组。 ENIS将由我们的资源使用,因此AWS CONSOL将显示它就像将安全组分配给资源本身一样。
在以下情况下将无法删除安全组:
- 它被分配给一个或多个ENIS:可以将安全组分配给一个或多个ENIS,此外,ENI可以将up to 5 security groups assigned与IT分配(软限制,通过询问AWS支持,我们可以将此限制提高到16)。如果将一个安全组附加到至少一个ENI上,我们需要摆脱ENI或尝试从其中解放安全组,以使SG能够被删除。
- 它由安全组规则引用:安全组可以根据规则允许入站/出站流量。我们可以将另一个SG用作规则的源/目的地。如果另一个SG的规则引用了SG,则不能在删除/更改规则之前将其删除。
- SG是VPC中的默认SG:每个VPC创建时都会自动获取安全组。我们只有在删除VPC时才能摆脱此安全组。
- 我们没有删除SG的特权:如果我们使用的角色没有必要的许可进行
DeleteSecurityGroup
操作。
安全组被分配给ENI
如果我们将安全组分配给AWS资源(EC2,Lambda,RDS数据库,VPC端点等),则将始终将安全组分配给网络接口(ENI)。 AWS控制台在某种程度上具有误导性,因为它显示安全组已分配给资源本身,但事实并非如此。由于所有这些ENI供应和SG分配都发生在后台,因此在大多数情况下,我们不允许对ENI和安全组分配进行审查。有时,当我们进行资源提供时,这可能会使引擎盖下发生的事情混淆,所以让我们看看一些示例以了解AWS在做什么:
- EC2实例:当我们提供EC2实例时,这将自动收到默认的ENI。该ENI不能与实例分离,因此无法将其删除。 AWS期望我们在创建时将安全组分配为实例。如果我们要删除此安全组,则必须将另一个安全组分配给我们的EC2实例。我们可以通过进入ENI控制台并将安全组直接分配给ENI,或者转到EC2实例并在安全设置中更改安全组。 来做到这一点。
EC2实例还可以附带次要恩利。这些ENIS是独立配置的,因此我们可以从ENI控制台更改为他们分配的安全组。
-
lambda函数:lambda函数需要一个安全组,以防我们希望它们与VPC具有连接性。如果我们选择它,AWS将在我们指定的每个子网中放置一个ENI,将将安全组分配给每个配置的ENI。如果我们修改了lambda函数配置,我们可以自由更改安全组,但是我们不能直接对ENIS进行调整。如果我们决定删除我们的功能,则将自动删除ENIS。这种去除通常会延迟10-15分钟,从本质上暂时卡住。我们只需要等到删除最终完成。如果我们将Terraform IAC用于基础架构,这可能会很烦人,因为它将尝试一遍又一遍地删除安全组(请参阅本文开头的GIF)。如果不会及时发生这种删除,我们很容易以不一致的地下状态。我们能做的就是拭目以待,并希望Terraform不会暂时。
-
ECS Fargate任务:对于ECS任务,任务中的每个容器都可以具有ENI,具体取决于网络设置。这些eNIS由AWS管理,我们不能真正对其进行脾气。我们可以更改任务设置上的安全组。如果我们决定删除任务,则将容器退役时,将自动删除ENIS。在大多数情况下,这种情况会立即发生,但是在极少数情况下,我们可以设法最终遇到卡住ENI。如果发生这种情况,我们可以尝试从AWS控制台手动删除ENI。如果这是不成功的,我们必须写信给AWS支持。
-
VPC端点:VPC端点对我们的基础架构具有多个好处。我们可以拥有到达AWS服务(例如S3,DynamoDB等)的终点,而无需与公共Internet具有外向连接,或者我们可以与与另一个AWS帐户完全不同的实例有一对一的连接。限制是PrivateLink(为VPC端点提供动力的服务)在可用性区域级别工作。这意味着我们的连接子网必须与暴露端点的另一个子网相同。在ENIS和安全组方面,这个想法与其他资源相同。我们在每个子网中获得一个eni,其中我们放置了一个端点。此ENI由AWS管理。如果我们转到VPC端点设置,我们可以修改安全组。如果我们摆脱了VPC端点,将删除ENI,并将自动拆除安全组。
我们可以在这里注意到一种模式。如果我们采用任何需要访问VPC的AWS管理的资源,我们最终将获得类似的网络设置,并将ENI安置和安全组分配给ENI。重要的是要知道以下内容:
- 安全组被分配给网络接口。在大多数情况下,没有安全组就无法存在
- 在大多数情况下,在我们提供资源时,ENI被放置在我们的VPC中。在配置时,我们必须将安全组分配给ENI
- 通常,我们不能对ENI进行调整,这意味着我们不能直接与安全组取消缔合。如果我们修改使用ENI 的AWS服务,我们可以更改安全组
- 如果我们要删除一个安全组,我们必须要任一:
- 删除使用我们的安全组分配的ENI的AWS服务;
- 修改使用ENI的服务,因此通过为其分配另一个安全组并删除我们要删除的服务。
什么是使用我随机命名的安全组?
我们最终决定删除一个带有随机时髦名称的安全组,我们不记得创建了。我们怀疑某些资源使用它,但是我们不确定哪些是哪些。在AWS控制台中,我们导航到安全组,然后按Delete security groups
按钮。我们对此受到欢迎:
控制台告诉我们,我们无法删除安全组,因为它由一个或多个网络接口使用。它还可以方便地为我们提供了所有这些网络接口列表的链接。我们单击链接,获取网络接口的列表,片刻之后,我们意识到我们不知道谁在使用这些网络接口。
在继续前进之前,您可能会认为这种情况是不现实的,它不可能发生在我身上,我知道我在帐户中创建的每个资源,并且我都有良好的命名实践。在理想的世界中,通过明确定义的命名惯例,我们的基础设施将尽可能干净。在现实世界中,不幸的是,这并不总是正确的。如果您有在多个团队部署他们的东西的AWS帐户中工作的经验,那么您可能很容易获得不符合您预定义务的惯例的资源。此外,在许多情况下,AWS控制台本身提供了创建具有半随机生成名称的安全组的机会。
回到我们的主题,我们有一个带有网络接口的列表,但是不幸的是,该控制台并不能帮助我们显示谁在使用这些网络接口(只要ENI未连接到EC2实例)。问题是我们如何下一步?
我们可以使用一些技巧来检测谁在使用网络接口。通常,我们可以查看安全性的描述。这可能包含有关资源的附件ID或ID。例如,在lambda函数的情况下,我们可能会在描述:AWS Lambda VPC ENI-vpc-lambda-f8872d9f-745a-42dd-bca9-3ac0e87ac215
中具有类似的东西。在这里,描述告诉我们ENI由放置在VPC中的lambda函数使用,该函数的名称为ENI-vpc-lambda
,该函数的标识符是此uuid f8872d9f-745a-42dd-bca9-3ac0e87ac215
。不幸的是,此描述格式不是标准的,也不是在AWS文档中记录的。对于其他资源,我们可能会使用其他格式获得描述(例如:sagemaker使用的安全组的[DO NOT DELETE] ENI managed by SageMaker for Studio Domain(d-vegsk0mcgrdp) - 946a4c21ed31356ee889a8dd95fde7cf
)。
在这一点上,我们可能会问自己是否有更好的解决方案来找出谁在使用ENI。搜寻互联网,我找不到任何帮助我的东西,所以我决定为自己创建一个工具。我想介绍koude6。
sg-ripper
是在戈兰开发的CLI应用程序,其目的是使我们的生活更轻松,以防我们想在安全组列表中进行一些清理。它可以列出AWS帐户中的所有安全组,它可以为每个安全组获取所有ENIS,并试图找到可能依靠这些ENIS的所有其他资源。
例如:
- 我们可以列出所有使用这些ENIS的所有安全组,其关联的ENIS和资源:
- 我们可以直接列出所有ENIS。在这种情况下,它将显示哪个安全组正在使用每个ENI,以及其他AWS资源依赖于ENIS:
使用sg-ripper
,我们还可以应用一个过滤器,仅查看某些安全组或ENI,以防我们不想从我们的帐户中获取所有现有的安全组。除了显示哪个资源使用ENI之外,它还可以显示安全组是否可拆卸。如果不是这样,它还将显示一些解释为什么被删除被阻止。
sg-ripper
是一个正在进行的项目,源代码本身是开源的,可以在github:https://github.com/cloud-crafts/sg-ripper上找到。欢迎捐款。
结论
随着我们的基础设施正在发展,我们可能倾向于将未使用的资源留在安全集团等后面。仅当不使用,未引用或不在VPC中默认时,才能删除安全组。 sg-ripper
可以使我们的生活更轻松地检测未使用的安全组,并解释了为什么不能删除某个安全组,并指出哪些ENI/哪些资源阻止了我们删除它。