There are three ways to connect to instances running in a VPC: first, your machine is part of your organization’s VPN; second, with an elastic IP to the instance, and third, through a “bastion” server.
Inside the VPN
This is the simplest method and recommended when running in a production scenario in your own network. Instances inside the VPC are directly reachable by your machine.
Outside the VPN via an Elastic IP
If you do not have a VPN or cannot extend a VPC to your VPN (for instance, while testing a new VPC), you can attach an elastic IP to the target instance. This will give that instance direct network access. Note that the security groups on that instance may be configured to allow types of traffic that are not authorized, so this is not recommended. It also allows outbound connections to bypass any firewalls you have in place, so it is not an accurate test of how your instance will behave normally (for example, installing packages via the Linux ”yum” package manager will succeed because the instance has direct network access).
Outside the VPN via a Bastion Server
The recommended way to connect to a target instance inside the VPC is to connect through an external-facing server, or ”bastion server”, which has an elastic IP. This is the NAT/proxy server configured above.
These instructions assume you are using SSH, with public-key authentication. This is typical for Linux instances. For Windows, you can use this method to set up an RDP tunnel (assuming the bastion server is Linux).
First, make the private key accessible to the target instance. The simplest way is to run an SSH agent. This is run on your personal machine, the one which has your private key.
The private key should never leave your personal machine!
From your local machine, start the agent with the ssh-agent command:
exec ssh-agent bash
If the private key is not your default private key (~/.ssh/id_rsa or ~/.ssh/identity), add it to the agent:
your private key never leaves your machine. The agent uses this to respond to authentication challenges sent by the remote instance.
Those commands only need to be run once (or after you reboot).
Now, when you connect to the server, tell SSH to use agent forwarding.
ssh -A -t ec2-user@BASTION_SERVER_IP ssh -A root@TARGET_SERVER_IP
This connects to the bastion and then immediately runs ssh again, so you get a terminal on the target instance. (The default NAT ami uses ec2-user. You may need to specify a user other than root on the target instance if your cluster is configured differently.) The -A argument forwards the agent connection so your private key on your local machine is used automatically (without ever leaving your local machine). Note that agent forwarding is a chain, so the second ssh command also includes -A so that any subsequent SSH connections initiated from the target instance also use your local private key.
Connecting to Services on the Target Instance
You can use the SSH connection to connect to services on the target instance, such as a Remote Desktop, a database, etc. For example, if the target instance is Windows, you can create a Remote Desktop tunnel by connecting to the target instance with a similar SSH command from above, using the -L argument:
ssh -A -t ec2-user@BASTION_SERVER_IP -L 33890:TARGET:3389 ssh -A root@TARGET_SERVER_IP
This will tunnel port 3389 on target to 33890 on your local machine. Then if you connect to localhost:33890 you will actually be connected to the target instance.