5

Our team is working on AWS, where we have lots of instances, which we keep adding and removing. Each instance has a logical name, which helps us know what it does as well as finding it. When we want to connect to one, though, we either need to update the ~/.ssh/config file all the time, or go to the web console, find the instance by its name, copying its IP and only then we can run it using:

ssh -i ~/.aws/my-pem-file.pem ubuntu@ec2-111-111-111-111.compute-1.amazonaws.com

I was wandering whether there is an easier way to do it, where you could specify the machine name, and EC2 would do the rest?

Something like

ssh-aws my-machine-name
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93

3 Answers3

8

If you configure your instance/load balancer with an Elastic IP (which doesn't change), you can always use an SSH config file.

Secondly, if you have the Unified AWS CLI Tools configured, you can add these functions to your Bash profile. Assuming every instance you have has a unique "Name" tag, this will return the IP address of that instance for SSH requests. (Otherwise, it will simply use the first "Name" match.)

function hostname_from_instance() {
    echo $(aws ec2 describe-instances --filters "{\"Name\":\"tag:Name\", \"Values\":[\"$1\"]}" --query='Reservations[0].Instances[0].PublicDnsName' | tr -d '"')
}

function ip_from_instance() {
    echo $(aws ec2 describe-instances --filters "{\"Name\":\"tag:Name\", \"Values\":[\"$1\"]}" --query='Reservations[0].Instances[0].PublicIpAddress' | tr -d '"')
}

function ssh-aws() {
    ssh -i ~/.ssh/your-keypair.pem ec2-user@$(ip_from_instance "$1")
}

Depending on whether you're running instances inside of VPC or not, sometimes you'll get back one or the other. All-public (classic) EC2 should always get back a hostname, and sometimes a public IP.

Feel free to tweak/adjust as necessary.

Ryan Parman
  • 6,855
  • 1
  • 29
  • 43
  • The problem with using the SSH config file, is that the list is very dynamic, and changes all the time, so every time a new instance is launched, the config file should change. This double maintenance is inconvenient, especially when working with a team - you don't always know that something changes... – Uri Agassi Jan 29 '14 at 10:55
  • Regarding the bash script - it sounds like a good idea! I've got [ec2 command-line tools](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SettingUp_CommandLine.html#setting_up_ec2_command_linux) installed, and I'm trying to leverage on it – Uri Agassi Jan 29 '14 at 10:57
  • There are the old-school EC2 CLI tools, then there are the new Unified CLI tools. My code leverages the new-school CLI tools. – Ryan Parman Jan 30 '14 at 05:03
  • I tried this but for some reason I keep on getting: "Name or service not knownname \033[?1h\033=". Any ideas? – deann Jul 29 '21 at 10:58
  • 1
    @deann: Yes. Those are markers for ANSI color codes in the terminal. You need to ensure you're working with non-colored plain text. – Ryan Parman Jul 29 '21 at 17:35
  • @RyanParman How can I do that? I am using the default bash on Ununtu 16.04, and I am following your script .. I tried echo -E, or echo ... | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" but neither worked – deann Jul 31 '21 at 18:25
3

I wrote a little bash script which uses aws-cli (thanks @Ryan Parman) to find the correct machine IP and PEM from the machine name:

http://sash.agassi.co.il/

To use it simply call

sash <machine-name>

I've also added more features to it like upload, download, and multiplex connect...

Community
  • 1
  • 1
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
  • I'm getting an error: `Unable to construct an endpoint for ec2 in region None.Could not find an instance named m-name`. What am I missing? – user2503775 Jun 29 '14 at 12:32
  • Do I must specify the region? – user2503775 Jun 29 '14 at 14:39
  • It isn't taking the configurations from `aws-cli`? anyway, I'm keep getting the same error, after adding ACCESS_KEY & SECRET_KEY to `aws configure`... – user2503775 Jun 29 '14 at 14:56
  • @user2503775 - yes, it takes the configuration from `aws-cli` (it actually uses their API. Also, you need to specify default region via `aws configure` (or manually by setting `AWS_DEFAULT_REGION`). – Uri Agassi Jun 29 '14 at 15:23
  • Toda Raba :) actually, I had problem with the keys, since I put them with quotes. But still I can see some of my instance names, that I can get them via the autocomplete, but when trying to connect them, I'm getting `Connecting to m-name (None)` – user2503775 Jun 29 '14 at 15:30
0

The simple way would be enter this ssh -i ~/.aws/my-pem-file.pem ubuntu@ec2-111-111-111-111.compute-1.amazonaws.cominto a .sh file with a logical name as you specified. Now when u run $logical-name.sh, you are logged in to that instance. The file needs to be updated in case the instance address has changed. One option to overcome would be assign ip's to each instance but i'm not sure if that is feasible from your end.

Bijendra
  • 9,467
  • 8
  • 39
  • 66
  • This would be fine if I have one instance on amazon, but if I have fifty? and if they change daily? – Uri Agassi Jan 29 '14 at 10:58
  • In case you are not willing to assign ip to instances, you need to devise a mechanism to update shell scripts when any of the instance addresses change. Either some version control for those sh files. – Bijendra Jan 29 '14 at 11:07