Skip to content

Latest commit

 

History

History
251 lines (180 loc) · 9.73 KB

README.md

File metadata and controls

251 lines (180 loc) · 9.73 KB

AWS Deployment for Gleam with Terraform

This guide demonstrates how to deploy DeployEx in Amazon Web Services (AWS) using Terraform to programmatically set up the environment.

Setup

To begin, ensure the following applications are installed:

1. SSH Key Pair

Create an SSH key pair named, e. g. myappname-web-ec2 by visiting the AWS Key Pair page. Save the private key in your local SSH folder (~/.ssh). The name myappname-web-ec2 will be used by this file devops/terraform/modules/standard-account/variables.tf within terraform templates.

2. Environment Secrets

Ensure you have access to the following secrets for storage in Secrets Manager:

SECRET NAME EXAMPLE SOURCE
DEPLOYEX_SECRET_KEY_BASE 42otsNl...Fpq3dIJ02 mix phx.gen.secret
DEPLOYEX_ERLANG_COOKIE my-cookie
DEPLOYEX_ADMIN_HASHED_PASSWORD $2b$12$...3Lu6ys538TW Bcrypt.hash_pwd_salt("my-pass")

3. Variables Configuration

Rename the file main_example.tf_ to main.tf and verify and configure the variables according to your specific environment. Ensure that you also review and update the variables file. These variables will be utilized across all Terraform templates to ensure correct setup.

4. Provisioning the Environment

Check you have the correct credentials to create/update resources in aws:

cat ~/.aws/credentials 
[default]
aws_access_key_id=access_key_id
aws_secret_access_key=secret_access_key

Once the key is configured, proceed with provisioning the environment. Navigate to the ./environments/prod folder and execute the following commands:

terraform plan # Check if the templates are configured correctly
terraform apply # Apply the configurations to create the environment

Wait for the environment to be created. Once the provisioning is complete, you can check the instance at this address.

Updating Secret Manager

Navigate to AWS Secrets Manager, locate and update the following secret:

  • deployex-myappname-prod-secrets

Click on the secret, then select "Retrieve Secret Value" and edit the secret by adding the new key/value pairs:

DEPLOYEX_SECRET_KEY_BASE=xxxxxxxxxx
DEPLOYEX_ERLANG_COOKIE=xxxxxxxxxx
DEPLOYEX_ADMIN_HASHED_PASSWORD=xxxxxxxxxx
  • myappname-stage-otp-tls-ca, myappname-stage-otp-tls-key, myappname-stage-otp-tls-crt:

Create the TLS certificates for OTP distribution using the Following script, changing the appropriate names and regions inside it.

make tls-distribution-certs

The command will generate three files: ca.crt, deployex.key and deployex.crt. Click in each secret in AWS, then select "Retrieve Secret Value" and edit the secret by adding them as plain text, For guidance, you can refer to this eaxample.

5. EC2 Provisioning (Manual Steps)

When running Terraform for the first time, AWS secrets are not yet created. Consequently, attempts to execute deployex or certificates installation will fail. Once these AWS secrets, including certificates and other sensitive information, are updated, subsequent iterations of Terraform's EC2 destroy/create process will no longer require manual intervention.

For initial installations or updates to deployex, follow these steps:

PS: make sure you have the pair myappname-web-ec2.pem saved in ~/.ssh/

ssh -i "myappname-web-ec2.pem" ubuntu@ec2-52-67-178-12.sa-east-1.compute.amazonaws.com
ubuntu@ip-10-0-1-56:~$

After getting access to EC2, you need to grant root permissions:

ubuntu@ip-10-0-1-56:~$ sudo su
root@ip-10-0-1-56:/home/ubuntu$

Since the secrets are already updated, we are going to install them in the appropriate addresses

./install-otp-certificates.sh 

# Installing Certificates env: stage at /usr/local/share/ca-certificates #
Retrieving and saving ......
[OK]

Check that the certificates are correctly installed:

ls /usr/local/share/ca-certificates
ca.crt  myappname.crt myappname.key deployex.crt  deployex.key

If you are updating DeployEx, you may need to update the deployex.sh script. This step is not necessary during the initial installation, as the script is already installed by default. To update the script, use the following commands:

version=0.3.0
rm deployex.sh
wget https://github.com/thiagoesteves/deployex/releases/download/${version}/deployex.sh -P /home/ubuntu
chmod a+x deployex.sh

Run the script to install (or update) deployex:

```bash
root@ip-10-0-1-116:/home/ubuntu# ./deployex.sh --install deployex-config.json
#           Removing Deployex              #
...
# Clean and create a new directory         #
# Start systemd                            #
# Start new service                        #
Created symlink /etc/systemd/system/multi-user.target.wants/deployex.service → /etc/systemd/system/deployex.service.

If you need to update Deployex, follow these steps to ensure that the configuration file reflects the new version:

vi deployex-config.json
{
 ...
  "version": "0.3.0-rc15",
  "os_target": "ubuntu-22.04",
  ...
}

Once the file is updated, run the update command:

root@ip-10-0-1-116:/home/ubuntu# ./deployex.sh --update deployex-config.json

Important

Depending on the new version of DeployEx, you may need to update both the deployex-config.json file and the deployex.sh script

At this point, DeployEx should be running. You can view the logs using the following commands:

tail -f /var/log/deployex/deployex-stdout.log
tail -f /var/log/deployex/deployex-stderr.log

6. Monitored App deployment

Once DeployEx is running, you MUST deploy the monitored app. This deployment involves creating the release package and the current version JSON file in the designated storage path.

Release Version

The release version file MUST be formatted in JSON and include the following information:

{
  "version": "0.1.0-9cad9cd",
  "hash": "9cad9cd3581c69fdd02ff60765e1c7dd4599d84a",
  "pre_commands": []
}

The JSON file MUST be stored at the following path: /versions/{monitored_app}/{env}/current.json

Release package

After DeployEx fetches the release file, it will download the release package for installation. The package should be located at: /dist/{monitored_app}/{monitored_app}-{version}.tar.gz

[CI/CD] Upload files to AWS from Github

Here are some useful resources with suggestions on how to automate the upload of version and release files to your environment using GitHub Actions:

7. Setting Up HTTPS Certificates with Let's Encrypt

Important

Before proceeding, make sure that the DNS is correctly configured to point to the AWS instance.

For HTTPS, you can use free certificates from Let's encrypt. In this example, we'll use cert bot for ubuntu to obtain and configure the certificates:

sudo su
apt update
apt install snapd
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot

Before installing the certificate, make a backup of the current Nginx configuration file located at /etc/nginx/sites-available/default. Certbot may modify this file, so keeping a local copy ensures you can restore it if needed. Once the backup is created, run the following command:

certbot --nginx

This command will install Certbot and automatically configure Nginx to use the obtained certificates. After Nginx is configured, the certificate paths will be set up and will look something like this:

vi /etc/nginx/sites-available/default
 ...
           ssl_certificate /etc/letsencrypt/live/myappname.com/fullchain.pem; # managed by Certbot
           ssl_certificate_key /etc/letsencrypt/live/myappname.com/privkey.pem; # managed by Certbot
           include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
           ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

Update your configuration file to include the Let's Encrypt certificate paths. Find the section where it mentions:

           # Add here the letsencrypt paths

replace this comment with the actual certificate paths:

               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection "upgrade";

               proxy_pass http://deployex;
           }
           ssl_certificate /etc/letsencrypt/live/myappname.com/fullchain.pem; # managed by Certbot
           ssl_certificate_key /etc/letsencrypt/live/myappname.com/privkey.pem; # managed by Certbot
           include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
           ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
       }

Also, ensure that port 443 is enabled for both servers. For example:

      server {
          listen 443 ssl; # managed by Certbot

After modifying the configuration file, save the changes and restart Nginx:

sudo su
vi /etc/nginx/sites-available/default
# modify and save file
systemctl reload nginx

Note

After the changes, It may require a reboot.