encrypted EBS caused AWS EC2 failed to start by Lambda
前不久因为安全方面的考虑,把AWS EC2挂载的EBS硬盘做了加密处理,具体就是先给未加密non-encrypted的EBS硬盘创建一个snapshot,然后在KMS里创建了一个新的key,再从那个未加密的snapshot来copy一个新的snapshot,copy的时候选KMS里的key来做加密,这样就得到了一个加密过的snapshot,最后再用这个加密过的snapshot创建一个新的EBS,来替换原先EC2挂载的未加密的EBS硬盘,这样就完成了对EC2硬盘的加密。
当时做的很顺利,做完看看貌似EC2一切正常,也就放那儿用了。
但是最近发现,用来定时启动这些EC2的Lambda function貌似失效了,具体表现为可以被Lambda停机,但不能被Lambda启动了。
查了一下,发现Lambda自己是执行成功了的,打印Lambda的instance.start()的response,可以看到Lambda的确已经成功发出了启动的event:
[{'StartingInstances': [ {'CurrentState': {'Code': 0, 'Name': 'pending'}, 'InstanceId': 'i-aaaaa', 'PreviousState': {'Code': 80, 'Name': 'stopped'}}, {'CurrentState': {'Code': 0, 'Name': 'pending'}, 'InstanceId': 'i-bbbbbb', 'PreviousState': {'Code': 80, 'Name': 'stopped'}}], 'ResponseMetadata': {'RequestId': 'a15ff429-06ae-4214-b29a-982e7958e8e9', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'a15ff429-06ae-4214-b29a-982e7958e8e9', 'cache-control': 'no-cache, no-store', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'content-type': 'text/xml;charset=UTF-8', 'content-length': '916', 'date': 'Tue, 04 Jun 2024 05:39:06 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0} }]
可以看到,Lambda已经发出了让EC2从stopped启动到pending的event,按理说EC2从pending就会转到start状态。但问题是EC2并没有变成started,而是一直保持stopped状态。
被这个问题困扰了两周多,搜了AWS自己Lambda的文档,也搜了stack overflow上的相关问题,大多给出的回答都是检查Lambda是否被正确配置、是否被触发这些。
走了很多弯路,最后在AWS re:Post上发帖提问,得到了AWS技术专家Didier Durand的回答,他建议去查一下CloudTrail里API调用是否成功。
于是按照建议去查了CloudTrail,Lambda的event记录倒是没啥问题,但是紧挨着lambda event,有一条同样发给这个account的CreateGrant的记录,里面报了一个access denied的错:
{ ... "errorCode": "AccessDenied", "errorMessage": "User: arn:aws:sts::1111111:assumed-role/aaaaaa-lambda-start-instance-service-role/aaaaaa-start-ec2-on-monday-morning is not authorized to perform: kms:CreateGrant on resource: arn:aws:kms:us-east-1:1111111:key/8f702ef1-61cb-4ddc-a369-bb71c004955d because no identity-based policy allows the kms:CreateGrant action", }
这个KMS key一下子让我想起来了之前做的EBS硬盘加密的操作,当时用的key就是这个key。于是打开KMS页面,把Lambda的IAM role加到了这个KMS key的policy里面。再去试lambda,果然这次CloudTail的CreateGrant不报错了,EC2也启动起来了。
评论
发表评论