From ea46b13a1727c9324530a05b9a3880bd7e52c888 Mon Sep 17 00:00:00 2001 From: Pijus Kamandulis Date: Fri, 28 Jan 2022 18:02:57 +0200 Subject: [PATCH] Initial commit --- .gitignore | 21 +++ ansible/main.yml | 158 ++++++++++++++++++++++ ansible/static_files/7days.j2 | 8 ++ ansible/static_files/7days.service.j2 | 19 +++ ansible/static_files/serverconfig.xml | 127 +++++++++++++++++ ansible/static_files/serverconfig_3rd.xml | 125 +++++++++++++++++ ansible/stop.yml | 28 ++++ down.sh | 24 ++++ setup_environment.sh | 31 +++++ terraform_pl/.terraform.lock.hcl | 24 ++++ terraform_pl/main.tf | 105 ++++++++++++++ terraform_pl/outputs.tf | 4 + terraform_pl/variables.tf | 40 ++++++ up.sh | 24 ++++ 14 files changed, 738 insertions(+) create mode 100644 .gitignore create mode 100644 ansible/main.yml create mode 100644 ansible/static_files/7days.j2 create mode 100644 ansible/static_files/7days.service.j2 create mode 100644 ansible/static_files/serverconfig.xml create mode 100644 ansible/static_files/serverconfig_3rd.xml create mode 100644 ansible/stop.yml create mode 100644 down.sh create mode 100644 setup_environment.sh create mode 100644 terraform_pl/.terraform.lock.hcl create mode 100644 terraform_pl/main.tf create mode 100644 terraform_pl/outputs.tf create mode 100644 terraform_pl/variables.tf create mode 100644 up.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a324770 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Binaries +/bin +*.exe + +/key +/key.pub + +# Terraform +## Local .terraform directories +**/.terraform/* + +## .tfstate files +*.tfstate +*.tfstate.* + +## Crash log files +crash.log +crash.*.log + +# Ansible +venv/ \ No newline at end of file diff --git a/ansible/main.yml b/ansible/main.yml new file mode 100644 index 0000000..4ed4a40 --- /dev/null +++ b/ansible/main.yml @@ -0,0 +1,158 @@ +--- +# Install required dependancies +- hosts: '{{ target | default("all") }}' + become: yes + become_method: sudo + tasks: + + - name: Install aptitude + apt: pkg=aptitude state=present update_cache=true + + - name: Configure the package manager to include accommodations for i386 architecture + shell: dpkg --add-architecture i386 + ignore_errors: True + + - name: apt update + apt: update-cache=yes cache_valid_time=3600 + retries: 3 + delay: 1 + ignore_errors: yes + register: apt_updated + + - name: apt safe upgrade + apt: upgrade=safe + delay: 1 + ignore_errors: yes + register: apt_upgraded + + - name: check if reboot is required + stat: path=/var/run/reboot-required + register: rb + + - name: Reboot if necessary + reboot: + reboot_timeout: 3600 + ignore_errors: true + when: rb.stat.exists + + - name: Delete reboot-required file + file: + path: /var/run/reboot-required + state: absent + ignore_errors: true + + - name: Install requisite 32-bit libraries + apt: + name: "{{ packages }}" + state: present + update_cache: yes + vars: + packages: + - lib32gcc-s1 + - netcat + +# Mount data drive +- hosts: '{{ target | default("all") }}' + become: yes + become_method: sudo + tasks: + + - name: Create a ext4 filesystem on /dev/vdb and check disk blocks + community.general.filesystem: + fstype: ext4 + dev: /dev/vdb + state: present + + - name: Mount up device by label + ansible.posix.mount: + path: /data + src: /dev/vdb + fstype: ext4 + state: present + +# Download steamcmd +- hosts: '{{ target | default("all") }}' + become: yes + become_method: sudo + vars: + ssh_user: debian + url: http://media.steampowered.com/installer/steamcmd_linux.tar.gz + tasks: + + - name: Sets Steam folder + file: path=/data/Steam owner={{ssh_user}} group={{ssh_user}} state=directory mode=0775 + ignore_errors: True + + - stat: path=/data/Steam/steamcmd.sh + register: steamcmd_dir + + - name: Download SteamCMD + get_url: + url: "{{url}}" + dest: /data/Steam/steamcmd_linux.tar.gz + mode: '0664' + #when: not steamcmd_dir.stat.exists + + - name: Unarchive SteamCMD + unarchive: + src: /data/Steam/steamcmd_linux.tar.gz + dest: /data/Steam + remote_src: yes + creates: /data/Steam/steamcmd.sh + #when: not steamcmd_dir.stat.exists + + - name: Delete file steamcmd_linux.tar.gz + file: + path: /data/Steam/steamcmd_linux.tar.gz + state: absent + +# SteamCMD game server setup +- hosts: '{{ target | default("all") }}' + vars: + ssh_user: debian + become: yes + become_method: sudo + become_user: "{{ssh_user}}" + tasks: + + - name: Sets Steam folder + file: path=/data/Steam owner={{ssh_user}} group={{ssh_user}} state=directory mode=0775 + ignore_errors: True + + - name: Create game script + template: src=static_files/7days.j2 dest=/data/Steam/7days.txt owner={{ssh_user}} group={{ssh_user}} mode=0644 + + - name: Run the SteamCMD setup + shell: './steamcmd.sh +runscript /data/Steam/7days.txt' + args: + chdir: /data/Steam/ + ignore_errors: True + + - name: Upload serverconfig.xml + copy: + src: static_files/serverconfig_3rd.xml + dest: /data/Steam/sdtt-server/serverconfig.xml + owner: "{{ssh_user}}" + group: "{{ssh_user}}" + mode: 0644 + +# Create game server systemd service +- hosts: '{{ target | default("all") }}' + vars: + ssh_user: debian + become: yes + become_method: sudo + tasks: + + - name: Upload 7days.service + template: src=static_files/7days.service.j2 dest=/etc/systemd/system/7days.service owner=root group=root mode=0644 + ignore_errors: True + + - name: force systemd to reread configs + systemd: daemon_reload=yes + + - name: enable 7days.service + systemd: + name: 7days + state: started + enabled: True diff --git a/ansible/static_files/7days.j2 b/ansible/static_files/7days.j2 new file mode 100644 index 0000000..4b2fdcb --- /dev/null +++ b/ansible/static_files/7days.j2 @@ -0,0 +1,8 @@ +// sdtt.txt +// +@ShutdownOnFailedCommand 1 +@NoPromptForPassword 1 +login anonymous +force_install_dir ./sdtt-server +app_update 294420 validate +quit diff --git a/ansible/static_files/7days.service.j2 b/ansible/static_files/7days.service.j2 new file mode 100644 index 0000000..65a47ae --- /dev/null +++ b/ansible/static_files/7days.service.j2 @@ -0,0 +1,19 @@ +## /etc/systemd/system/7days.service +[Unit] +Description=Seven Days To Die Server + +After=network.target + +[Service] +User={{ssh_user}} +WorkingDirectory=/data/Steam/sdtt-server + +ExecStart=/data/Steam/sdtt-server/startserver.sh -configfile=/data/Steam/sdtt-server/serverconfig.xml + +TimeoutStartSec=infinity +Restart=always +LimitNOFILE=4096 + +[Install] +WantedBy=multi-user.target +## END OF FILE diff --git a/ansible/static_files/serverconfig.xml b/ansible/static_files/serverconfig.xml new file mode 100644 index 0000000..1c24002 --- /dev/null +++ b/ansible/static_files/serverconfig.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ansible/static_files/serverconfig_3rd.xml b/ansible/static_files/serverconfig_3rd.xml new file mode 100644 index 0000000..69a99ba --- /dev/null +++ b/ansible/static_files/serverconfig_3rd.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ansible/stop.yml b/ansible/stop.yml new file mode 100644 index 0000000..7ebbf44 --- /dev/null +++ b/ansible/stop.yml @@ -0,0 +1,28 @@ +--- +- hosts: '{{ target | default("all") }}' + become: yes + become_method: sudo + tasks: + + - name: Save world + ansible.builtin.command: echo "saveworld" | nc -w 5 localhost 8081 + + - name: Shutdown server + ansible.builtin.command: echo "shutdown" | nc -w 5 localhost 8081 + + - name: Stop service + ansible.builtin.service: + name: 7days + state: stopped + + - name: Create a directory if it does not exist + ansible.builtin.file: + path: /data/backup + state: directory + mode: '0755' + + - name: Make save backup + community.general.archive: + path: /data/Saves + dest: /data/backup/{{ ansible_date_time.date }}_{{ ansible_date_time.hour }}-{{ ansible_date_time.minute }}.tar.gz + format: gz diff --git a/down.sh b/down.sh new file mode 100644 index 0000000..7112ccc --- /dev/null +++ b/down.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +TERRAFORM_DIR="terraform_pl" + +# Get server IP +SERVER_IP=$(bin/terraform -chdir=$TERRAFORM_DIR output public_ip | tr -d '"') + +# Run ansible stop.xml playbook +VENV_NAME="./venv" + +if [ -d "$VENV_NAME" ] +then + source "$VENV_NAME/bin/activate" + (cd ansible && ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u root -i "$SERVER_IP," --private-key ~/sdtt/key -e 'pub_key=~/sdtt/key.pub' stop.yml) + deactivate +else + echo "Could not find venv directory." +fi + +# Destroy resources + +bin/terraform -chdir=$TERRAFORM_DIR destroy -auto-approve -target scaleway_instance_server.instance_server +bin/terraform -chdir=$TERRAFORM_DIR destroy -auto-approve -target scaleway_instance_security_group.security_group +bin/terraform -chdir=$TERRAFORM_DIR destroy -auto-approve -target scaleway_instance_ip.public_ip diff --git a/setup_environment.sh b/setup_environment.sh new file mode 100644 index 0000000..e2b354a --- /dev/null +++ b/setup_environment.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Install packages +sudo apt -y install wget unzip python3 python3-venv + +# Download terraform +if [ -d "./bin" ] +then + echo "Found bin directory." +else + wget https://releases.hashicorp.com/terraform/1.1.3/terraform_1.1.3_linux_amd64.zip + unzip terraform_1.1.3_linux_amd64.zip -d ./bin + rm terraform_1.1.3_linux_amd64.zip +fi + +# Initialize terraform +bin/terraform -chdir=terraform_pl init + +# Create ansible venv for python +VENV_NAME="./venv" + +if [ -d "$VENV_NAME" ] +then + echo "Found venv directory." +else + echo "Creating venv..." + python3 -m venv "$VENV_NAME" + source "$VENV_NAME/bin/activate" + pip3 install ansible + deactivate +fi diff --git a/terraform_pl/.terraform.lock.hcl b/terraform_pl/.terraform.lock.hcl new file mode 100644 index 0000000..3944aef --- /dev/null +++ b/terraform_pl/.terraform.lock.hcl @@ -0,0 +1,24 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/scaleway/scaleway" { + version = "2.2.0" + hashes = [ + "h1:4+BjCUfLPVaSe1tiAECUHv6gIEpu+CeLzeawsegB7ww=", + "h1:4M58uMZHO9fYFPBug868UjaDo+EutwtEGSsCHi4E3UM=", + "zh:016486d3e448630e29595412b8d31c8a3b2cec83fa531a86ef3d3858f6ebe45d", + "zh:0ae1eb5142f866da8849475d976da21a2f7cc905f37c99e7aef810c3369e0f65", + "zh:0c2c8bd7b8beb49d6320cbb4dfba647a465dc1d0f3583b01ad7f0b0559cc043a", + "zh:1a2ddae054c2e21db960d25432406f01ac0aca7529838176c11a892f62987a8f", + "zh:211c92dd31513b06d679f1d9d85ed39911ee32a5c03a2af93e7a5710cb6d0a64", + "zh:76ae419f8ebdc39236c14f87b6c03c9b1f2c6f60081fec48d7d3531cadafcdbe", + "zh:8a951e6fb2c329d0095edb607e5c760c47838956d7b0a75111692bd77158a445", + "zh:9ff0638bd03a39aacf331912ff1547d31c5a5a3e1961bf3ca50a581ae2bf0cba", + "zh:a3ece235aefa0a3110ecae34304122fe32a566a9d54123593e9434693b03d764", + "zh:a47f101c77be03df35179474110ab05397693ce7efb74c5a133ae3cb0041bb88", + "zh:a69562aaf71b7ef7b2c8ef345637a3309762f45d960560453595ea2ec2cb0e2c", + "zh:aa4b8699e888b08905271a6a2c5da206ac737742b8a947a1d9ed53c875954cd5", + "zh:abb3e3e235b4862ead53397dd09be40c91910931a993b9415185ea6e8492fdb4", + "zh:e772b6ccb6d70a2d610c696185d3411548c73ad6e10870f70921021134ef1e67", + ] +} diff --git a/terraform_pl/main.tf b/terraform_pl/main.tf new file mode 100644 index 0000000..6e2e554 --- /dev/null +++ b/terraform_pl/main.tf @@ -0,0 +1,105 @@ +terraform { + required_providers { + scaleway = { + source = "scaleway/scaleway" + } + } + required_version = ">= 0.13" +} + +provider "scaleway" { + zone = var.zone + region = var.region +} + +resource "scaleway_instance_ip" "public_ip" { + project_id = var.project_id +} + +resource "scaleway_instance_volume" "volume" { + name = "v7days" + project_id = var.project_id + size_in_gb = var.data_volume_size + type = "l_ssd" + + lifecycle { + prevent_destroy = true + } +} + +resource "scaleway_instance_security_group" "security_group" { + name = "sg7daysPL" + project_id = var.project_id + inbound_default_policy = "drop" + outbound_default_policy = "accept" + + inbound_rule { + action = "accept" + port = "22" + } + + inbound_rule { + action = "accept" + port = "80" + } + + inbound_rule { + action = "accept" + port = "443" + } + + inbound_rule { + action = "accept" + port = "26900" + protocol = "TCP" + } + + inbound_rule { + action = "accept" + port = "26900" + protocol = "UDP" + } + + inbound_rule { + action = "accept" + port = "26901" + protocol = "TCP" + } + + inbound_rule { + action = "accept" + port = "26901" + protocol = "UDP" + } + + inbound_rule { + action = "accept" + port = "26902" + protocol = "TCP" + } + + inbound_rule { + action = "accept" + port = "26902" + protocol = "UDP" + } +} + +resource "scaleway_instance_server" "instance_server" { + name = "i7daysPL" + project_id = var.project_id + type = var.instance_type + image = var.instance_image + + tags = ["game", "terraform"] + + ip_id = scaleway_instance_ip.public_ip.id + + additional_volume_ids = [scaleway_instance_volume.volume.id] + + root_volume { + size_in_gb = var.instance_volume_size + } + + security_group_id = scaleway_instance_security_group.security_group.id +} diff --git a/terraform_pl/outputs.tf b/terraform_pl/outputs.tf new file mode 100644 index 0000000..4eeca80 --- /dev/null +++ b/terraform_pl/outputs.tf @@ -0,0 +1,4 @@ +output "public_ip" { + description = "The public IP of the i7days server" + value = scaleway_instance_ip.public_ip.address +} diff --git a/terraform_pl/variables.tf b/terraform_pl/variables.tf new file mode 100644 index 0000000..3d5edde --- /dev/null +++ b/terraform_pl/variables.tf @@ -0,0 +1,40 @@ +variable "project_id" { + type = string + default = "d8504e56-fd7e-4640-9308-6d95e8406c7e" + description = "Project id" +} + +variable "region" { + description = "The region to create things in." + default = "pl-waw" +} + +variable "zone" { + description = "The zone to create things in." + default = "pl-waw-1" +} + +# Data volume configuration +variable "data_volume_size" { + description = "Size of data volume" + default = 50 +} + +# Instance configuration +variable "instance_type" { + description = "Instance type to create." + default = "GP1-XS" + #default = "DEV1-L" + #default = "DEV1-XL" + #default = "DEV1-S" +} + +variable "instance_image" { + description = "Instance image to use." + default = "debian_bullseye" +} + +variable "instance_volume_size" { + description = "Instance type to create." + default = 100 +} diff --git a/up.sh b/up.sh new file mode 100644 index 0000000..56ca6bb --- /dev/null +++ b/up.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +TERRAFORM_DIR="terraform_pl" + +# Create resources +bin/terraform -chdir=$TERRAFORM_DIR apply -auto-approve + +# Get server IP +SERVER_IP=$(bin/terraform -chdir=$TERRAFORM_DIR output public_ip | tr -d '"') + +# Sleep for 30s (Usually terraform finishes before server boot) +sleep 30 + +# Run ansible stop.xml playbook +VENV_NAME="./venv" + +if [ -d "$VENV_NAME" ] +then + source "$VENV_NAME/bin/activate" + (cd ansible && ANSIBLE_HOST_KEY_CHECKING=False ANSIBLE_NOCOWS=1 ansible-playbook -u root -i "$SERVER_IP," --private-key ~/sdtt/key -e 'pub_key=~/sdtt/key.pub' main.yml) + deactivate +else + echo "Could not find venv directory." +fi