Issues trying to SSH into a fresh EC2 instance with Paramiko

a 夏天 提交于 2019-12-04 02:54:34

I seem to have figured this out by trial and error. Even though the instance status is "running" according to boto, there is a delay for when it will actually allow an SSH connection. Adding a "time.sleep(30)" before the "ssh.connect(...)" seems to do the trick for me, though this may vary.

Why not use boto.manage.cmdshell instead?

cmd = boto.manage.cmdshell.sshclient_from_instance(instance,
                                                   key_path,
                                                   user_name='ec2_user')

(code taken from line 152 in ec2_launch_instance.py)

For available cmdshell commands have a look at the SSHClient class from cmdshell.py.

The way to check it's ssh available is to make sure its two status checks both passes. On web UI it looks like this:

And using boto3 (the original question used boto but it was 5 years ago), we can do:

session = boto3.Session(...)
client = session.client('ec2')
res = client.run_instances(...) # launch instance
instance_id = res['Instances'][0]['InstanceId']

while True:
    statuses = client.describe_instance_status(InstanceIds=[instance_id])
    status = statuses['InstanceStatuses'][0]
    if status['InstanceStatus']['Status'] == 'ok' \
            and status['SystemStatus']['Status'] == 'ok':
        break
    print '.'
    time.sleep(5)
print "Instance is running, you are ready to ssh to it"

I recently ran into this issue. The "correct" way would be to initiate a close() first and then reopen the connection. However on older versions, close() was broken.

With this version or later, it should be fixed: https://github.com/boto/boto/pull/412

"Proper" method:

newinstance = image.run(min_count=instancenum, max_count=instancenum, key_name=keypair, security_groups=security_group, user_data=instancename, instance_type=instancetype, placement=zone)
time.sleep(2)
newinstance.instances[0].add_tag('Name',instancename)

print "Waiting for public_dns_name..."
counter = 0
while counter < 70:
    time.sleep(1)
    conn.close()
    conn = boto.ec2.connection.EC2Connection(ec2auth.access_key,ec2auth.private_key)
    startedinstance = conn.get_all_instances(instance_ids=str(newinstance.instances[0].id))[0]
    counter = counter + 1
    if str(startedinstance.instances[0].state) == "running":
        break
    if counter == 69:
        print "Timed out waiting for instance to start."
print "Added: " + startedinstance.instances[0].tags['Name'] + " " + startedinstance.instances[0].public_dns_name

I recently view this code and I have a suggestion for code, Instead of running while loop to check whether the instance is running or not, you can try "wait_until_running()".

Following is the sample code...

client = boto3.resource(
    'ec2',
    region_name="us-east-1"
)

Instance_ID = "<your Instance_ID>"
instance = client.Instance(Instance_ID)
instance.start()
instance.wait_until_running()

After that try to code for the ssh connection code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!