3

I am running the following script:

from __future__ import print_function

import paramiko
import boto3


#print('Loading function')

paramiko.util.log_to_file("/tmp/Dawny.log")

# List of EC2 variables
region = 'us-east-1'
image = 'ami-<>'
keyname = '<>.pem'

ec2 = boto3.resource('ec2')


instances = ec2.create_instances(ImageId=image, MinCount=1, MaxCount=1, InstanceType = 't2.micro', KeyName=keyname)

instance = instances[0]
instance.wait_until_running()

instance.load()

print(instance.public_dns_name)



def lambda_handler(event, context):
    instances = ec2.create_instances(ImageId=image, MinCount=1, MaxCount=1, InstanceType = 't2.micro', KeyName=keyname)

    instance = instances[0]
    instance.wait_until_running()

    instance.load()

    print(instance.public_dns_name)

When I run it, I am getting this error

botocore.exceptions.ClientError: An error occurred (InvalidKeyPair.NotFound) when calling the RunInstances operation: The key pair '<>.pem' does not exist

Even when I add the complete path to the key-pair, boto3 gives me the same error. Also, I tried this too: https://stackoverflow.com/a/34410564/4993513

Still, doesn't work.

franklinsijo
  • 17,784
  • 4
  • 45
  • 63
Dawny33
  • 10,543
  • 21
  • 82
  • 134

5 Answers5

6

The KeyName argument in create_instances() refers to the Name given to the KeyPair when creating one in AWS.

The name would usually be "KeyName.pem". Pass the string without the .pem extension. The KeyName argument in create_instances() expects only the name of the Keypair and not the actual Key file.

For example:
If the key file is myinstance.pem, then the KeyName would be myinstance unless the keyfile has been renamed. You will be able to view all the KeyPairs owned by you from the console (can be listed with cli and api too).

franklinsijo
  • 17,784
  • 4
  • 45
  • 63
  • 3
    Just to further explain... The command does not need access to the keypair you have on disk. Instead, it sends the name of the keypair to EC2 and then EC2 will access the named keypair that is already stored on AWS and it will be used when launching the instance. – John Rotenstein Mar 15 '17 at 10:34
  • @franklinsijo I do own the KeyPair. Yet, I am getting this error. Also, when I create an instance without the KeyName attribute, it creates one. But, I can't find it in my EC2 dashboard :/ . [I have also cross-checked the access and secret access keys too] – Dawny33 Mar 15 '17 at 10:52
  • Pass the argument without the `.pem` extension. – franklinsijo Mar 15 '17 at 10:54
2

In cases like this, you are looking at a different region. Most likely you are creating the instance in default region but keypair exists in us-east-1.

Try:

ec2 = boto3.resource('ec2', region_name=region)
helloV
  • 50,176
  • 7
  • 137
  • 145
1

Let's explain the "KeyPair" in AWS EC2. Usually, people will use the console to generate a keypair, where AWS will give you the private key afterwards and save the public key into the your key repository inside AWS.

When launching a EC2 instance, the process will copy the Public Key found inside your account EC2 keypair and put it inside the instance OS respective location. (e.g. ~/.ssh/authorized_keys)

You cannot use your own key "on-the-fly", the launcher will not give you the option(reason is shown later). If you want to use your own key, you must first import your public key into the repo and give it a name that you use for your EC2.

Do take note that ec2 keypair must be compliance to AWS standard as following:

  • OpenSSH public key format (the format in ~/.ssh/authorized_keys)
  • Base64 encoded DER format SSH public key file format as specified in
  • RFC4716 Amazon EC2 does not accept DSA keys. Make sure your key generator is set up to create RSA keys.

Supported lengths: 1024, 2048, and 4096.

If you can't import your public key into the EC2 keypair repo, you must generate a new one that is compliance. Only after successfully importing the key, you may launch the instance using your keypair.

In addition, if you want to automate import of your own key, you can use ec2.client.import_key_pair() to do it.

mootmoot
  • 12,845
  • 5
  • 47
  • 44
1

You have to create your keypair before deploying a new instance

keyPairResponse =ec2Client.create_key_pair(KeyName=keyPairName)

Then you can deploy. Don't forget to save your key string.

keyresponse['KeyMaterial']
Niza Siwale
  • 2,390
  • 1
  • 18
  • 20
0

I have faced the same issue, actually I have created a user in my AWS account, but in CLI I have used another region than the one I usually work in. The issue was that I was using the KeyPair of my default region, so when I provid the name without the .pem extention it gives the error InvalidKeyPair. What I did is that I created another KeyPair specific to the region I mentionned in the CLI. I used the name of the KeyPair without the .pem extention and the issue was resolved.

Hope my answer will Help!

Iriel
  • 171
  • 2
  • 2
  • 13