Compare commits

...

6 Commits

13 changed files with 123 additions and 156 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
.*.sw?
toclerbe
data/
.terraform

1
.tool-versions Normal file
View File

@ -0,0 +1 @@
opentofu 1.8.0

View File

@ -8,6 +8,7 @@ RUN nimble build -y
FROM alpine
EXPOSE 80
RUN apk -v --update add --no-cache pcre
RUN mkdir -p /data
COPY --from=build /toclerbe/toclerbe /

View File

@ -4,6 +4,8 @@ ECR_ACCOUNT_URL ?= 063932952339.dkr.ecr.us-west-2.amazonaws.com
VERSION ?=`git describe`
PORT ?= 8080
TARGET_SERVER ?= sobeck.jdb-software.com
default: serve-docker
build: $(SOURCES)
@ -22,13 +24,27 @@ build-image: $(SOURCES)
push-image: build-image
docker push $(ECR_ACCOUNT_URL)/toclerbe:$(VERSION)
serve-docker: build-image start-postgres
serve-docker: build-image
docker run \
-v "data:/data" \
-e TOCLERBE_PORT=80 \
-e TOCLERBE_API_KEYS=qwertyasdfgh
-e TOCLERBE_API_KEYS=qwertyasdfgh \
-e "ISSUER=$(ISSUER)" \
-p 127.0.0.1:$(PORT):80/tcp \
$(ECR_ACCOUNT_URL)/toclerbe:$(VERSION)
ecr-auth:
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin $(ECR_ACCOUNT_URL)
publish:
-mkdir deploy
m4 -D "TOCLERBE_VERSION=$(VERSION)" \
toclerbe.service \
> deploy/toclerbe.service
-ssh deployer@$(TARGET_SERVER) "docker stop toclerbe.service && sudo systemctl stop toclerbe"
ssh deployer@$(TARGET_SERVER) "aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $(ECR_ACCOUNT_URL) && docker pull $(ECR_ACCOUNT_URL)/toclerbe:$(VERSION)"
scp \
deploy/toclerbe.service \
deployer@$(TARGET_SERVER):/etc/systemd/system/toclerbe.service
ssh deployer@$(TARGET_SERVER) "sudo systemctl daemon-reload"
ssh deployer@$(TARGET_SERVER) "sudo systemctl start toclerbe"

View File

@ -1,84 +0,0 @@
resource "aws_secretsmanager_secret" "toclerbe" {
name = "${var.app_name}-config"
}
resource "aws_efs_mount_target" "ortis" {
file_system_id = data.terraform_remote_state.jdbsoft.outputs.sobeck-efs.id
subnet_id = data.terraform_remote_state.jdbsoft.outputs.aws_subnet_private2.id
security_groups = [ data.terraform_remote_state.jdbsoft.outputs.aws_security_group_private_traffic.id ]
}
resource "aws_ecs_task_definition" "toclerbe" {
family = var.app_name
network_mode = "bridge"
requires_compatibilities = ["EC2"]
execution_role_arn = aws_iam_role.ecs_task.arn
# See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html
container_definitions = jsonencode([
{
name = var.app_name
image = "${aws_ecr_repository.toclerbe.repository_url}:${data.external.git_describe.result.version}"
cpu = 128
memory = 128
memoryReservation = 32
environment = [
{
name = "TOCLERBE_PORT"
value = "80"
}
]
mountPoints = [
{
containerPath = "/data"
sourceVolume = "efs-toclerbe-data"
}
]
portMappings = [
{
protocol = "tcp"
containerPort = 80
}
]
secrets = [
{
name = "API_KEYS"
description = "API keys allowed to configure the service.."
valueFrom = "${aws_secretsmanager_secret.toclerbe.arn}:apiKeys::"
}
]
}
])
volume {
name = "efs-toclerbe-data"
efs_volume_configuration {
file_system_id = data.terraform_remote_state.jdbsoft.outputs.sobeck-efs.id
root_directory = "/toclerbe/data"
}
}
tags = {
Name = var.app_domain
}
}
resource "aws_ecs_service" "toclerbe" {
name = var.app_name
cluster = data.terraform_remote_state.jdbsoft.outputs.aws_ecs_cluster_ortis.id
task_definition = aws_ecs_task_definition.toclerbe.arn
desired_count = 1
launch_type = "EC2"
load_balancer {
target_group_arn = aws_lb_target_group.toclerbe.arn
container_name = var.app_name
container_port = 80
}
tags = {
Name = var.app_domain
}
}

View File

@ -1,68 +0,0 @@
resource "aws_iam_role" "ecs_task" {
name = "${var.app_name}-EcsTaskRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
inline_policy {
name = "AllowSecretsAccessFor${var.app_name}Tasks"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"secretsmanager:GetSecretValue",
"kms:Decrypt"
]
Resource = [
aws_secretsmanager_secret.toclerbe.arn
]
}
]
})
}
inline_policy {
name = "AllowAccessToEcrFor${var.app_name}Tasks"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecr:GetAuthorizationToken"
]
Resource = [ "*" ]
},
{
Effect = "Allow"
Action = [
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:DescribeImages",
"ecr:GetDownloadUrlForLayer"
]
Resource = [
aws_ecr_repository.toclerbe.arn
]
}
]
})
}
tags = {
Name = "${var.app_name}-EcsTaskRole"
}
}

View File

@ -39,3 +39,14 @@ resource "aws_lb_listener_rule" "toclerbe" {
Name = "${var.app_domain} HTTPS"
}
}
resource "aws_lb_listener_certificate" "toclerbe" {
listener_arn = data.terraform_remote_state.jdbsoft.outputs.aws_lb_listener_https.arn
certificate_arn = aws_acm_certificate.clerbe.arn
}
resource "aws_lb_target_group_attachment" "toclerbe" {
target_group_arn = aws_lb_target_group.toclerbe.arn
target_id = data.terraform_remote_state.jdbsoft.outputs.sobeck-instance-id
port = 6001
}

View File

@ -0,0 +1,52 @@
resource "aws_route53_zone" "clerbe" {
name = "cler.be"
comment = "Short domain for JDB Software services."
}
// ===========================================================================
// Routes and certificates defined on cler.be
// ===========================================================================
resource "aws_route53_record" "to_clerbe" {
name = "to.cler.be"
type = "A"
zone_id = aws_route53_zone.clerbe.id
alias {
evaluate_target_health = true
name = data.terraform_remote_state.jdbsoft.outputs.aws_lb_jdbsoft.dns_name
zone_id = data.terraform_remote_state.jdbsoft.outputs.aws_lb_jdbsoft.zone_id
}
}
resource "aws_acm_certificate" "clerbe" {
domain_name = "*.cler.be"
subject_alternative_names = [ "cler.be" ]
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "clerbe_cert_validation" {
for_each = {
for dvo in aws_acm_certificate.clerbe.domain_validation_options: dvo.domain_name => {
name = dvo.resource_record_name
type = dvo.resource_record_type
record = dvo.resource_record_value
}
}
allow_overwrite = true
name = each.value.name
records = [ each.value.record ]
ttl = 300
type = each.value.type
zone_id = aws_route53_zone.clerbe.zone_id
}
resource "aws_acm_certificate_validation" "clerbe" {
certificate_arn = aws_acm_certificate.clerbe.arn
validation_record_fqdns = [for record in aws_route53_record.clerbe_cert_validation : record.fqdn]
}

2
prod.env Normal file
View File

@ -0,0 +1,2 @@
TOCLERBE_PORT=80
TOCLERBE_API_KEYS=CHANGEME

16
server-setup.sh Normal file
View File

@ -0,0 +1,16 @@
# From dev machine
cd ~/projects/to.cler.be
scp prod.env sobeck.jdb-software.com:~/temp/to.cler.be.prod.env
scp to.cler.be.service sobeck.jdb-software.com:~/temp/to.cler.be.service
# SSH into sobeck
sudo mkdir /etc/to.cler.be
sudo mv temp/to.cler.be.prod.env /etc/to.cler.be/prod.env
sudo mv temp/toclerbe.service /etc/systemd/system/toclerbe.service
sudo chown root:root /etc/to.cler.be/*
sudo vim /etc/to.cler.be/prod.env # add value for API keys, etc.
sudo systemctl daemon-reload
sudo systemctl enable toclerbe
sudo systemctl start toclerbe

View File

@ -1,4 +1,4 @@
const TOCLERBE_VERSION* = "0.1.0"
const TOCLERBE_VERSION* = "0.2.0"
const USAGE* = """
Usage:

View File

@ -1,6 +1,6 @@
# Package
version = "0.1.0"
version = "0.2.0"
author = "Jonathan Bernard"
description = "Jonathan's custom URL shortener/bookmark service."
license = "MIT"

18
toclerbe.service Normal file
View File

@ -0,0 +1,18 @@
[Unit]
Description=to.cler.be URL shortener
After=network-online.target
Requires=docker.service
[Service]
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker exec %n stop
ExecStartPre=-/usr/bin/docker rm %n
ExecStart=/usr/bin/docker run --rm -p 6001:80 --name %n \
--env-file /etc/to.cler.be/prod.env \
-v /efs/toclerbe/data:/data \
063932952339.dkr.ecr.us-west-2.amazonaws.com/to.cler.be:TOCLERBE_VERSION
ExecStop=/usr/bin/docker stop --name %n
[Install]
WantedBy=default.target