You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AWS CloudFormation报错:新建EC2 key pair不存在问题排查

我来帮你搞定这个CloudFormation的密钥对报错问题——"The key pair ___ does not exist"这个坑我之前也踩过,大概率是时序、权限或者资源引用这几个地方出了问题,咱们一步步来排查:

问题核心原因拆解

这个报错通常逃不开以下3种场景:

  1. 资源创建时序乱了:CloudFormation默认并行创建资源,如果EC2实例先启动,此时自定义Lambda还没生成密钥对,自然会报找不到的错误。
  2. Lambda权限不够:你的LambdaRoleLambdaPolicy可能没给足创建/查询EC2密钥对的权限,甚至缺少CloudFormation自定义资源的回调权限。
  3. 密钥对名称引用错了:EC2实例配置里写的密钥对名称,和Lambda生成并返回的名称不匹配。
分步解决方案

1. 锁死资源创建的依赖顺序

你需要让EC2实例明确等待自定义密钥对资源创建完成,同时确保Lambda的IAM角色先部署好。在EC2实例的DependsOn里加上对应的资源逻辑ID:

MyEC2Instance:
  Type: AWS::EC2::Instance
  DependsOn:
    - CustomKeyPairResource  # 替换成你的自定义密钥对资源的逻辑ID
    - LambdaRole
    - LambdaPolicy
  # 其他EC2配置...

2. 补全Lambda的IAM权限

你的Lambda需要3类核心权限:创建/查询密钥对、写CloudWatch日志(方便排查问题)、给CloudFormation发送回调信号。更新你的LambdaPolicy

LambdaPolicy:
  Type: AWS::IAM::Policy
  DependsOn: LambdaRole
  Properties:
    PolicyName: LambdaKeyPairManagementPolicy
    Roles:
      - !Ref LambdaRole
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
        # 允许创建、查询EC2密钥对
        - Effect: Allow
          Action:
            - ec2:CreateKeyPair
            - ec2:DescribeKeyPairs
          Resource: "*"
        # 允许Lambda写日志,方便排查执行问题
        - Effect: Allow
          Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
          Resource: "arn:aws:logs:*:*:*"
        # 允许Lambda给CloudFormation发送执行结果回调
        - Effect: Allow
          Action:
            - cloudformation:SignalResource
          Resource: "*"

你的LambdaRole信任策略已经允许Lambda服务扮演角色,这部分是对的,可以保留。

3. 确保密钥对名称引用正确

Lambda执行生成密钥对后,要把密钥对名称通过自定义资源的Data字段返回给CloudFormation,比如Lambda代码里的回调逻辑:

# Lambda代码示例(Python)
import boto3
from crhelper import CfnResource

helper = CfnResource()
ec2 = boto3.client('ec2')

@helper.create
def create_key_pair(event, context):
    key_pair_name = f"{event['StackName']}-custom-key"  # 用栈名做前缀避免重复
    key_pair = ec2.create_key_pair(KeyName=key_pair_name)
    # 返回密钥对名称给CloudFormation
    helper.Data.update({"KeyPairName": key_pair_name})

def handler(event, context):
    helper(event, context)

然后EC2实例里要正确引用这个返回值:

MyEC2Instance:
  Type: AWS::EC2::Instance
  Properties:
    KeyName: !GetAtt CustomKeyPairResource.KeyPairName
    # 其他EC2配置...

4. 查Lambda日志找细节

如果还是报错,直接去CloudWatch Logs里找这个Lambda的执行日志——大概率能看到具体的失败原因,比如权限不足、区域不匹配(要确保Lambda和EC2在同一个AWS区域)。

额外避坑提示
  • 重复部署模板时,要避免密钥对名称重复(比如给名称加栈名或随机后缀),不然会报“密钥对已存在”的错误。
  • 跨区域部署的话,Lambda和EC2必须在同一个区域,不然Lambda创建的密钥对在另一个区域,EC2根本找不到。

内容的提问来源于stack exchange,提问作者cayblood

火山引擎 最新活动