The main idea

# What is aws-upload?

aws-upload is a CLI Tool to rapid deploy files on your server over ssh. Unlike other scripts or tools, aws-upload is designed to maximize efficiency, speed, and automation.

The core functionality is based on rsync to deploy only what you need. It will automatically compress and upload only the files you change it.

# Why

The project was born because a frustration I got at work. We had a lot of small projects in place and no deploy system.

FTP clients

At the beginning, I was using just standard FTP clients (eg. FileZilla). But this process was just tedious and full of errors.

There are at least two main issues:

Find the file: this process probably was the most time consuming and frustrating. You have to click through all the tree on each folder till you reach the file you want to upload. And then repeat the process for each file you want to upload. Not efficient at all.

Upload only the correct file: sometimes for laziness, you may be tempted to drag and drop a full folder. Big mistake, chances are you are uploading as well some file you may not want to upload. Think about of your .git folder for example.

Later on, I start using rsync with alias.

Alias

I believe that when you reach a critical amount of data on your .rc file (.zshrc, .aliases), the full experience with alias is broken.

There are at least three main issues:

Setup: when you setup an alias is tedious. Long strings are risky to edit and manipulate. Reload the shell all the time you edit it's quite frustrating. It's better in real time.

Debug: if you make a mistake in your alias you won't receive specific error messages to help you and make the process painless. It's better with some check.

Structure: crawl a huge file and edit a three line command without any structure it's not fun. It's better to edit with scope and focus.

At the end, I finished writing a PHP script with some json files to fix the problem: aws-upload was born.

# Why not

aws-upload does just one thing, deploy.

I think if you are playing with a huge project in which you need to automate a little bit more (eg. testing before deploy, building systems, versioning for each server) aws-upload is not for you.

In these cases, you should have a proper deployment automation in place, maybe with some CI system.

Getting Started

# Installation

This guide assumes you are already familiar with composer and you have it installed on your machine. If you don't have composer follow the guide here to install it.

To install aws-upload we will use Composer.
Run this in your terminal to get the latest aws-upload version:

                                
# get latest stable
$ composer global require aws-upload/aws-upload

When the procedure is completed you can verify that all is good by typing:

                                
$ aws-upload -V
# in the shell you should see something like
aws-upload version x.x.x

# Enabling tab-completion

The tab completion is done by the shell you are using.

Right now the only shell supported is zsh in combination with oh-my-zsh.

The auto-complete function is done with an oh-my-zsh plugin. To enable the autocomplete you can type:

                                
$ aws-upload autocomplete
# download, install and enable the oh-my-zsh plugin

This command will download, install and enable the oh-my-zsh plugin for you.

Note:

The auto-complete function relies on a specific set of your system. In particular, it expects your system to have the following software already installed :

  • git
  • zsh
  • oh-my-zsh

Manual Installation:

The auto-complete is an oh-my-zsh plugin as said before. If you want to install the plugin manually, follow the instructions on the aws-upload-zsh documentation.

# Update

To update aws-upload to the latest version, run the self-update command. It will replace your aws-upload with the latest version.

If you have the tab-completion enabled run autocomplete to update the zsh plugin as well.

                                
# update latest stable
$ aws-upload selfupdate
# update tab-completion plugin
$ aws-upload autocomplete

# Speaking aws-upload: proj, env, and keys

There are some concept that you have to be aware if you want to use properly aws-upload.

Project: the project is a label to identify a project you are working on.
You can not use a . in the project label.
Abbreviation: proj.
Examples: [blog, client-name].

Environments: the environment is a label to identify a specific environment or setup. You can not use a . in the environment label.
Abbreviation: env.
Examples: [dev, stag, prod].

Keys: the key is a shortcut to identify a project in combination with an environment.
The syntax is: proj.env .

dev stag prod
blog blog.dev blog.stag blog.prod
client-name client-name.dev client-name.stag client-name.prod

# Your first deploy

Before to deploy with aws-upload you have to create a setting file. To create a setting file:

                                
$ aws-upload new [key]
# in the case of proj:blog env:dev
$ aws-upload new blog.dev

This command will generate a setting file for this key. Now you have to edit it.
To edit you can type:

                                
# to edit the setting file
$ aws-upload edit blog.dev

Now you are ready to deploy.
To deploy edit:

                                
# to deploy!
$ aws-upload blog dev

Done.

The setting files

# The file structure

This is the structure of a setting file.
As you can see there are 4 main parts: pem, local, remote, exclude.

                                
{
"pem" : "/home/keys/your-key.pem",
"local" : "/var/www/project/*",
"remote" : "[email protected]:/var/www/html",
"exclude" : [
".env",
".git/",
"storage/",
"tests/",
"node_modules/"
]
}

pem | string: it contains the path to your pem key.
local | string: it contains the path to the directory you want to upload to your ec2 server.
exclude | array: it contains the list of files or folders you DO NOT want to upload.
remote | string: it contains the information of your server.
In particular [user]@[host]:[remotePath] where:

  • user: is you user on your server. Possibles values [ec2-user, ubuntu]
  • host: is your ec2 host name. Similar value [ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com]
  • remotePath: is the folder you want to upload your project to. It's the folder on your server.

# Examples

Deploy on ec2 / ubuntu AMI

                                
{
"pem" : "/home/username/ssh/your-key.pem",
"local" : "/var/www/project/*",
"remote" : "[email protected]:/var/www/html",
"exclude" : [
".env",
".git/",
"node_modules/"
]
}

Deploy on ec2 / Amazon Linux AMI

                                
{
"pem" : "/home/username/ssh/your-key.pem",
"local" : "/var/www/project/*",
"remote" : "[email protected]:/var/www/html",
"exclude" : [
".env",
".git/",
"node_modules/"
]
}