禁用后自动清理CloudFront分布

时间:2019-05-02 18:47:17

标签: amazon-web-services aws-lambda amazon-cloudfront

我目前正在基于AWS Lambda构建一个无服务器应用程序,该应用程序代表用户创建CloudFront分配。当前,当用户调用我的“删除”操作时,我的API Lambda函数会禁用CloudFront分发。但是,从未清除和删除发行版,因为我需要等待禁用先完成。鉴于Lambda的限制为15分钟,我不能只等待禁用功能完成部署,即使我可以这样做也不会节省成本。

我意识到我可以有一个Lambda函数来定期轮询我的CloudFront分布并清理它们,但是我希望以事件驱动的方式做到这一点,以使其尽可能接近实时发生,而我不希望这样做。在没有要删除的内容时不需要使用任何计算。

我尝试将CloudWatch Event设置为在UpdateDistribution调用上触发,但是会在分发开始禁用而不是完成时触发,因此并不能真正解决我需要等待部署的问题。

关于如何实现此目标的任何建议?甚至有可能吗?

2 个答案:

答案 0 :(得分:0)

我建议使用AWS Step Function管理CloudFront分布的最终删除。您的lambda可以禁用CloudFront分配并调用Step Function。 step函数可以通过调用Lambda函数来管理分发的轮询和最终删除。

答案 1 :(得分:0)

AWS正式表示,CloudFront最多需要15分钟才能启用或禁用分发。尽管我们发现这通常是正确的,但是我们遇到了禁用分发超过15分钟的情况,因此,我建议任何解决方案都必须考虑由于某种原因而可能花费超过15分钟的可能性分钟以禁用分发。

尽管不是 perfect 事件驱动的解决方案,但绝对有可能以事件驱动的方式进行此操作。我们的解决方案是使用CloudWatch,Lambda,SQS和CloudTrail完成的。很明显,您已经启用了CloudTrail,但对于可能面临类似挑战的未来读者,如果您尚未启用CloudTrail,则第一步是在您的帐户中启用CloudTrail日志记录(注意:使用CloudTrail会产生详细的费用{ {3}})。启用CloudTrail后,CloudWatch Events将能够从CloudTrail获取CloudFront事件。

现在启用了CloudTrail,我们可以继续删除已禁用的分发。在CloudWatch中,创建一个CloudWatch事件,该事件在CloudFront的UpdateDistribution事件上触发一个Lambda函数,该函数将包含分发ID的消息发布到SQS Delay Queue,该消息的最大延迟为15分钟({{3} }。

SQS队列中的消息使用者是第二个Lambda函数。调用时,此Lambda函数应为提供的分发ID调用CloudFront GetDistribution API,并检查Distribution.DistributionConfig.Enabled === true是否正确,如果不正确,请检查Distribution.Status === Deployed

可以根据您的特定需求或用例调整逻辑,但是从这里开始,潜在的工作流程将是简单地检查是否Distribution.DistributionConfig.Enabled === true。如果为真,则退出该函数,因为您希望禁用它,但事实并非如此,因此有些不对劲。可能是手动重新启用了发行版,或者在某处禁用了它,或者由于其他原因调用了UpdateDistribution API,无论是什么原因,发行版都不处于我们期望的状态,我们不应该继续。在中断该功能之前,您应该/可以通过发送SNS消息通知管理员此错误发生来确保此操作不会无声地失败。

继续,如果Distribution.DistributionConfig.Enabled === true返回false,请检查以确保Distribution.Status === Deployed。如果返回false,则表示禁用仍为InProgress,您需要等待更长的时间。要在不保持Lambda正常运行的情况下解决此问题(并为此而产生费用),只需将第二条消息发布到我的Delay Queue中,该消息再次包含分发ID,然后函数结束。 Lambda将在15分钟后再次触发,并在下一次调用时重复上述过程。

如果Distribution.DistributionConfig.Enabled === true上的支票返回false,而Distribution.Status === Deployed则返回true,则该分发已被禁用,可以删除。从这里开始,只需调用具有发行版ID的DeleteDistribution API,并从开始时进行的ETag调用中调用GetDistribution。 API操作类似于DeleteDistribution --id {distributionId} --if-match {ETag}。如果成功删除它,您将得到204,就这样,所有操作都完成了。如果有错误,您将得到一个4xx,需要处理。