Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws: add ec2 deployment #5

Merged
merged 4 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ This repo is using [Opentofu](https://opentofu.org/) and other tools to create c

## Platform Support Status

| | VM | Docker | K8s |
| --------------------- | ------ | ------ | ---- |
| Microsoft Azure | VM ✅ | ACI 🔲 | AKS 🔲 |
| Amazon Web Services | EC2 🚧 | ECS 🔲 | EKS 🔲 |
| Google Cloud Platform | GCE 🔲 | GAE 🔲 | GKE 🔲 |
| Render | ❌ | DOCKER ✅(See 1) | ❌ |
| Heroku | ❌ | HCR 🔲 | ❌ |
| DigitalOcean | Droplets 🔲 | CR 🔲 | DOKS 🔲 |
| Native K8s | ❌ | ❌ | K8S ✅(See 2) |
| | VM | Docker | K8s |
|-----------------------|-------------|-----------------|--------------|
| Microsoft Azure | VM ✅ | ACI 🔲 | AKS 🔲 |
| Amazon Web Services | EC2 | ECS 🔲 | EKS 🔲 |
| Google Cloud Platform | GCE 🚧 | GAE 🔲 | GKE 🔲 |
| Render | ❌ | DOCKER ✅(See 1) | ❌ |
| Heroku | ❌ | HCR 🔲 | ❌ |
| DigitalOcean | Droplets 🔲 | CR 🔲 | DOKS 🔲 |
| Native K8s | ❌ | ❌ | K8S ✅(See 2) |

The following icons are used to represent the status of support for each platform:
- ✅: completed
Expand Down
16 changes: 16 additions & 0 deletions modules/aws-ec2/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
GTFS_URL=https://api.cityofkingston.ca/gtfs/gtfs.zip
TEST_API_KEY=test
VEHICLE_POSITIONS_URL=https://api.cityofkingston.ca/gtfs-realtime/vehicleupdates.pb
TRIP_UPDATES_URL=https://api.cityofkingston.ca/gtfs-realtime/tripupdates.pb
ALERTS_URL=https://api.cityofkingston.ca/gtfs-realtime/alerts.pb
REFRESH_INTERVAL=30
AGENCY_ID=Kingston Transit
TZ=America/Toronto
GOOGLE_MAPS_API_KEY=<YOUR_GOOGLE_MAPS_API_KEY>
GOOGLE_MAPS_CHANNEL_ID=<YOUR_GOOGLE_MAPS_CHANNEL_ID>
GOOGLE_MAPS_CLIENT_ID=<YOUR_GOOGLE_MAPS_CLIENT_ID>
# Your Domain Name, leave blank if you don't have one
DOMAIN=oba.example.com
# OBA image version. You can find the available versions at:
# https://hub.docker.com/r/opentransitsoftwarefoundation/onebusaway-api-webapp/tags
OBA_VERSION=latest
82 changes: 82 additions & 0 deletions modules/aws-ec2/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions modules/aws-ec2/docker-compose.caddy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3'

services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- caddy_data:/data
restart: unless-stopped

volumes:
caddy_data: {}
37 changes: 37 additions & 0 deletions modules/aws-ec2/init.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# install Docker Compose
curl -L "https://github.com/docker/compose/releases/download/v2.27.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

cd /home/${user}

# clone repo
git clone https://github.com/onebusaway/onebusaway-docker.git

cd /home/${user}/onebusaway-docker

# create .env file
echo "${docker_env}" > .env


# onebusaway-api-webapp depends on mysql, normally this will handle by docker-compose
# but in Azure, the mysql container will not be ready when onebusaway-api-webapp starts
# which leads to the error `Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set`
# so we need to start mysql container first
docker-compose -f docker-compose.prod.yml up -d oba_database

sleep 5s

# start Docker Compose
docker-compose -f docker-compose.prod.yml up -d

if [ -n "${caddy}" ]; then
# create docker-compose.caddy.yml
echo "${docker_compose}" > docker-compose.caddy.yml
# start Caddy
docker-compose -f docker-compose.caddy.yml up -d
fi
153 changes: 153 additions & 0 deletions modules/aws-ec2/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
provider "aws" {
region = var.region
}

resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}


resource "aws_security_group" "main" {
vpc_id = aws_vpc.main.id
name = var.security_group_name

ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "HTTP on 8080"
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}

resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
}

resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.main.id
route_table_id = aws_route_table.public.id
}

resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = var.availability_zone
map_public_ip_on_launch = true
}

resource "aws_key_pair" "ssh_key" {
key_name = "ec2-key-pair"
public_key = tls_private_key.ssh_key.public_key_openssh
}

resource "aws_instance" "main" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
key_name = aws_key_pair.ssh_key.key_name
vpc_security_group_ids = [aws_security_group.main.id]
subnet_id = aws_subnet.main.id
associate_public_ip_address = true

user_data = base64encode(templatefile("${path.module}/init.tpl", {
user = var.username,
caddy = var.caddy,
docker_compose = file("${path.module}/docker-compose.caddy.yml"),
docker_env = file("${path.module}/.env")
}))
}

resource "tls_private_key" "ssh_key" {
algorithm = "RSA"
rsa_bits = 4096
}

resource "local_sensitive_file" "private_key" {
content = tls_private_key.ssh_key.private_key_pem
filename = "${path.module}/ssh/id_rsa"
}

# Only use this resource if you are using Linux or MacOS
resource "null_resource" "set_permission" {
depends_on = [local_sensitive_file.private_key]

provisioner "local-exec" {
command = "chmod 0600 ${local_sensitive_file.private_key.filename}"
}
}

resource "local_file" "public_key" {
content = tls_private_key.ssh_key.public_key_openssh
filename = "${path.module}/ssh/id_rsa.pub"
}

# Fetch the latest Ubuntu Server AMI for the provided region and instance type
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}
}

# Remove ssh keys after destroy
resource "null_resource" "remove_ssh_keys" {
triggers = {
always_run = timestamp()
}

# replace `rm` with `del` if you are using Windows
provisioner "local-exec" {
command = "rm ${path.module}\\ssh\\id_rsa ${path.module}\\ssh\\id_rsa.pub"
when = destroy
}
}


9 changes: 9 additions & 0 deletions modules/aws-ec2/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "private_ip" {
value = aws_instance.main.private_ip
description = "The private IP address of the EC2 instance."
}

output "public_ip" {
value = aws_instance.main.public_ip
description = "The public IP address of the EC2 instance."
}
Loading