Cloudformation的基本思想就是 software as infrastruture。很多时候,可以作为一种快速有效的架构的备份方式。当我们使用Cloudformation 配置了 stack和对应的 resource之后,如果有管理员有意或者无意地在控制台手动修改了对应的服务配置,那么导致实际运行的架构和我们的cloudformation template不一致,这种情况就叫做 stack drift。stack drift的情况应该尽量避免,cloudformation提供了3种方式来检测。这三种方式分别是 stack action控制台,AWS CLI 命令行, 和 AWS Config

下面通过实际例子进行说明。

首先我们配置一个模板。就用他自己提供的例子LAMP
AWS Cloudformation -  Stack drift

给个名字 demodrift
AWS Cloudformation -  Stack drift

等待1分钟后就创建好了了对应的EC2和SG
AWS Cloudformation -  Stack drift

可以看见他的SG的名字
AWS Cloudformation -  Stack drift

inbound的规则允许 80 和22 端口
AWS Cloudformation -  Stack drift

然后我们手动添加一条443,这样就造成了drift
AWS Cloudformation -  Stack drift

首先来看看如何通过控制台检测,点击stack actions,可以看见他提供了Detect driit,点击之后,等待几秒钟,再点击view drift results
AWS Cloudformation -  Stack drift

可以看见结果里面有2个resource,其中安全组的资源因为我们人工添加了一条规则,造成了drift
AWS Cloudformation -  Stack drift

我们还可以进一步点开,查看具体哪些配置进行了变化

AWS Cloudformation -  Stack drift

不过console的方法需要管理员人工去查看,不够自动化。另外一种方式是通过命令行来查看,这样我们可以改成脚本并通过计划任务进行自动扫描

首先我们需要检查stack drift,他会生成一个id

AWS Cloudformation -  Stack drift

我们可以查看这个id 的状态和进度
AWS Cloudformation -  Stack drift

最后可以查看结果
AWS Cloudformation -  Stack drift

最后,我们来看看AWS Config。

首先 Setting里面需要打开 recording
AWS Cloudformation -  Stack drift

然后选择一个rule cloudformation-stack-drift-detection-rule
AWS Cloudformation -  Stack drift

配置这个rule 的时候,他会要求提供一个Role的arn,因此我们需要额外配置一个IAM Role

AWS Cloudformation -  Stack drift

配置IAM Role
AWS Cloudformation -  Stack drift

最后整个AWS Config的配置界面
AWS Cloudformation -  Stack drift

Evaluate 之后 可以发现他的状态是noncompliant
AWS Cloudformation -  Stack drift

这里有个小插曲,我不小心terminate掉了我们的测试EC2,因此结果出现了两个警告,一个是EC2,一个是SG。

AWS Cloudformation -  Stack drift

说完了三种检测方式,我们最后看看如何修复一下stack drift,确保我们的template和真正的架构一致。一般说来,要么是通过手动修改,把改动再改回去;要么是修改template文件,把新增的变化写进去。

对于SG的改变,我们可以直接Update Stack, 然后在template上面添加对应的新规则

AWS Cloudformation -  Stack drift

但是这个时候有意思的事情就会发生了! SG的改变没问题,但是对于我手动terminate掉的EC2,直接Update我的template并不会自动给我再生成一个!!他会认为已经存在,而不会做任何改变!!!

AWS Cloudformation -  Stack drift

解决方法一般是,直接在template移除掉我的这个EC2,确保一致性;然后再重新添加回来,再次Update,重新生成一个新的EC2