# AWS LightSail CI / CD

## Prerequisites

* Project on GitHub (in this tutorial I’m using the Next js application).
    
* Server SSH private key (the key you create while creating a new instance).
    

## Step 1 - Create GitHub Action secrets

We need 3 Action secrets `AWS_USERNAME` `AWS_HOSTNAME` `AWS_PRIVATE_KEY`

* Navigate to the main page of the repository.
    
* Click on the Setting Tab (top right area).
    
* Select Action under “Secrets”
    
* Click on the “New repository secret” button (top right area)
    
* Set Name to “`AWS_PRIVATE_KEY`".
    
* Paste the content of the server SSH private key and remove `----BEGIN RSA PRIVATE KEY---—` and `----END RSA PRIVATE KEY---—`
    
* Click on “Add secret”
    
* follow the above point to add further “action secrets”
    
* Set `AWS_USERNAME` value to your Linux users (most commonly centos, apache2) you can use `whoami` command to get your current user name.
    
* Set `AWS_HOSTNAME` value to your server IP address.
    

<mark>You can also add any ENV variable as Action secrets by following the same guide above.</mark>

## Step 2 - Setup Workflows

This is the part where all magic happens

* Create folders in your project repository `my-cool-app/.github/workflows`
    
* Set up your workflow by creating two `.yml` files. For the sake of simplicity, we named it `build.yml` and `deploy.yml`. 
    

*#build.yml*

```yml
name: build

on:
    push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v2
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    - run: npm ci
    - run: npm run build
      env:
        NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
```

Add env variable under `env:` if any.

*#deploy.yml*

```yml
name: deploy

on:
  push:
    branches:
      - main
  workflow_dispatch:  

jobs:
  deploy:
  	needs: [build]  # require build to pass before deploy runs
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: SSH to Host
      env:
        AWS_PRIVATE_KEY: ${{ secrets.AWS_PRIVATE_KEY  }}
        AWS_HOSTNAME: ${{ secrets.AWS_HOSTNAME }}
        AWS_USERNAME : ${{ secrets.AWS_USERNAME  }}

      run: |
          echo "$AWS_PRIVATE_KEY" > private_key && chmod 600 private_key
          ssh -o StrictHostKeyChecking=no -i private_key ${AWS_USERNAME}@${AWS_HOSTNAME} '

            # 📌 Start your instance/server related tasks form here.
            # 1
            cat whereami.txt
            # 2
            bash ~/scripts/my-app-deploy.sh
          '
```

#1

Tip: Create `whereami.txt` a file on your server to test out the connection.

#2

You can run your `.sh` file stored on your LightSail server, the script will contain all the required commands to build and start your application.

*#*[*my-app-deploy.sh*](http://my-app-deploy.sh)

```bash
pm2 stop my-app

git pull

npm install

npm run build
```

```bash

pm2 start my-app

echo "my-app-deploy script executed"
```

### **WTH is pm2?**

it is a production process manager for Node.js applications with a built-in load balancer.
