Skip to content

Instantly share code, notes, and snippets.

@sakirtemel
Last active December 22, 2022 02:08
Show Gist options
  • Save sakirtemel/236a4f71f53d0e1ca9d4121e86b37fbc to your computer and use it in GitHub Desktop.
Save sakirtemel/236a4f71f53d0e1ca9d4121e86b37fbc to your computer and use it in GitHub Desktop.
#!/bin/bash
# <UDF name="SSL_CERTIFICATE" label="CLOUDFLARE_SSL_CERTIFICATE" example="public key" default="">
# <UDF name="SSL_CERTIFICATE_KEY" label="CLOUDFLARE_SSL_CERTIFICATE_KEY" example="private key" default="">
# stop the script if any error occurs
set -o errexit
set -o nounset
# don't ask yes/no questions, just continue
export DEBIAN_FRONTEND=noninteractive
# get the latest updates, install some fundamentals and enable automated security updates
apt-get update && apt-get upgrade -y
apt-get install -y ntp fail2ban unattended-upgrades
ln -fs /usr/share/zoneinfo/UTC /etc/localtime
dpkg-reconfigure -f noninteractive tzdata
echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | debconf-set-selections
dpkg-reconfigure -f noninteractive unattended-upgrades
# add a default non-root user: ubuntu
adduser --disabled-password --gecos "" --shell /bin/bash ubuntu
chpasswd <<<"ubuntu:ubuntu"
usermod -aG sudo ubuntu
# install docker and docker compose
apt-get install -y docker.io docker-compose
systemctl enable --now docker
usermod -aG docker ubuntu
# enable linux level firewall
ufw allow in https
ufw default deny incoming
ufw enable
# disable ssh, we're going to access via LiSH console
systemctl disable ssh
systemctl stop ssh
# save the certificates as files
echo "$SSL_CERTIFICATE" > ssl_certificate.pem
echo "$SSL_CERTIFICATE_KEY" > ssl_certificate.key
# LINODE_TOKEN is set as a workspace variable in Terraform Cloud
provider "linode" {
}
resource "linode_firewall" "backend_firewall" {
label = "backend_firewall"
# cloudflare ip addresses, only allow traffic coming through cloudflare and over https
inbound {
label = "allow-https"
action = "ACCEPT"
protocol = "TCP"
ports = "443"
ipv4 = ["173.245.48.0/20", "103.21.244.0/22", "103.22.200.0/22", "103.31.4.0/22", "141.101.64.0/18", "108.162.192.0/18", "190.93.240.0/20", "188.114.96.0/20", "197.234.240.0/22", "198.41.128.0/17", "162.158.0.0/15", "104.16.0.0/13", "104.24.0.0/14", "172.64.0.0/13", "131.0.72.0/22"]
}
inbound_policy = "DROP"
outbound_policy = "ACCEPT"
linodes = [linode_instance.backend_prod.id]
}
resource "linode_stackscript" "backend" {
label = "backend"
description = "Backend init script"
script = file("${path.module}/backend_stackscript.sh")
images = ["linode/ubuntu22.04"]
rev_note = "initial version"
}
resource "random_password" "password" {
length = 16
special = true
override_special = "!#$%&*()-_=+[]{}<>:?"
}
# authorized_keys is not important actually it's needed by linode. just generate anything and put the public one here (https://8gwifi.org/sshfunctions.jsp)
resource "linode_instance" "backend_prod" {
image = "linode/ubuntu22.04"
label = "backend-prod"
group = "Terraform"
region = "us-west"
type = "g6-standard-1"
authorized_keys = [ "YOUR_LOCAL_PUBLIC_SSH_KEY" ]
root_pass = random_password.password.result
stackscript_id = linode_stackscript.backend.id
stackscript_data = {
"SSL_CERTIFICATE" = var.SSL_CERTIFICATE
"SSL_CERTIFICATE_KEY" = var.SSL_CERTIFICATE_KEY
}
}
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream backend {
server 127.0.0.1:3000 fail_timeout=0;
}
server {
listen 443;
ssl on;
ssl_certificate /root/ssl_certificate.pem;
ssl_certificate_key /root/ssl_certificate.key;
location / {
proxy_pass http://backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
client_max_body_size 100m;
client_body_buffer_size 128k;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
}
variable "SSL_CERTIFICATE" {
type = string
}
variable "SSL_CERTIFICATE_KEY" {
type = string
}
terraform {
cloud {
organization = "YOUR_TERRAFORM_CLOUD_ORGANIZATION_NAME"
workspaces {
name = "YOUR_TERRAFORM_CLOUD_WORKSPACE"
}
}
required_providers {
linode = {
source = "linode/linode"
version = ">= 1.29.2"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment