Inital commit

This commit is contained in:
Alex Pickering 2024-04-17 19:48:28 -05:00
parent 0b425ddbd8
commit ece2007c14
12 changed files with 781 additions and 31 deletions

View File

@ -3,13 +3,19 @@
# binaries
pp=luajit tools/etluapp/etluapp.lua # preprocessor
pack=luajit tools/shpack/shpack.lua # bash script packer
startup_code=$(wildcard src/startup/*.sh.etlua) # startup files that need to be run through the preprocessor
startup_built=$(startup_code:src/startup/%.etlua=build/startup/%) # the files after preprocessing
srcs=$(wildcard src/*.etlua) # other files to run through the preprocessor
data_files=$(wildcard src/data/*)
data_templated=$(wildcard src/data/*.etlua)
data_built=$(data_templated:src/data/%.etlua=build/data/%)
data_copied=$(data_files:src/data/%=build/data/%)
data_immediate=$(filter-out $(data_built),$(data_copied))
built=$(srcs:src/%.etlua=build/%) # other files after preprocessing
ready=$(built) $(startup_built)
ready=$(built) $(startup_built) $(data_built)
all: $(ready)
echo "Ready: $(startup_built)"
@ -21,6 +27,12 @@ $(built): build/% : src/%.etlua config.lua secrets.lua
$(startup_built) : build/startup/% : src/startup/%.etlua config.lua secrets.lua
cat $< | $(pp) > $@
$(data_immediate) : build/data/% : src/data/% config.lua
cp $< $@
$(data_built) : build/data/% : src/data/%.etlua config.lua
cat $< | $(pp) > $@
build/init.tf : config.lua
clean:

View File

@ -1,47 +1,329 @@
-- Configuration!
-- Change this stuff
local e = require "express"
local download = e.download
local immediate = e.immediate
local command = e.command
-- Configuration!
-- Change this stuff!
-- Bits of config
local config = {
aws_region="us-west-2",
domain = "txwea.boo",
subdomain_fmt = "%s.txwea.boo",
domain = "txwea.boo", --domain
subdomain_fmt = "%s.txwea.boo", --how to structure subdomains
version="0.0.1",
bucket_name="txweaboo", --aws s3 bucket, created manually to prevent terraform from trying to delete it.
instance_name="Weaboos Anonymous", -- Name to use for the multimc instance
server_starts="1 16 * * 5", --Starts at 4pm on Fridays
server_stops="1 1 * * 6", --Server stops at 1am on Sundays
}
-- These scripts spin up
-- each vps gets a name, and each vps gets some services. Each services may
-- depend on other services in a directed acyclic graph.
config.services = {
mc = {-- The minecraft server
ports = {25565},
public = true,
},
laminar = { -- A laminar ci/cd server
ports = {8080},
},
web = {-- Web server hosts the mmc instance, the map, ect.
ports = {80, 443},
public = true,
},
ssh = { -- The ssh server into the vpc, so you can bounce to other boxes that may not open ssh directly
ports = {22},
public = true,
},
}
-- Configure services -> machines
-- Each machine gets a startup script, located in src/startup that configures
-- it when the vps starts up for the first time.
config.machines = {
main = {
services = {"mc","laminar","web","ssh"},
size = "t3.nano"
ebs = 500,
size = "t3.medium",
},
sidecar = {
size = "t3.nano",
}
}
-- Minecraft mods!
config.mods = {
shared = {
"https://cdn.modrinth.com/data/P7dR8mSH/versions/xklQBMta/fabric-api-0.97.0%2B1.20.4.jar",
-- Teleportation waystones
"https://cdn.modrinth.com/data/LOpKHB2A/versions/5rsvBzQq/waystones-fabric-1.20.4-16.0.4.jar",
"https://cdn.modrinth.com/data/MBAkmtvl/versions/U79V1VMr/balm-fabric-1.20.4-9.0.7.jar",
-- More potions (and brewing stand tweak)
"https://cdn.modrinth.com/data/n0S5OkPo/versions/VEkp93me/extraalchemy-fabric-1.20.4-1.11.3.jar",
-- Armor trims grant effects
"https://cdn.modrinth.com/data/BL7ADJ7w/versions/Ig73knQu/trimeffects-1.1.1-fabric.jar",
-- Jade is needed on the server for things like horse stats
"https://cdn.modrinth.com/data/nvQzSEkH/versions/fNHCa6bl/Jade-1.20.4-fabric-13.3.1.jar",
-- Item restocking
"https://cdn.modrinth.com/data/mQWkB9ON/versions/HGSYHrgz/stackrefill-1.20.4-4.2.jar",
"https://cdn.modrinth.com/data/e0M1UDsY/versions/n9TNesVV/collective-1.20.4-7.40.jar",
-- Rechisled - decoration
"https://cdn.modrinth.com/data/B0g2vT6l/versions/9RrwNTgN/rechiseled-1.1.5b-fabric-mc1.20.jar",
"https://cdn.modrinth.com/data/LN9BxssP/versions/cp6X3Hrn/supermartijn642configlib-1.1.8a-fabric-mc1.20.2.jar",
"https://cdn.modrinth.com/data/rOUBggPv/versions/wvyQg8qd/supermartijn642corelib-1.1.17-fabric-mc1.20.3.jar",
"https://cdn.modrinth.com/data/p19vrgc2/versions/TIXGDm8a/fusion-1.1.1-fabric-mc1.20.4.jar",
-- Handcrafted - more decoration
"https://cdn.modrinth.com/data/pJmCFF0p/versions/K4jSQsxb/handcrafted-fabric-1.20.4-3.2.1.jar",
"https://cdn.modrinth.com/data/G1hIVOrD/versions/TiIWVg2u/resourcefullib-fabric-1.20.4-2.4.10.jar",
},
server = {
--Aditional Structures
"https://cdn.modrinth.com/data/TWsbC6jW/versions/4aO595R4/AdditionalStructures-1.20.x-%28v.4.2.1%29.jar",
"https://cdn.modrinth.com/data/9s6osm5g/versions/eBZiZ9NS/cloth-config-13.0.121-fabric.jar",
--Yung's *
"https://cdn.modrinth.com/data/Ua7DFN59/versions/RXxBbRs7/YungsApi-1.20.4-Fabric-4.4.2.jar",
"https://cdn.modrinth.com/data/HjmxVlSr/versions/St6cNi1U/YungsBetterMineshafts-1.20.4-Fabric-4.4.1.jar",
"https://cdn.modrinth.com/data/kidLKymU/versions/lT8OssHA/YungsBetterStrongholds-1.20.4-Fabric-4.4.1.jar",
"https://cdn.modrinth.com/data/o1C1Dkj5/versions/8zaPNLL8/YungsBetterDungeons-1.20.4-Fabric-4.4.1.jar",
"https://cdn.modrinth.com/data/Ht4BfYp6/versions/tx2e5Fjp/YungsBridges-1.20.4-Fabric-4.4.0.jar",
"https://cdn.modrinth.com/data/XNlO7sBv/versions/ubWx2R23/YungsBetterDesertTemples-1.20.4-Fabric-3.4.1.jar",
"https://cdn.modrinth.com/data/3dT9sgt4/versions/M9acJ70z/YungsBetterOceanMonuments-1.20.4-Fabric-3.4.1.jar",
"https://cdn.modrinth.com/data/Z2mXHnxP/versions/W7R83Bhr/YungsBetterNetherFortresses-1.20.4-Fabric-2.4.2.jar",
"https://cdn.modrinth.com/data/t5FRdP87/versions/hXyLPxPz/YungsBetterWitchHuts-1.20.4-Fabric-3.4.1.jar",
--Terralith
"https://cdn.modrinth.com/data/cl223EMc/versions/3aypqSNl/cristellib-1.2.4-fabric.jar",
"https://cdn.modrinth.com/data/DjLobEOy/versions/bwfVhUnU/t_and_t-1.12.1.1.jar",
"https://cdn.modrinth.com/data/8oi3bsk5/versions/zA1qYB0L/Terralith_1.20.4_v2.4.11_FABRIC.jar",
--Dungeons and Taverns
"https://cdn.modrinth.com/data/tpehi7ww/versions/xwTzTss5/dungeons-and-taverns-3.1.1.jar",
--Vein miner
"https://cdn.modrinth.com/data/OhduvhIc/versions/DCSFfJF9/Veinminer-2.0.3.jar",
"https://cdn.modrinth.com/data/aTaCgKLW/versions/qm0TSoQL/silk-all-1.10.3.jar",
"https://cdn.modrinth.com/data/Ha28R6CL/versions/ZMokinzs/fabric-language-kotlin-1.10.19%2Bkotlin.1.9.23.jar",
--Profundis
"https://cdn.modrinth.com/data/aucz7XCt/versions/qX0iNakQ/profundis-1.6.2.jar",
--Sleep
"https://cdn.modrinth.com/data/Cw8IlnGM/versions/2LFCQnd1/serversleep-datapack.jar",
-- More structures
"https://cdn.modrinth.com/data/rYlnn25U/versions/qu1FkIzJ/adorabuild-structures-2.6.0-fabric-1.20.4.jar",
-- More structures
"https://cdn.modrinth.com/data/HSfsxuTo/versions/DFkIejTe/explorify-v1.3.0-mc1.20.jar",
-- Inventory sorting
"https://cdn.modrinth.com/data/5ibSyLAz/versions/MO3Q3zs2/InventorySorter-1.9.0-1.20.4.jar",
},
client = {
-- Shaders
"https://cdn.modrinth.com/data/YL57xq9U/versions/kGdJ11Rt/iris-mc1.20.4-1.6.17.jar",
-- Menu tweaks
"https://cdn.modrinth.com/data/aC3cM3Vq/versions/mjuG4AYd/MouseTweaks-fabric-mc1.20-2.26.jar",
-- Light levels
"https://cdn.modrinth.com/data/yjvKidNM/versions/X4PKtqOJ/lighty-fabric-2.2.0%2B1.20.3.jar",
-- Rendering optimizations
"https://cdn.modrinth.com/data/AANobbMI/versions/4GyXKCLd/sodium-fabric-0.5.8%2Bmc1.20.4.jar",
"https://cdn.modrinth.com/data/PtjYWJkn/versions/M0ndiav7/sodium-extra-0.5.4%2Bmc1.20.4-build.116.jar",
-- Search bar for key binds
"https://cdn.modrinth.com/data/xv94TkTM/versions/KFbkZFLx/Controlling-fabric-1.20.4-15.0.3.jar",
"https://cdn.modrinth.com/data/fuuu3xnx/versions/CESw4Xj5/Searchables-fabric-1.20.4-1.0.6.jar",
-- Mod menu
"https://cdn.modrinth.com/data/mOgUt4GM/versions/w3icASIi/modmenu-9.1.0-beta.1.jar",
-- Hunger bar tweaks
"https://cdn.modrinth.com/data/EsAfCjCV/versions/pmFyu3Sz/appleskin-fabric-mc1.20.3-2.5.1.jar",
-- Just enough items
"https://cdn.modrinth.com/data/u6dRKJwZ/versions/HPR5ThoH/jei-1.20.4-fabric-17.3.0.49.jar",
"https://cdn.modrinth.com/data/uEfK2CXF/versions/FjwDwtUL/JustEnoughResources-Fabric-1.20.4-1.5.0.4.jar",
-- Lightmatica - blueprints
"https://cdn.modrinth.com/data/GcWjdA9I/versions/kZJWQDi6/malilib-fabric-1.20.4-0.18.1.jar",
"https://masa.dy.fi/mcmods/litematica/litematica-fabric-1.20.4-0.17.3-pre.1.jar",
"https://cdn.modrinth.com/data/3llatzyE/versions/xeDghx1o/litematica-printer-1.20.4-3.2.1.jar",
},
}
config.mods = {
-- Resource packs to download
config.resource_packs = {
shared = {},
server = {},
client = {},
client = {
-- Redstone tweaks
"https://cdn.modrinth.com/data/RvfAlf4Z/versions/6x5Vyy2c/Redstone%20Tweaks%202.4.3.zip",
},
}
-- Shaders, only makes sense client side
config.shaders = {
shared = {},
server = {},
client = {
-- Minmal
"https://cdn.modrinth.com/data/UaS8ROxa/versions/6iI428Kp/miniature-shader-2.9.1.zip",
-- Maximal
"https://cdn.modrinth.com/data/R6NEzAwj/versions/MCqlWur4/ComplementaryUnbound_r5.1.1.zip",
},
}
-- Patches to apply to the instance
config.config = {
shared = {},
server = {},
client = {
[".minecraft/config/iris.properties"] = immediate([[
#This file stores configuration options for Iris, such as the currently active shaderpack
#Mon Apr 01 00:00:00 CDT 2024
colorSpace=SRGB
disableUpdateMessage=false
enableDebugOptions=false
maxShadowRenderDistance=32
shaderPack=miniature-shader-2.9.1.zip
enableShaders=true
]]),
["instance.cfg"] = immediate(string.format([[
ForgeVersion=
InstanceType=OneSix
IntendedVersion=
JavaArchitecture=64
JavaPath=javaw
JavaTimestamp=1638914208000
JavaVersion=17.0.2
JoinServerOnLaunch=true
JoinServerOnLaunchAddress=%s
JoinSingleplayerWorldOnLaunch=false
JoinWorldOnLaunch=true
LWJGLVersion=
LaunchMaximized=true
LiteloaderVersion=
LogPrePostOutput=true
MCLaunchMethod=LauncherPart
ManagedPack=false
ManagedPackID=
ManagedPackName=
ManagedPackType=
ManagedPackVersionID=
ManagedPackVersionName=
MinecraftWinHeight=480
MinecraftWinWidth=854
OverrideCommands=false
OverrideConsole=false
OverrideGameTime=false
OverrideJavaArgs=false
OverrideJavaLocation=true
OverrideMCLaunchMethod=false
OverrideMemory=false
OverrideNativeWorkarounds=false
OverrideWindow=true
iconKey=default
lastLaunchTime=1712902064290
lastTimePlayed=0
name=%s
notes=
totalTimePlayed=
]], string.format(config.subdomain_fmt,"mc") , config.instance_name)),
[".minecraft/options.txt"] = immediate([[
version:3700
autoJump:false
operatorItemsTab:false
autoSuggestions:true
chatColors:true
chatLinks:true
chatLinksPrompt:true
enableVsync:true
entityShadows:true
forceUnicodeFont:false
discrete_mouse_scroll:false
invertYMouse:false
realmsNotifications:true
reducedDebugInfo:false
showSubtitles:false
directionalAudio:false
touchscreen:false
fullscreen:true
bobView:false
toggleCrouch:false
toggleSprint:false
darkMojangStudiosBackground:false
hideLightningFlashes:false
hideSplashTexts:false
mouseSensitivity:0.5
fov:0.0
screenEffectScale:1.0
fovEffectScale:1.0
darknessEffectScale:1.0
glintSpeed:0.5
glintStrength:0.75
damageTiltStrength:1.0
highContrast:false
narratorHotkey:true
gamma:0.5
renderDistance:12
simulationDistance:12
entityDistanceScaling:1.0
guiScale:2
particles:0
maxFps:120
graphicsMode:1
ao:true
prioritizeChunkUpdates:0
biomeBlendRadius:2
renderClouds:"true"
resourcePacks:["vanilla","fabric","file/Redstone%20Tweaks%202.4.3.zip"]
incompatibleResourcePacks:["appleskin","balm-fabric","controlling","jade","jei","jeresources","rechiseled","searchables","supermartijn642corelib","waystones"]
lastServer:
lang:en_us
soundDevice:""
chatVisibility:0
chatOpacity:1.0
chatLineSpacing:0.0
textBackgroundOpacity:0.5
backgroundForChatOnly:true
hideServerAddress:false
advancedItemTooltips:false
pauseOnLostFocus:true
overrideWidth:0
overrideHeight:0
chatHeightFocused:1.0
chatDelay:0.0
chatHeightUnfocused:0.4375
chatScale:1.0
chatWidth:1.0
notificationDisplayTime:1.0
mipmapLevels:4
useNativeTransport:true
mainHand:"right"
attackIndicator:1
narrator:0
tutorialStep:movement
mouseWheelSensitivity:1.0
rawMouseInput:true
glDebugVerbosity:1
skipMultiplayerWarning:false
skipRealms32bitWarning:false
hideMatchedNames:true
joinedFirstServer:false
hideBundleTutorial:false
syncChunkWrites:true
showAutosaveIndicator:true
allowServerListing:true
onlyShowSecureChat:false
panoramaScrollSpeed:1.0
telemetryOptInExtra:false
onboardAccessibility:false
key_key.attack:key.mouse.left
key_key.use:key.mouse.right
key_key.forward:key.keyboard.w
key_key.left:key.keyboard.a
key_key.back:key.keyboard.s
key_key.right:key.keyboard.d
key_key.jump:key.keyboard.space
key_key.sneak:key.keyboard.left.shift
key_key.sprint:key.keyboard.left.control
key_key.drop:key.keyboard.q
key_key.inventory:key.keyboard.e
key_key.chat:key.keyboard.t
key_key.playerlist:key.keyboard.tab
key_key.pickItem:key.mouse.middle
key_key.command:key.keyboard.slash
key_key.socialInteractions:key.keyboard.p
key_key.screenshot:key.keyboard.f2
key_key.togglePerspective:key.keyboard.f5
key_key.smoothCamera:key.keyboard.unknown
key_key.fullscreen:key.keyboard.f11
key_key.spectatorOutlines:key.keyboard.unknown
key_key.swapOffhand:key.keyboard.f
key_key.saveToolbarActivator:key.keyboard.c
key_key.loadToolbarActivator:key.keyboard.x
key_key.advancements:key.keyboard.l
key_key.hotbar.1:key.keyboard.1
key_key.hotbar.2:key.keyboard.2
key_key.hotbar.3:key.keyboard.3
key_key.hotbar.4:key.keyboard.4
key_key.hotbar.5:key.keyboard.5
key_key.hotbar.6:key.keyboard.6
key_key.hotbar.7:key.keyboard.7
key_key.hotbar.8:key.keyboard.8
key_key.hotbar.9:key.keyboard.9
]])
},
}
-- Validation! Don't change stuff below this line!

24
express.lua Normal file
View File

@ -0,0 +1,24 @@
-- Express configuration more sussunctly
local exp = {}
local types = {
download = {},
immediate = {},
command = {},
}
for name, _ in pairs(types) do
exp[name] = function(v)
return {v, [types[name]] = true}
end
exp["is_" .. name] = function(tbl)
return tbl[types[name]]
end
end
-- Produce a string contains alfanum and underscore
exp.safe = function(s)
return s:gsub("[^A-Za-z0-9]","-")
end
return exp

21
readme.md Normal file
View File

@ -0,0 +1,21 @@
# Readme
This is a little pile of scripts to configure stuff on the AWS cloud.
In general, create a setup script under `src/startup/your_service_name.sh.etlua`,
Then add `your_service_name` to `config.lua` under the `services`, and `machines`.
`your_service_name.sh.etlua` will be preprocessed with [etlua](), then run in a
chroot on the machine configured in `machines`. Everything else is configured
in `src/main.tf.etlua` and should generally not be touched.
### Setup
There are a few one-time set up things:
* Register your domain name, put it in the `config.lua` file
* Create an s3 bucket with any name, and put it's name in the `config.lua` file.
* run make
* Create a hosted zone for your domain name, and set up your registrar with AWS's DNS servers.
* Wait for DNS to resolve
* Connect to the sidecar server, and run certbot:
* while in sidecar server, run `service httpd start` and check that it works in your browser

31
src/data.tf.etlua Normal file
View File

@ -0,0 +1,31 @@
<% local config = require "config" %>
<% local e = require "express" %>
resource "aws_s3_object" "object" {
bucket = "<%- config.bucket_name %>"
key = "instance.zip"
source = "${path.module}/data/instance.zip"
etag = filemd5("${path.module}/data/instance.zip")
}
resource "aws_s3_object" "site" {
bucket = "<%- config.bucket_name %>"
key = "index.html"
source = "${path.module}/data/index.html"
etag = filemd5("${path.module}/data/index.html")
}
<% for filename, value in pairs(config.config.client) do %>
<% if e.is_immediate(value) then %>
resource "aws_s3_object" "config-<%- filename:gsub("[^A-Za-z0-9]","-") %>" {
bucket = "<%- config.bucket_name %>"
key = "<%- filename %>"
content = <<EOS
<%- value[1] %>
EOS
}
<% end %>
<% end %>

66
src/data/index.html.etlua Normal file
View File

@ -0,0 +1,66 @@
<% local config = require "config" %>
<html>
<style>
body{
margin:40px auto;
max-width:650px;
line-height:1.6;
font-size:18px;
color:#444;
padding:0 10px
}
h1,h2,h3{line-height:1.2}
</style>
<script src="https://unpkg.com/cronstrue@latest/dist/cronstrue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/later/1.2.0/later.min.js"></script>
<script>
var starts_sched = "<%- config.server_starts %>";
var stops_sched = "<%- config.server_stops %>";
var starts = later.parse.cron(starts_sched);
var stops = later.parse.cron(stops_sched);
var cronstrue;
var soon_el, starts_el, stops_el;
function msToTime(duration) {
seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
days = Math.floor((duration / (1000 * 60 * 60 * 24) % 7));
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
days = (days < 10) ? "0" + days : days;
return days + ":" + hours + ":" + minutes + ":" + seconds;
}
document.addEventListener("DOMContentLoaded", function(e){
cronstrue = window.cronstrue
soon_el = document.getElementById("soon");
starts_el = document.getElementById("starts");
stops_el = document.getElementById("stops");
starts_el.innerText = cronstrue.toString(starts_sched);
stops_el.innerText = cronstrue.toString(stops_sched);
});
setInterval(function() {
var next_start = later.schedule(starts).next(1);
var next_stop = later.schedule(stops).next(1);
if (next_stop < next_start){
//server's up!
soon_el.innerText = "now!"
}else{
soon_el.innerText = msToTime(next_start - Date.now())
}
}, 1000);
</script>
<h1> Server will come up <span id="soon">when it comes up</span></h1>
<p> Server starts <span id="starts"><%- config.server_starts %></span>
and goes down again <span id="stops"><%- config.server_stops %></span>.
In the meantime, you can download <a href="https://multimc.org/">MultiMC</a>
and add the <a href="/instance.zip">instance</a> so you can play right
away when the server comes up.
</html>

BIN
src/data/instance.zip Normal file

Binary file not shown.

32
src/init.tf.etlua Normal file
View File

@ -0,0 +1,32 @@
<% local secrets = require "secrets" %>
<% local config = require "config" %>
# Things I did manually:
# Added a route to the internet gateway in the route table
terraform {
backend "local" {
path = ".terraform.tfstate"
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.45"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
access_key = "<%- secrets.access_key %>"
secret_key = "<%- secrets.secret_key %>"
region = "<%- config.aws_region %>"
}
<% local domain, tld = string.match(config.domain,"(.*)%.(.*)") %>
# This should be created manually, so it never gets accidentally destroyed.
# resource "aws_s3_bucket" "backup-bucket" {
# bucket = "txweaboo-backup"
# acl = "private"
# }

45
src/machines.tf.etlua Normal file
View File

@ -0,0 +1,45 @@
<% local secrets = require "secrets" %>
<% local config = require "config" %>
<% local ami_lookup = {
aws_linux = "ami-0395649fbe870727e",
}
%>
<% for name, info in pairs(config.machines) do %>
resource "aws_instance" "<%- name %>" {
ami = "<%- ami_lookup.aws_linux %>"
instance_type = "<%- info.size %>"
availability_zone = "<%- config.aws_region %>a"
user_data = file("${path.module}/startup/<%- name %>.sh")
network_interface {
network_interface_id = aws_network_interface.<%- name %>.id
device_index = 0
}
tags = {
Name = "<%- name %> instance"
}
}
<% if info.ebs then %>
resource "aws_ebs_volume" "<%- name %>" {
availability_zone = "<%- config.aws_region %>a"
size = <%- info.ebs %>
type = "st1"
tags = {
Name = "<%- name %> ebs"
}
}
resource "aws_volume_attachment" "<%- name %>" {
device_name = "/dev/sdf"
volume_id = aws_ebs_volume.<%- name %>.id
instance_id = aws_instance.<%- name %>.id
}
<% end %>
<% end %>

104
src/network.tf.etlua Normal file
View File

@ -0,0 +1,104 @@
<% local secrets = require "secrets" %>
<% local config = require "config" %>
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "vpc"
}
}
resource "aws_security_group" "sg" {
name = "allow_traffic"
description = "Allow traffic to the machines"
vpc_id = aws_vpc.vpc.id
ingress {
description = "to vpc"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
description = "from vpc"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "security group"
}
}
resource "aws_subnet" "subnet" {
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.0.0/24"
availability_zone = "<%- config.aws_region %>a"
tags = {
Name = "subnet"
}
}
<% local private_ip = 10 %>
<% for name, info in pairs(config.machines) do %>
<% assert(name ~= "internal", "config.machines may contain a machine named 'internal'") %>
resource "aws_network_interface" "<%- name %>" {
subnet_id = aws_subnet.subnet.id
private_ips = ["10.0.0.<%- private_ip %>"]
<% private_ip = private_ip + 1 %>
security_groups = [aws_security_group.sg.id]
source_dest_check = false
tags = {
Name = "<%- name %> network interface"
}
}
resource "aws_eip" "<%- name %>" {
vpc = true
network_interface = aws_network_interface.<%- name %>.id
associate_with_private_ip = "10.0.0.<%- private_ip - 1 %>"
tags = {
Name = "<%- name %> ip"
}
}
<% end %>
resource "aws_main_route_table_association" "main" {
vpc_id = aws_vpc.vpc.id
route_table_id = aws_route_table.rt.id
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "Internet gateway"
}
}
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "Route table"
}
}
resource "aws_route53_zone" "main" {
name = "<%- config.domain %>"
}
resource "aws_route53_record" "www" {
zone_id = aws_route53_zone.main.zone_id
name = "<%- config.domain %>"
type = "A"
ttl = 300
records = [aws_eip.sidecar.public_ip]
}
resource "aws_route53_record" "mc" {
zone_id = aws_route53_zone.main.zone_id
name = "<%- string.format(config.subdomain_fmt, 'mc') %>"
type = "A"
ttl = 300
records = [aws_eip.main.public_ip]
}

43
src/startup/main.sh.etlua Normal file
View File

@ -0,0 +1,43 @@
#!/bin/bash
<% local config = require "config" %>
<% local secrets = require "secrets" %>
exec 1>>~/message.log 2>&1
set -x
echo "Starting main" >> ~/message.log
aws configure set aws_access_key_id "<%- secrets.access_key %>"
aws configure set aws_secret_access_key "<%- secrets.secret_key %>"
mkdir /mnt
mount /dev/sdf /mnt
sudo yum install java-17-amazon-corretto-devel -y
cd /mnt
UA="User-Agent: tempmc (alex@cogarr.net)"
# Download the dedicated server if we don't have it
if [ ! -e fabric-server-mc.1.20.4-loader.0.15.9-launcher.1.0.0.jar ]; then
echo "Downloading fabricmc" >> ~/message.log
curl -OJ https://meta.fabricmc.net/v2/versions/loader/1.20.4/0.15.9/1.0.0/server/jar
# Run it to download the mojang jar
java -Xmx2G -jar fabric-server-mc.1.20.4-loader.0.15.9-launcher.1.0.0.jar nogui --nogui
# It will error out because we haven't accepted the eula
sed -i s/eula=false/eula=true/g eula.txt
fi
# Then download mods
cd mods
echo "Downloading <%- #config.mods.server %> mods" >> ~/message.log
<% for _,mod in pairs(config.mods.server) do %>
URL=<%- mod %>
echo "Checking $(basename $URL)" >> ~/message.log
if [ ! -e "$(basename $URL)" ]; then
echo "Downloading $URL" >> ~/message.log
curl -OJ "$URL"
else
echo "$URL already exists" >> ~/message.log
fi
<% end %>

View File

@ -0,0 +1,90 @@
#!/bin/bash
<% local config = require "config" %>
<% local secrets = require "secrets" %>
<% local e = require "express" %>
exec 1>>~/message.log 2>&1
set -x
echo "Hello, sidecar!" >> ~/message.log
cd ~
sudo yum install certbot cronie httpd mod_ssl -y
cat > /etc/httpd/conf.d/ssl.conf<< EOF
LoadModule ssl_module modules/mod_ssl.so
Listen 443
<VirtualHost *:443>
ServerName <%- config.domain %>
SSLEngine on
SSLCertificateFile "/etc/letsencrypt/live/<%- config.domain %>/fullchain.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/<%- config.domain %>/privkey.pem"
</VirtualHost>
EOF
aws configure set aws_access_key_id "<%- secrets.access_key %>"
aws configure set aws_secret_access_key "<%- secrets.secret_key %>"
# Scripts that start and stop the main instance
cat > start.sh<< EOF
EID=$(aws ec2 describe-instances | jq -r ".Reservations[].Instances[] | select(.Tags[].Value == \"main instance\").InstanceId")
aws ec2 start-instances --instance-ids $EID
EOF
cat > stop.sh<< EOF
EID=$(aws ec2 describe-instances | jq -r ".Reservations[].Instances[] | select(.Tags[].Value == \"main instance\").InstanceId")
aws ec2 stop-instances --instance-ids $EID
EOF
# Download the multimc instance from s3
aws s3 cp s3://<%- config.bucket_name %>/instance.zip .
unzip instance.zip
cd instance/.minecraft/mods
# Set up mods, shaders, datapacks, ect.
<% for _, mod in pairs(config.mods.client) do %>
URL=<%- mod %>
if [ ! -e $(basename $URL) ]; then
echo "Downloading $URL"
curl -JO $URL
fi
<% end %>
cd ../resourcepacks
<% for _, resource_pack in pairs(config.resource_packs.client) do %>
URL=<%- resource_pack %>
if [ ! -e $(basename $URL) ]; then
echo "Downloading $URL"
curl -JO $URL
fi
<% end %>
cd ../shaderpacks
<% for _, shader in pairs(config.shaders.client) do %>
URL=<%- shader %>
if [ ! -e $(basename $URL) ]; then
echo "Downloading $URL"
curl -JO $URL
fi
<% end %>
<% for filename, info in pairs(config.config.client) do %>
<% if e.is_immediate(info) then %>
aws s3 cp s3://<%- config.bucket_name %>/<%- filename %> <%- filename %>
<% elseif e.is_command(info) then %>
<%- info[1] %>
<% end %>
<% end %>
# Set up a crontab to start and stop the main server on a schedule
# Then re-zip the instance, and serve a webpage
cd ~
zip -r instance instance
cp instance.zip /var/www/html
aws s3 cp s3://<%- config.bucket_name %>/index.html /var/www/html/index.html
service httpd start