cayblood
cayblood

Reputation: 1876

AWS CloudFormation: "The key pair ___ does not exist" error for newly-created EC2 key pair

I'm using a custom CloudFormation resource to generate an EC2 keypair for an automated install. I'm trying to remove as many manual steps as possible for a highly-automated server setup. Here is the portion of the CloudFormation template with the relevant code:

LambdaRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Action:
            - sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com

LambdaPolicy:
  Type: AWS::IAM::Policy
  DependsOn:
    - LambdaRole
  Properties:
    PolicyName: CFNCustomSecretProviderPolicy
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Action:
            - iam:CreateAccessKey
            - iam:DeleteAccessKey
            - iam:UpdateAccessKey
            - ssm:PutParameter
            - ssm:GetParameter
            - ssm:DeleteParameter
            - ec2:ImportKeyPair
            - ec2:DeleteKeyPair
          Resource:
            - '*'
        - Effect: Allow
          Action:
            - kms:Encrypt
          Resource:
            - '*'
        - Action:
            - logs:*
          Resource: arn:aws:logs:*:*:*
          Effect: Allow
    Roles:
      - !Ref 'LambdaRole'

CFNSecretProvider:
  Type: AWS::Lambda::Function
  DependsOn:
    - LambdaPolicy
  Properties:
    Description: CloudFormation Custom:Secret implementation
    Code:
      S3Bucket: !Sub 'binxio-public-${AWS::Region}'
      S3Key: lambdas/cfn-secret-provider-0.11.0.zip
    Handler: secrets.handler
    MemorySize: 128
    Timeout: 30
    Role: !GetAtt 'LambdaRole.Arn'
    Runtime: python2.7

PrivateKey:
  Type: Custom::RSAKey
  DependsOn: CFNSecretProvider
  Properties:
    Name: /mainframe/onyx-private-key
    KeyAlias: alias/aws/ssm
    ServiceToken: !Join
      - ":"
      - - arn:aws:lambda
        - !Ref "AWS::Region"
        - !Ref "AWS::AccountId"
        - !Ref CFNSecretProvider

CustomKeyPair:
  Type: Custom::KeyPair
  DependsOn:
    - CFNSecretProvider
    - PrivateKey
  Properties:
    Name: CustomKeyPair
    PublicKeyMaterial: !GetAtt
      - PrivateKey
      - PublicKey
    ServiceToken: !Join
      - ":"
      - - arn:aws:lambda
        - !Ref "AWS::Region"
        - !Ref "AWS::AccountId"
        - !Ref CFNSecretProvider

EC2Instance:
  Type: AWS::EC2::Instance
  DependsOn:
   - CustomKeyPair
   - InstanceProfile
  Properties:
    IamInstanceProfile: !Ref InstanceProfile
    InstanceType: !Ref InstanceType
    ImageId: !FindInMap [AWSRegionToAMI, !Ref "AWS::Region", AMI]
    KeyName: !Ref CustomKeyPair

...

Everything in this seems to work great up until the instance is created. It fails claiming the keypair doesn't exist, even though the keypair is there after it runs, and I can query it:

∴ aws ec2 describe-key-pairs --region=us-east-2 --profile=mainframe- 
personal
{
    "KeyPairs": [
        {
            "KeyFingerprint": "90:42:11:40:a5:9b:66:af:78:ce:b4:d1:54:07:95:27",
            "KeyName": "CustomKeyPair"
        },
        {
            "KeyFingerprint": "27:5c:bf:4a:b2:f6:75:3b:8c:c3:1b:57:0d:7e:28:de:8e:cd:90:69",
            "KeyName": "default"
        }
    ]
}

The error I'm getting in the CloudFormation event log is The key pair 'arn:aws:ec2:us-east-2:685716241758:keypair/CustomKeyPair' does not exist. That ARN is exactly what is shown in the resource list. Is there some reason that CloudFormation can't find this keypair?

Upvotes: 1

Views: 4285

Answers (1)

John Rotenstein
John Rotenstein

Reputation: 269320

The AWS::EC2::Instance - AWS CloudFormation documentation says:

KeyName: Provides the name of the Amazon EC2 key pair.

The error message is suggesting that an ARN was passed. Instead, try just passing the name (the last part of the ARN).

Upvotes: 3

Related Questions