diff --git a/Makefile b/Makefile index 241e532..001e0ac 100644 --- a/Makefile +++ b/Makefile @@ -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: diff --git a/config.lua b/config.lua index 204f904..9c298f5 100644 --- a/config.lua +++ b/config.lua @@ -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! diff --git a/express.lua b/express.lua new file mode 100644 index 0000000..a07845f --- /dev/null +++ b/express.lua @@ -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 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..0124f11 --- /dev/null +++ b/readme.md @@ -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 diff --git a/src/data.tf.etlua b/src/data.tf.etlua new file mode 100644 index 0000000..0cfdaf6 --- /dev/null +++ b/src/data.tf.etlua @@ -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 +} + <% end %> +<% end %> diff --git a/src/data/index.html.etlua b/src/data/index.html.etlua new file mode 100644 index 0000000..53a215b --- /dev/null +++ b/src/data/index.html.etlua @@ -0,0 +1,66 @@ +<% local config = require "config" %> + + + + + + +

Server will come up when it comes up

+

Server starts <%- config.server_starts %> + and goes down again <%- config.server_stops %>. + In the meantime, you can download MultiMC + and add the instance so you can play right + away when the server comes up. + diff --git a/src/data/instance.zip b/src/data/instance.zip new file mode 100644 index 0000000..f449153 Binary files /dev/null and b/src/data/instance.zip differ diff --git a/src/init.tf.etlua b/src/init.tf.etlua new file mode 100644 index 0000000..9f17273 --- /dev/null +++ b/src/init.tf.etlua @@ -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" +# } diff --git a/src/machines.tf.etlua b/src/machines.tf.etlua new file mode 100644 index 0000000..31c8d3e --- /dev/null +++ b/src/machines.tf.etlua @@ -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 %> diff --git a/src/network.tf.etlua b/src/network.tf.etlua new file mode 100644 index 0000000..67f57b8 --- /dev/null +++ b/src/network.tf.etlua @@ -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] +} diff --git a/src/startup/main.sh.etlua b/src/startup/main.sh.etlua new file mode 100644 index 0000000..1a6f10c --- /dev/null +++ b/src/startup/main.sh.etlua @@ -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 %> diff --git a/src/startup/sidecar.sh.etlua b/src/startup/sidecar.sh.etlua new file mode 100644 index 0000000..fbf6360 --- /dev/null +++ b/src/startup/sidecar.sh.etlua @@ -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 + + ServerName <%- config.domain %> + SSLEngine on + SSLCertificateFile "/etc/letsencrypt/live/<%- config.domain %>/fullchain.pem" + SSLCertificateKeyFile "/etc/letsencrypt/live/<%- config.domain %>/privkey.pem" + +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