I'm trying to connect to the Amazon EC2 instance via SSH using boto
. I know that ssh connection can be established after some time after instance was created. So my questions are:
boto.manage.cmdshell.sshclient_from_instance()
? I mean for example if the output prints out Could not establish SSH connection
, than try again.That's what I tried so far, but have no luck:
if instance.state == 'running':
retry = True
while retry:
try:
print 'Connecting to ssh'
key_path = os.path.join(os.path.expanduser('~/.ssh'), 'secret_key.pem')
cmd = boto.manage.cmdshell.sshclient_from_instance(instance,
key_path,
user_name='ec2-user')
print instance.update()
if cmd:
retry = False
except:
print 'Going to sleep'
time.sleep(10)
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
SSH Connection refused, will retry in 5 seconds
Could not establish SSH connection
And of course everything is working properly, because I can launch the same code after some time and will get a connection, and will be able to use cmd.shell()
Choose Settings > Connections, and then choose the Hosts tab. Choose the button next to the host you want to view, and then choose View details. The following information appears for your host: The host name.
For Amazon Linux 2 or the Amazon Linux AMI, the user name is ec2-user . For a CentOS AMI, the user name is centos or ec2-user . For a Debian AMI, the user name is admin . For a Fedora AMI, the user name is fedora or ec2-user .
The message "SSH Connection refused, will retry in 5 seconds" is coming from boto: http://code.google.com/p/boto/source/browse/trunk/boto/manage/cmdshell.py
Initially, 'running' just implicates that the instance has started booting. As long as sshd
is not up, connections to port 22 are refused. Hence, what you observe is absolutely to be expected if sshd
does not come up within the first 25 seconds of 'running' state.
Since it is not predictable when sshd
comes up exactly and in case you do not want to waste time by just defining a constant long waiting period, you could implement your own polling code that in e.g. 1 to 5 second intervals checks if port 22 is reachable. Only if it is invoke boto.manage.cmdshell.sshclient_from_instance()
.
A simple way to test if a certain TCP port of a certain host is reachable is via the socket
module:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('hostname', 22))
print "Port 22 reachable"
except socket.error as e:
print "Error on connect: %s" % e
s.close()
I have 2 parts, one to check if the instance is running, then another one to check if the instance is reachable
# Get instance status till it is running
status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
instance_status=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceState.Name)
echo $instance_status
while [ ${instance_status:1:-1} != running ]
do
status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
instance_status=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceState.Name)
echo $instance_status
done
# Get instance reachability till it is ready
status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
instance_reachability=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceStatus.Status)
echo $instance_reachability
while [ ${instance_reachability:1:-1} != ok ]
do
status_output=$(aws ec2 describe-instance-status --instance-ids $instance_id)
instance_reachability=$(jq -n "$status_output" | jq .InstanceStatuses[0] | jq .InstanceStatus.Status)
echo $instance_reachability
done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With