-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding terraform template configuration for AWS
- Loading branch information
1 parent
89689db
commit 26b0d5f
Showing
13 changed files
with
1,013 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
name: Publish the project on AWS | ||
|
||
on: | ||
push: | ||
branches: | ||
- test | ||
|
||
jobs: | ||
build: | ||
name: Building a release and version file | ||
runs-on: ubuntu-22.04 | ||
outputs: | ||
tag: ${{ steps.save-tag.outputs.tag }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Setup BEAM | ||
uses: erlef/setup-beam@v1 | ||
with: | ||
version-file: .tool-versions | ||
version-type: strict | ||
rebar3-version: '3.24.0' | ||
|
||
- name: Capture GITHUB_SHORT_SHA | ||
run: | | ||
GITHUB_SHORT_SHA=$(git rev-parse --short ${{ github.sha }}) | ||
echo "GITHUB_SHORT_SHA=${GITHUB_SHORT_SHA}" >> $GITHUB_ENV | ||
- name: Capture and update project mix version | ||
id: save-tag | ||
run: | | ||
GLEAM_VERSION=`grep "version =" gleam.toml | awk -F'"' '{print $2}'` | ||
PROJ_TAG=${GLEAM_VERSION}-${GITHUB_SHORT_SHA} | ||
echo "PROJ_TAG=${PROJ_TAG}" >> $GITHUB_ENV | ||
echo "tag=$PROJ_TAG" >> "$GITHUB_OUTPUT" | ||
echo "Creating the tag: $PROJ_TAG" | ||
- name: Update project gleam version | ||
run: | | ||
sed -i "s/.*version =.*/version = \"${{ env.PROJ_TAG }}\"/" gleam.toml | ||
- name: Install Gleam dependencies | ||
run: gleam deps download | ||
|
||
- name: Generate the release files | ||
run: gleam export erlang-shipment | ||
|
||
- name: Generate tarball to publish | ||
run: | | ||
cd build | ||
tar -czvf cochito-${{ env.PROJ_TAG }}.tar.gz erlang-shipment | ||
- name: Create Release file version | ||
run: | | ||
echo "{\"version\":\"${{ env.PROJ_TAG }}\",\"hash\":\"${GITHUB_SHA}\"}" | jq > current.json | ||
- name: 'Upload release file artifact' | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: release-file | ||
path: build/cochito-${{ env.PROJ_TAG }}.tar.gz | ||
retention-days: 5 | ||
|
||
- name: 'Upload version file artifact' | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: version-file | ||
path: current.json | ||
retention-days: 5 | ||
|
||
upload_aws: | ||
name: Upload files to AWS environment | ||
needs: build | ||
runs-on: ubuntu-22.04 | ||
env: | ||
VERSION_SHA: ${{ needs.build.outputs.tag }} | ||
permissions: | ||
contents: write | ||
steps: | ||
- name: Download version file artefact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: version-file | ||
|
||
- name: Download release file artefact | ||
uses: actions/download-artifact@v4 | ||
with: | ||
name: release-file | ||
|
||
- name: Copy a release file to the s3 distribution folder | ||
uses: prewk/s3-cp-action@v2 | ||
with: | ||
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
aws_region: "us-east-1" | ||
source: "cochito-${VERSION_SHA}.tar.gz" | ||
dest: "s3://cochito-${{ secrets.CLOUD_ENV_NAME }}-distribution/dist/cochito/cochito-${VERSION_SHA}.tar.gz" | ||
|
||
- name: Copy a version file to the s3 version folder | ||
uses: prewk/s3-cp-action@v2 | ||
with: | ||
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
aws_region: "us-east-1" | ||
source: "current.json" | ||
dest: "s3://cochito-${{ secrets.CLOUD_ENV_NAME }}-distribution/versions/cochito/${{ secrets.CLOUD_ENV_NAME }}/current.json" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
erlang 26.1.2 | ||
gleam 1.5.1 | ||
terraform 1.5.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
# 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: | ||
|
||
* Terraform | ||
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) | ||
|
||
### 1. SSH Key Pair | ||
|
||
Create an SSH key pair named, e. g. `cochito-web-ec2` by visiting the [AWS Key Pair page](https://sa-east-1.console.aws.amazon.com/ec2/home?region=sa-east-1#KeyPairs:). Save the private key in your local SSH folder (`~/.ssh`). The name `cochito-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_](./environments/prod/main_example.tf_) to [main.tf](./environments/prod/main.tf) and verify and configure the variables according to your specific environment. Ensure that you also review and update the [variables file](./modules/standard-account/variables.tf). 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: | ||
```bash | ||
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: | ||
|
||
```bash | ||
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](https://console.aws.amazon.com/ec2/home). | ||
|
||
#### Updating Secret Manager | ||
|
||
Navigate to [AWS Secrets Manager](https://console.aws.amazon.com/secretsmanager/listsecrets), locate and update the following secret: | ||
|
||
* *__deployex-cochito-prod-secrets__* | ||
|
||
Click on the secret, then select "Retrieve Secret Value" and edit the secret by adding the new key/value pairs: | ||
|
||
```bash | ||
DEPLOYEX_SECRET_KEY_BASE=xxxxxxxxxx | ||
DEPLOYEX_ERLANG_COOKIE=xxxxxxxxxx | ||
DEPLOYEX_ADMIN_HASHED_PASSWORD=xxxxxxxxxx | ||
``` | ||
|
||
* *__cochito-stage-otp-tls-ca__*, *__cochito-stage-otp-tls-key__*, *__cochito-stage-otp-tls-crt__*: | ||
|
||
Create the TLS certificates for OTP distribution using the [Following script](../../../devops/scripts/tls-distribution-certs), changing the appropriate names and regions inside it. | ||
|
||
```bash | ||
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](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-ranger-tls-certificates.html). | ||
|
||
### 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 cochito-web-ec2.pem saved in `~/.ssh/` | ||
|
||
```bash | ||
ssh -i "cochito-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: | ||
|
||
```bash | ||
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 | ||
```bash | ||
./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: | ||
```bash | ||
ls /usr/local/share/ca-certificates | ||
ca.crt cochito.crt cochito.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: | ||
|
||
```bash | ||
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: | ||
|
||
```bash | ||
vi deployex-config.json | ||
{ | ||
... | ||
"version": "0.3.0-rc15", | ||
"os_target": "ubuntu-22.04", | ||
... | ||
} | ||
``` | ||
|
||
Once the file is updated, run the update command: | ||
```bash | ||
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: | ||
```bash | ||
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: | ||
|
||
```bash | ||
{ | ||
"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: | ||
|
||
* [Guthub Actions - S3 Downloader/Uploader](https://github.com/marketplace/actions/s3-cp) | ||
* [Calori Webserver Example with AWS](https://github.com/thiagoesteves/calori/tree/main/devops/aws/terraform) | ||
|
||
### 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](https://letsencrypt.org/getting-started/). In this example, we'll use [cert bot for ubuntu](https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal) to obtain and configure the certificates: | ||
|
||
```bash | ||
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: | ||
```bash | ||
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: | ||
|
||
```bash | ||
vi /etc/nginx/sites-available/default | ||
... | ||
ssl_certificate /etc/letsencrypt/live/cochito.com/fullchain.pem; # managed by Certbot | ||
ssl_certificate_key /etc/letsencrypt/live/cochito.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: | ||
```bash | ||
# Add here the letsencrypt paths | ||
``` | ||
replace this comment with the actual certificate paths: | ||
```bash | ||
proxy_set_header Upgrade $http_upgrade; | ||
proxy_set_header Connection "upgrade"; | ||
proxy_pass http://deployex; | ||
} | ||
ssl_certificate /etc/letsencrypt/live/cochito.com/fullchain.pem; # managed by Certbot | ||
ssl_certificate_key /etc/letsencrypt/live/cochito.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: | ||
```bash | ||
server { | ||
listen 443 ssl; # managed by Certbot | ||
``` | ||
After modifying the configuration file, save the changes and restart Nginx: | ||
```bash | ||
sudo su | ||
vi /etc/nginx/sites-available/default | ||
# modify and save file | ||
systemctl reload nginx | ||
``` | ||
> [!NOTE] | ||
> After the changes, It may require a reboot. |
Oops, something went wrong.