This guide demonstrates how to deploy DeployEx in Amazon Web Services (AWS) using Terraform to programmatically set up the environment.
To begin, ensure the following applications are installed:
- Terraform
- AWS CLI
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.
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") |
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.
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.
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.
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
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.
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
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
Here are some useful resources with suggestions on how to automate the upload of version and release files to your environment using GitHub Actions:
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.