Using rsync with an AWS EC2 instance and an SSH key

rsync is an extremely useful utility for synchronizing files between remote computers. It is the primary tool I use to deploy code to targets such as servers, Raspberry Pies, or other remote Linux machines. In this post, I am going to show the basic rsync usage examples, break down the meaning of the widely-used options of the rsync command, and demonstrate the principles of deployment of files to an AWS EC2 instance using rsync with an SSH key.

Let’s say you are working on a project on your local machine that is stored in directory /Users/michaelscott/my_project. You want to transmit this directory to a remote machine, say into /home/michaelscott/my_project. The transmission is done as follows:

# in /Users/michaelscott

rsync -avz my_project/ michaelscott@$REMOTE_HOSTNAME:/home/michaelscott/my_project

After you have made additional changes on the local machine, running the same command will synchronize the remote files with only the updated files transmitted.

In this example, the top-level directory names of both the source and the destination is the same. It doesn’t have to be like that. You would get the same result with such command:

rsync -avz my_project/ michaelscott@$REMOTE_HOSTNAME:/home/michaelscott/my_code

It is very important to notice the trailing slash in the source directory. If it is present, all files of the source my_project will be copied to the destination my_code. However, if it is absent, the directory my_code/my_project will be created, and all the files will be transmitted there.

If your curent directory on the local machine is /Users/michaelscott/my_project, you can invoke rsync like this to get the result identical to the first example:

rsync -avz * michaelscott@$REMOTE_HOSTNAME:/home/michaelscott/my_project

If you look at the documentation via man rsync, the classic -avz option boils down to the following directives:

  • -a enables recursion and preserves elements such as symbolic links, devices, attributes, permissions, ownerships
  • -v enables verbosity
  • -z compresses the files being transmitted

When dealing with an AWS instance, one requires a private key (pem-file) that is associated with the given instance in order to authencicate. Let’s say your key is stored as ~/.ssh/aws_key.pem. Then you would use the following command:

rsync -avze "ssh -i ~/.ssh/aws_key.pem" my_project/ $EC2_USER@$EC2_HOSTNAME:/home/$EC2_USER/my_project

Notice the additional -e option and the "ssh -i ..." string. The latter is basically how you would connect to a remote server via ssh when the name of your private key is othen than the default ~/.ssh/id_rsa:

ssh -i ~/.ssh/aws_key.pem $EC2_USER@$EC2_HOSTNAME

The -e option of rsync specifies the remote shell to be used for transmission. In our case, it is done via the cusom SSH tunnel.

You my refer to additional examples of using rsync in this blog post at TecMint.