├── .gitignore ├── README.md ├── ansible ├── hosts.ini.sample ├── playbook.yml └── roles │ └── minecraft-server │ ├── handlers │ └── main.yml │ ├── tasks │ ├── install.yml │ ├── main.yml │ ├── post-install │ │ ├── main.yml │ │ ├── sshd.yml │ │ ├── sudo.yml │ │ └── systemd.yml │ └── setup.yml │ └── templates │ ├── eula.txt.j2 │ ├── minecraft-server.service.j2 │ ├── server.properties.j2 │ └── sshd_config.j2 ├── destroy.sh ├── env ├── .env.aws.sample ├── .env.hetzner.sample └── .env.openstack.sample ├── parse_tf_output.py ├── provision.sh └── terraform ├── aws ├── .terraform.lock.hcl ├── ec2.tf ├── keypair.tf ├── launch_template.tf ├── main.tf ├── outputs.tf ├── security_group.tf ├── vars.tf └── vpc.tf ├── hetzner ├── .terraform.lock.hcl ├── firewall.tf ├── main.tf ├── output.tf ├── server.tf ├── ssh_key.tf └── vars.tf └── openstack ├── .terraform.lock.hcl ├── flavor.tf ├── image.tf ├── instance.tf ├── keypair.tf ├── main.tf ├── network.tf ├── outputs.tf ├── security_group.tf └── vars.tf /.gitignore: -------------------------------------------------------------------------------- 1 | .env.* 2 | !.env.*.sample 3 | hosts.ini 4 | *.tfstate* 5 | 6 | output.json 7 | 8 | .terraform 9 | # Created by https://www.toptal.com/developers/gitignore/api/terraform 10 | # Edit at https://www.toptal.com/developers/gitignore?templates=terraform 11 | 12 | ### Terraform ### 13 | # Local .terraform directories 14 | **/.terraform/* 15 | 16 | # .tfstate files 17 | *.tfstate 18 | *.tfstate.* 19 | 20 | # Crash log files 21 | crash.log 22 | crash.*.log 23 | 24 | # Exclude all .tfvars files, which are likely to contain sensitive data, such as 25 | # password, private keys, and other secrets. These should not be part of version 26 | # control as they are data points which are potentially sensitive and subject 27 | # to change depending on the environment. 28 | *.tfvars 29 | *.tfvars.json 30 | 31 | # Ignore override files as they are usually used to override resources locally and so 32 | # are not checked in 33 | override.tf 34 | override.tf.json 35 | *_override.tf 36 | *_override.tf.json 37 | 38 | # Include override files you do wish to add to version control using negated pattern 39 | # !example_override.tf 40 | 41 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 42 | # example: *tfplan* 43 | 44 | # Ignore CLI configuration files 45 | .terraformrc 46 | terraform.rc 47 | 48 | # End of https://www.toptal.com/developers/gitignore/api/terraform 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minecraft Server Provisioner 2 | 3 | ## Objective 4 | 5 | * Provision an [Minecraft](https://www.minecraft.net/) server where you and your friends can connect and play. 6 | 7 | ## Prerequisites 8 | 9 | * [OpenTofu](https://opentofu.org/) or [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) 10 | * [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) 11 | * Minecraft Client 12 | 13 | ### AWS 14 | 15 | * An AWS account with [access and secret keys](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-appendix-sign-up.html). 16 | 17 | ### Hetzner 18 | 19 | * An Hetzner Cloud account with a valid [API access token](https://docs.hetzner.com/cloud/api/getting-started/generating-api-token/). 20 | 21 | ## Which resources does Terraform will provision? 22 | 23 | ### AWS 24 | 25 | | Instance Type | OS | RAM | vCPUs | 26 | |---------------|--------------|------|-------| 27 | | t2.medium | Ubuntu 22.04 | 4GB | 2 | 28 | 29 | ### Hetzner 30 | 31 | | Instance Type | OS | RAM | vCPUs | 32 | |---------------|--------------|------|-------| 33 | | CPX21 | Ubuntu 22.04 | 4GB | 3 | 34 | 35 | ## How to 36 | 37 | ### Customization 38 | 39 | If you want, you can customize some options on your Minecraft Server. To do it, you need to edit `./ansible/playbook.yml` minecraft-server role. 40 | 41 | * `server_jar_url`: The server.jar file that will run the server. The version of this file must match the version of the Minecraft Client. (Default 1.20.1) 42 | 43 | The other variables are self-explainable. 44 | 45 | ### Provision and Configure 46 | 47 | 1. Init terraform: 48 | 49 | ```bash 50 | cd terraform/ && terraform init 51 | ``` 52 | 53 | 2. Create, if not existent, an SSH key: 54 | 55 | ```bash 56 | ssh-keygen 57 | ``` 58 | 59 | 3. Config your credentials on `./env/.env.` 60 | 61 | 4. Provision your server: 62 | 63 | ```bash 64 | ./provision.sh 65 | ``` 66 | 67 | ### Just Configure 68 | 69 | If you already have a server, you can only run the ansible playbook that install and configure a Minecraft Server on your server. 70 | 71 | 1. Write the user that ansible will user and your IP address on `./ansible/hosts.ini` 72 | 73 | 2. Install ansible community.general collection: 74 | 75 | ```bash 76 | ansible-galaxy collection install community.general 77 | ``` 78 | 79 | 3. Run: 80 | 81 | ```bash 82 | cd ansible && ansible-playbook -i hosts.ini -v playbook.yml 83 | ``` 84 | 85 | ### Destroy 86 | 87 | If you want to destroy your Minecraft Server instances, just run: 88 | 89 | ```bash 90 | ./destroy.sh 91 | ``` 92 | 93 | ## Playing 94 | 95 | * Grab your server IP address (`output.json`) 96 | * Go to Multiplayer on your Minecraft Client 97 | * Add your brand new server and start playing! 98 | 99 | ## Managing 100 | 101 | 1. SSH into your server: 102 | 103 | ```bash 104 | ssh minecraft@ 105 | ``` 106 | 107 | 2. Your Minecraft Server simply is a systemd process, that you can manage with: 108 | 109 | ```bash 110 | sudo /bin/systemctl (status | start | stop | restart | enable | disable) 111 | ``` 112 | 113 | ## Costs 114 | 115 | ### AWS 116 | 117 | TODO 118 | 119 | ### Hetzner 120 | 121 | | ~ 7.00€ / month | 122 | |-----------------| 123 | -------------------------------------------------------------------------------- /ansible/hosts.ini.sample: -------------------------------------------------------------------------------- 1 | [server] 2 | localhost ansible_user=me ansible_ssh_common_args='-o StrictHostKeyChecking=no' 3 | -------------------------------------------------------------------------------- /ansible/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Config and install Minecraft Server 3 | hosts: server 4 | become: true 5 | vars: 6 | server_jar_url: https://piston-data.mojang.com/v1/objects/84194a2f286ef7c14ed7ce0090dba59902951553/server.jar 7 | server_difficulty: easy 8 | server_gamemode: survival 9 | server_seed: null 10 | server_max_players: 20 11 | server_motd: My Own Minecraft Server 12 | hardcore: false 13 | roles: 14 | - minecraft-server 15 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Daemon-reload 3 | ansible.builtin.systemd: 4 | daemon_reload: true 5 | 6 | - name: Restart and enable minecraft-server 7 | ansible.builtin.systemd: 8 | name: minecraft-server 9 | state: restarted 10 | enabled: true 11 | 12 | - name: Reload sshd 13 | ansible.builtin.systemd: 14 | name: sshd 15 | state: reloaded 16 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Get server jar 3 | ansible.builtin.get_url: 4 | url: "{{ server_jar_url }}" 5 | dest: /srv/minecraft 6 | owner: minecraft 7 | group: minecraft 8 | 9 | - name: Upload server required files 10 | ansible.builtin.template: 11 | src: "{{ item.src }}" 12 | dest: "/srv/minecraft/{{ item.dest }}" 13 | owner: minecraft 14 | with_items: 15 | - { src: eula.txt.j2, dest: eula.txt } 16 | - { src: server.properties.j2, dest: server.properties } 17 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Setup minecraft server 3 | become: true 4 | import_tasks: setup.yml 5 | 6 | - name: Install minecraft server 7 | become: true 8 | become_user: minecraft 9 | import_tasks: install.yml 10 | 11 | - name: Post install 12 | import_tasks: post-install/main.yml 13 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/post-install/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Config maintenance script with systemd 3 | import_tasks: systemd.yml 4 | 5 | - name: Config SSH to minecraft user 6 | import_tasks: sshd.yml 7 | 8 | - name: Config sudo 9 | import_tasks: sudo.yml 10 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/post-install/sshd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create .ssh dir to minecraft user 3 | ansible.builtin.file: 4 | path: /srv/minecraft/.ssh 5 | owner: minecraft 6 | group: minecraft 7 | state: directory 8 | mode: '0755' 9 | 10 | - name: Create authorized_keys to minecraft user 11 | ansible.builtin.copy: 12 | remote_src: true 13 | src: "{{ ansible_env.HOME }}/.ssh/authorized_keys" 14 | dest: /srv/minecraft/.ssh/authorized_keys 15 | owner: minecraft 16 | group: minecraft 17 | mode: '0644' 18 | 19 | - name: Upload SSH configuration 20 | ansible.builtin.template: 21 | src: sshd_config.j2 22 | dest: /etc/ssh/sshd_config 23 | notify: 24 | - Reload sshd 25 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/post-install/sudo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add minecraft to sudoers file 3 | community.general.sudoers: 4 | name: minecraft 5 | state: present 6 | user: minecraft 7 | commands: ALL 8 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/post-install/systemd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Upload service file 3 | ansible.builtin.template: 4 | src: minecraft-server.service.j2 5 | dest: /etc/systemd/system/minecraft-server.service 6 | notify: 7 | - Daemon-reload 8 | - Restart and enable minecraft-server 9 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/tasks/setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install java and acl 3 | ansible.builtin.apt: 4 | pkg: 5 | - openjdk-17-jdk-headless 6 | - acl 7 | - screen 8 | state: present 9 | update_cache: true 10 | 11 | - name: Create minecraft server user 12 | ansible.builtin.user: 13 | name: minecraft 14 | shell: /bin/bash 15 | system: true 16 | home: /srv/minecraft 17 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/templates/eula.txt.j2: -------------------------------------------------------------------------------- 1 | eula=true 2 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/templates/minecraft-server.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=start and stop the minecraft-server 3 | After=network.target 4 | 5 | [Service] 6 | WorkingDirectory=/srv/minecraft/ 7 | User=minecraft 8 | Group=minecraft 9 | Restart=on-failure 10 | RestartSec=20 5 11 | Type=forking 12 | ExecStart=/usr/bin/screen -dmS minecraft /usr/bin/java -Xms2G -Xmx2G -jar server.jar --nogui 13 | 14 | [Install] 15 | 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/templates/server.properties.j2: -------------------------------------------------------------------------------- 1 | allow-flight=false 2 | allow-nether=true 3 | broadcast-console-to-ops=true 4 | broadcast-rcon-to-ops=true 5 | difficulty={{ server_difficulty }} 6 | enable-command-block=false 7 | enable-jmx-monitoring=false 8 | enable-query=false 9 | enable-rcon=false 10 | enable-status=true 11 | enforce-secure-profile=true 12 | enforce-whitelist=false 13 | entity-broadcast-range-percentage=100 14 | force-gamemode=false 15 | function-permission-level=2 16 | gamemode={{ server_gamemode }} 17 | generate-structures=true 18 | generator-settings={} 19 | hardcore={{ hardcore }} 20 | hide-online-players=false 21 | initial-disabled-packs= 22 | initial-enabled-packs=vanilla 23 | level-name=world 24 | level-seed={{ server_seed }} 25 | level-type=minecraft\:normal 26 | max-chained-neighbor-updates=1000000 27 | max-players={{ server_max_players }} 28 | max-tick-time=60000 29 | max-world-size=29999984 30 | motd={{ server_motd }} 31 | network-compression-threshold=256 32 | online-mode=false 33 | op-permission-level=4 34 | player-idle-timeout=0 35 | prevent-proxy-connections=false 36 | pvp=true 37 | query.port=25565 38 | rate-limit=0 39 | rcon.password= 40 | rcon.port=25575 41 | require-resource-pack=false 42 | resource-pack= 43 | resource-pack-prompt= 44 | resource-pack-sha1= 45 | server-ip= 46 | server-port=25565 47 | simulation-distance=10 48 | spawn-animals=true 49 | spawn-monsters=true 50 | spawn-npcs=true 51 | spawn-protection=16 52 | sync-chunk-writes=true 53 | text-filtering-config= 54 | use-native-transport=true 55 | view-distance=10 56 | white-list=false 57 | -------------------------------------------------------------------------------- /ansible/roles/minecraft-server/templates/sshd_config.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | # This is the sshd server system-wide configuration file. See 4 | # sshd_config(5) for more information. 5 | 6 | # This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games 7 | 8 | # The strategy used for options in the default sshd_config shipped with 9 | # OpenSSH is to specify options with their default value where 10 | # possible, but leave them commented. Uncommented options override the 11 | # default value. 12 | 13 | Include /etc/ssh/sshd_config.d/*.conf 14 | 15 | PermitRootLogin no 16 | 17 | PubkeyAuthentication yes 18 | 19 | PasswordAuthentication no 20 | PermitEmptyPasswords no 21 | 22 | # Change to yes to enable challenge-response passwords (beware issues with 23 | # some PAM modules and threads) 24 | KbdInteractiveAuthentication no 25 | 26 | UsePAM yes 27 | 28 | X11Forwarding yes 29 | PrintMotd no 30 | 31 | # Allow client to pass locale environment variables 32 | AcceptEnv LANG LC_* 33 | 34 | # override default of no subsystems 35 | Subsystem sftp /usr/lib/openssh/sftp-server 36 | -------------------------------------------------------------------------------- /destroy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source env/.env.$1 && cd terraform/$1 && terraform destroy -auto-approve && cd - 4 | -------------------------------------------------------------------------------- /env/.env.aws.sample: -------------------------------------------------------------------------------- 1 | export AWS_ACCESS_KEY_ID= 2 | export AWS_SECRET_ACCESS_KEY= 3 | -------------------------------------------------------------------------------- /env/.env.hetzner.sample: -------------------------------------------------------------------------------- 1 | export HCLOUD_TOKEN= 2 | -------------------------------------------------------------------------------- /env/.env.openstack.sample: -------------------------------------------------------------------------------- 1 | # You can get this informations on rc-file downloaded from dashboard 2 | export OS_AUTH_URL= 3 | export OS_USERNAME= 4 | export OS_PASSWORD= 5 | export OS_PROJECT_ID= 6 | export OS_PROJECT_DOMAIN_ID= 7 | export OS_INTERFACE= 8 | export OS_USER_DOMAIN_NAME= -------------------------------------------------------------------------------- /parse_tf_output.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | 4 | 5 | class UnsupportedProviderException(Exception): 6 | def __init__(self, *args: object) -> None: 7 | super().__init__(*args) 8 | 9 | 10 | provider = sys.argv[1] 11 | 12 | PROVIDER_USER_MAP = { 13 | 'aws': 'ubuntu', 14 | 'openstack': 'ubuntu', 15 | 'hetzner': 'root' 16 | } 17 | 18 | user = PROVIDER_USER_MAP.get(provider) 19 | 20 | if user is None: 21 | raise UnsupportedProviderException('Unsupported provider') 22 | 23 | with open('./output.json', 'r') as f: 24 | j = json.load(f) 25 | 26 | ansible_workers_ip = '' 27 | vm_ip = j['vm_public_ip']['value'] 28 | 29 | ansible_hosts = f''' 30 | [server] 31 | {vm_ip} ansible_user={user} ansible_ssh_common_args='-o StrictHostKeyChecking=no' 32 | '''.lstrip() 33 | 34 | with open('./ansible/hosts.ini', 'w') as hosts_ini: 35 | hosts_ini.write(ansible_hosts) 36 | -------------------------------------------------------------------------------- /provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function provision_infra() { 4 | provider=$1 5 | 6 | source env/.env.$provider && \ 7 | cd terraform/$provider && \ 8 | opentofu init && \ 9 | opentofu apply -auto-approve && \ 10 | opentofu output -json | tee ../../output.json && cd - 11 | } 12 | 13 | function config_ansible_hosts() { 14 | provider=$1 15 | 16 | /usr/bin/python3 parse_tf_output.py $provider 17 | } 18 | 19 | function config_vm() { 20 | ansible-galaxy collection install community.general && cd ansible && ansible-playbook -i hosts.ini playbook.yml -v 21 | } 22 | 23 | PROVIDER=$1 24 | 25 | provision_infra $PROVIDER && sleep 30 && config_ansible_hosts $PROVIDER && config_vm 26 | -------------------------------------------------------------------------------- /terraform/aws/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/aws" { 5 | version = "4.67.0" 6 | constraints = "~> 4.0" 7 | hashes = [ 8 | "h1:dCRc4GqsyfqHEMjgtlM1EympBcgTmcTkWaJmtd91+KA=", 9 | "zh:0843017ecc24385f2b45f2c5fce79dc25b258e50d516877b3affee3bef34f060", 10 | "zh:19876066cfa60de91834ec569a6448dab8c2518b8a71b5ca870b2444febddac6", 11 | "zh:24995686b2ad88c1ffaa242e36eee791fc6070e6144f418048c4ce24d0ba5183", 12 | "zh:4a002990b9f4d6d225d82cb2fb8805789ffef791999ee5d9cb1fef579aeff8f1", 13 | "zh:559a2b5ace06b878c6de3ecf19b94fbae3512562f7a51e930674b16c2f606e29", 14 | "zh:6a07da13b86b9753b95d4d8218f6dae874cf34699bca1470d6effbb4dee7f4b7", 15 | "zh:768b3bfd126c3b77dc975c7c0e5db3207e4f9997cf41aa3385c63206242ba043", 16 | "zh:7be5177e698d4b547083cc738b977742d70ed68487ce6f49ecd0c94dbf9d1362", 17 | "zh:8b562a818915fb0d85959257095251a05c76f3467caa3ba95c583ba5fe043f9b", 18 | "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", 19 | "zh:9c385d03a958b54e2afd5279cd8c7cbdd2d6ca5c7d6a333e61092331f38af7cf", 20 | "zh:b3ca45f2821a89af417787df8289cb4314b273d29555ad3b2a5ab98bb4816b3b", 21 | "zh:da3c317f1db2469615ab40aa6baba63b5643bae7110ff855277a1fb9d8eb4f2c", 22 | "zh:dc6430622a8dc5cdab359a8704aec81d3825ea1d305bbb3bbd032b1c6adfae0c", 23 | "zh:fac0d2ddeadf9ec53da87922f666e1e73a603a611c57bcbc4b86ac2821619b1d", 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /terraform/aws/ec2.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "minecraft_server" { 2 | launch_template { 3 | id = aws_launch_template.minecraft_server_template.id 4 | } 5 | 6 | tags = { 7 | "Name" = "minecraft server vm" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /terraform/aws/keypair.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "minecraft_server_keypair" { 2 | key_name = "minecraft_server_keypair" 3 | public_key = file("${var.keypair_path}") 4 | } 5 | -------------------------------------------------------------------------------- /terraform/aws/launch_template.tf: -------------------------------------------------------------------------------- 1 | resource "aws_launch_template" "minecraft_server_template" { 2 | name = "minecraft_server_template" 3 | image_id = var.ami_config 4 | instance_type = var.instance_type 5 | key_name = aws_key_pair.minecraft_server_keypair.key_name 6 | 7 | monitoring { 8 | enabled = true 9 | } 10 | 11 | placement { 12 | availability_zone = var.availability_zone 13 | } 14 | 15 | network_interfaces { 16 | subnet_id = aws_subnet.minecraft_server_public_subnet.id 17 | associate_public_ip_address = true 18 | security_groups = [aws_security_group.minecraft_server_sg.id] 19 | } 20 | 21 | tags = { 22 | "Name" = "minecraft server EC2 template" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /terraform/aws/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | aws = { 4 | source = "hashicorp/aws" 5 | version = "~> 4.0" 6 | } 7 | } 8 | } 9 | 10 | provider "aws" { 11 | region = var.availability_zone 12 | } 13 | -------------------------------------------------------------------------------- /terraform/aws/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vm_public_ip" { 2 | value = aws_instance.minecraft_server.public_ip 3 | } 4 | -------------------------------------------------------------------------------- /terraform/aws/security_group.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "minecraft_server_sg" { 2 | vpc_id = aws_vpc.minecraft_server_vpc.id 3 | name = "minecraft_server_sg" 4 | 5 | ingress { 6 | from_port = 25565 7 | to_port = 25565 8 | protocol = "tcp" 9 | cidr_blocks = ["0.0.0.0/0"] 10 | } 11 | 12 | ingress { 13 | from_port = 8 14 | to_port = 0 15 | protocol = "icmp" 16 | cidr_blocks = ["0.0.0.0/0"] 17 | } 18 | 19 | ingress { 20 | from_port = 22 21 | to_port = 22 22 | protocol = "tcp" 23 | cidr_blocks = ["0.0.0.0/0"] 24 | } 25 | 26 | egress { 27 | from_port = 0 28 | to_port = 0 29 | protocol = "-1" 30 | cidr_blocks = ["0.0.0.0/0"] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /terraform/aws/vars.tf: -------------------------------------------------------------------------------- 1 | variable "keypair_path" { 2 | type = string 3 | default = "~/.ssh/id_rsa.pub" 4 | description = "Localização da chave ssh no sistema de arquivos" 5 | } 6 | 7 | variable "ami_config" { 8 | type = string 9 | default = "ami-0f1bae6c3bedcc3b5" 10 | } 11 | 12 | variable "instance_type" { 13 | type = string 14 | default = "t2.medium" 15 | } 16 | 17 | variable "availability_zone" { 18 | type = string 19 | default = "us-east-1" 20 | } 21 | -------------------------------------------------------------------------------- /terraform/aws/vpc.tf: -------------------------------------------------------------------------------- 1 | resource "aws_vpc" "minecraft_server_vpc" { 2 | cidr_block = "192.168.0.0/16" 3 | instance_tenancy = "default" 4 | enable_dns_support = true 5 | enable_dns_hostnames = true 6 | 7 | tags = { 8 | Name = "minecraft_server_vpc" 9 | } 10 | } 11 | 12 | resource "aws_subnet" "minecraft_server_public_subnet" { 13 | vpc_id = aws_vpc.minecraft_server_vpc.id 14 | cidr_block = "192.168.1.0/24" 15 | map_public_ip_on_launch = true 16 | availability_zone = "us-east-1a" 17 | 18 | tags = { 19 | Name = "minecraft_server_public_subnet" 20 | } 21 | } 22 | 23 | resource "aws_internet_gateway" "minecraft_server_igw" { 24 | vpc_id = aws_vpc.minecraft_server_vpc.id 25 | 26 | tags = { 27 | Name = "minecraft_server_igw" 28 | } 29 | } 30 | 31 | resource "aws_route_table" "minecraft_server_rt" { 32 | vpc_id = aws_vpc.minecraft_server_vpc.id 33 | 34 | route { 35 | cidr_block = "0.0.0.0/0" 36 | gateway_id = aws_internet_gateway.minecraft_server_igw.id 37 | } 38 | 39 | tags = { 40 | Name = "minecraft_server_rt" 41 | } 42 | } 43 | 44 | resource "aws_route_table_association" "minecraft_server_1a" { 45 | subnet_id = aws_subnet.minecraft_server_public_subnet.id 46 | route_table_id = aws_route_table.minecraft_server_rt.id 47 | } 48 | -------------------------------------------------------------------------------- /terraform/hetzner/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hetznercloud/hcloud" { 5 | version = "1.41.0" 6 | hashes = [ 7 | "h1:wsV+X5rrSTLRXGi4K9+pN+xz2zF0cTpsyopKfmQ2fDw=", 8 | "zh:261f14c7c2d2a289f98ad38b91ad377e5300a0c74d25eb232c7b2deaef115005", 9 | "zh:42acf8682dd1489966ec3724e592f7c0e96b8c47b8731756b581742469393494", 10 | "zh:4b954d5c4e98b0bda9d30ddd131b867c6f2517d989973bbda290c7ff2643ebd0", 11 | "zh:66236b067865e1386215c382b4d3380e3c12ad45bc9860557555417640e24f65", 12 | "zh:76cf2c7c3b151f662060f5fc69e28d34998610f30372b5cc7f06b601b9e53a73", 13 | "zh:7990d914f896f8ca95d5a8f18411994611b5d163d40fe724c2ebed3114dc2c0c", 14 | "zh:88efda045f5ca169d27880f03822fdf9b0ac8f5601a9e581aed5fdf844c6229a", 15 | "zh:896966307382fc2d48007faf266b406ad80efc1f202fc36cfa0c97ae408450bc", 16 | "zh:8cdae7f0daf10d7ace982d0c31ea3c79bc7e23e599864cf247ee14b396f8dd07", 17 | "zh:ab234e2c9fb26a4583934690de8c14b917890fb629689766b38bfdcc4666413b", 18 | "zh:b0755b3d8767f52ce7fbc018bc0c26c4486e042a752eefbb0ce037fdea1cbc24", 19 | "zh:cf144c2976485d46e531144f401ffc1fcfb1a9bf74b6ab88847010191b2b1767", 20 | "zh:f7b03a3ec8ad33289dbc4616cefcc85bb0cf8a3694f83d70b68ea0eb0083b7b0", 21 | "zh:fd89baf2b299b5d717c7707c2f29757cc081ee2147f820d121252e2f100647f4", 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /terraform/hetzner/firewall.tf: -------------------------------------------------------------------------------- 1 | resource "hcloud_firewall" "minecraft-server-fw" { 2 | name = "minecraft-server-firewall" 3 | 4 | rule { 5 | direction = "in" 6 | protocol = "icmp" 7 | source_ips = [ 8 | "0.0.0.0/0", 9 | "::/0" 10 | ] 11 | } 12 | 13 | rule { 14 | direction = "in" 15 | protocol = "tcp" 16 | port = "22" 17 | source_ips = [ 18 | "0.0.0.0/0", 19 | "::/0" 20 | ] 21 | description = "allows SSH" 22 | } 23 | 24 | rule { 25 | direction = "in" 26 | protocol = "tcp" 27 | port = "25565" 28 | source_ips = [ 29 | "0.0.0.0/0", 30 | "::/0" 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /terraform/hetzner/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | hcloud = { 4 | source = "hetznercloud/hcloud" 5 | } 6 | } 7 | } 8 | 9 | provider "hcloud" {} 10 | -------------------------------------------------------------------------------- /terraform/hetzner/output.tf: -------------------------------------------------------------------------------- 1 | output "vm_public_ip" { 2 | value = hcloud_server.minecraft-server.ipv4_address 3 | } 4 | -------------------------------------------------------------------------------- /terraform/hetzner/server.tf: -------------------------------------------------------------------------------- 1 | resource "hcloud_server" "minecraft-server" { 2 | name = "minecraft-server" 3 | image = "ubuntu-22.04" 4 | server_type = var.server_type 5 | location = var.location 6 | 7 | public_net { 8 | ipv4_enabled = true 9 | ipv6_enabled = true 10 | } 11 | 12 | firewall_ids = [hcloud_firewall.minecraft-server-fw.id] 13 | ssh_keys = [hcloud_ssh_key.minecraft-server-key.id] 14 | } 15 | -------------------------------------------------------------------------------- /terraform/hetzner/ssh_key.tf: -------------------------------------------------------------------------------- 1 | resource "hcloud_ssh_key" "minecraft-server-key" { 2 | name = "minecraft-server-key" 3 | public_key = file("${var.ssh_key_path}") 4 | } 5 | -------------------------------------------------------------------------------- /terraform/hetzner/vars.tf: -------------------------------------------------------------------------------- 1 | variable "location" { 2 | type = string 3 | default = "ash" 4 | } 5 | 6 | variable "server_type" { 7 | type = string 8 | default = "cpx21" 9 | } 10 | 11 | variable "ssh_key_path" { 12 | type = string 13 | default = "~/.ssh/id_rsa.pub" 14 | } 15 | -------------------------------------------------------------------------------- /terraform/openstack/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/terraform-provider-openstack/openstack" { 5 | version = "1.53.0" 6 | constraints = "~> 1.53.0" 7 | hashes = [ 8 | "h1:ZSJPqrlaHQ3sj7wyJuPSG+NblFZbAA6Y0d3GjSJf3o8=", 9 | "zh:09da7ca98ffd3de7b9ce36c4c13446212a6e763ba1162be71b50f95d453cb68e", 10 | "zh:14041bcbb87312411d88612056ed185650bfd01284b8ea0761ce8105a331708e", 11 | "zh:35bf4c788fdbc17c8e40ebc7b33c7de4b45a2fa2efaa657b10f0e3bd37c9627f", 12 | "zh:46ede8ef4cfa12d654c538afc1e1ec34a1f3e8eb4e986ee23dceae398b7176a6", 13 | "zh:59675734990dab1e8d87997853ea75e8104bba730b3f5a7146ac735540c9d6bf", 14 | "zh:6de52428849806498670e827b54810be7510a2a79449602c1aede4235a0ec036", 15 | "zh:78b2a20601272afceffac8f8ca78a6b647b84196c0dd8dc710fae297f6be15a4", 16 | "zh:7c41ed3a4fac09677e676ecf9f9edd1e38eef449e656cb01a848d2c799c6de8f", 17 | "zh:852800228f4118a4aa6cfaa4468b851247cbed6f037fd204f08de69eb1edc149", 18 | "zh:86d618e7f9a07d978b8bc4b190be350a00de64ec535f9c8f5dfe133542a55483", 19 | "zh:963a9e72b66d8bcf43de9b14a674ae3ca3719ce2f829217f7a65b66fc3773397", 20 | "zh:a8e72ab67795071bda61f99a6de3d2d40122fb51971768fd75e1324abe874ced", 21 | "zh:ce1890cf3af17d569af3bc7673cec0a8f78e6f5d701767593f3d29c551f44848", 22 | "zh:e6f1b96eb684f527a47f71923f268c86a36d7894751b31ee9e726d7502a639cd", 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /terraform/openstack/flavor.tf: -------------------------------------------------------------------------------- 1 | data "openstack_compute_flavor_v2" "medium" { 2 | vcpus = 2 3 | min_ram = 4096 4 | } -------------------------------------------------------------------------------- /terraform/openstack/image.tf: -------------------------------------------------------------------------------- 1 | data "openstack_images_image_ids_v2" "image" { 2 | name_regex = "^ubuntu-22.*" 3 | sort = "updated_at" 4 | } -------------------------------------------------------------------------------- /terraform/openstack/instance.tf: -------------------------------------------------------------------------------- 1 | # Basic instance, but is possible to create it to boot from volume. 2 | resource "openstack_compute_instance_v2" "minecraft-server" { 3 | name = "minecraft-server" 4 | image_id = tolist(data.openstack_images_image_ids_v2.image.ids)[0] 5 | flavor_id = data.openstack_compute_flavor_v2.medium.id 6 | key_pair = openstack_compute_keypair_v2.minecraft-keypair.name 7 | security_groups = ["default", openstack_networking_secgroup_v2.minecraft_sg.name] 8 | 9 | network { 10 | uuid = data.openstack_networking_network_v2.network.id 11 | } 12 | } -------------------------------------------------------------------------------- /terraform/openstack/keypair.tf: -------------------------------------------------------------------------------- 1 | resource "openstack_compute_keypair_v2" "minecraft-keypair" { 2 | name = "minecraft-keypair" 3 | public_key = file("${var.keypair_path}") 4 | } -------------------------------------------------------------------------------- /terraform/openstack/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | openstack = { 4 | source = "terraform-provider-openstack/openstack" 5 | version = "~> 1.53.0" 6 | } 7 | } 8 | } 9 | 10 | provider "openstack" { 11 | } -------------------------------------------------------------------------------- /terraform/openstack/network.tf: -------------------------------------------------------------------------------- 1 | data "openstack_networking_network_v2" "network" { 2 | external = false 3 | status = "active" 4 | } -------------------------------------------------------------------------------- /terraform/openstack/outputs.tf: -------------------------------------------------------------------------------- 1 | output "vm_public_ip" { 2 | value = openstack_compute_instance_v2.minecraft-server.access_ip_v4 3 | } -------------------------------------------------------------------------------- /terraform/openstack/security_group.tf: -------------------------------------------------------------------------------- 1 | resource "openstack_networking_secgroup_v2" "minecraft_sg" { 2 | name = "minecraft-sg" 3 | description = "All rules to access minecraft server" 4 | } 5 | 6 | resource "openstack_networking_secgroup_rule_v2" "ssh" { 7 | direction = "ingress" 8 | ethertype = "IPv4" 9 | protocol = "tcp" 10 | port_range_min = 22 11 | port_range_max = 22 12 | remote_ip_prefix = "0.0.0.0/0" 13 | security_group_id = openstack_networking_secgroup_v2.minecraft_sg.id 14 | } 15 | 16 | resource "openstack_networking_secgroup_rule_v2" "server_port" { 17 | direction = "ingress" 18 | ethertype = "IPv4" 19 | protocol = "tcp" 20 | port_range_min = 25565 21 | port_range_max = 25565 22 | remote_ip_prefix = "0.0.0.0/0" 23 | security_group_id = openstack_networking_secgroup_v2.minecraft_sg.id 24 | } 25 | 26 | resource "openstack_networking_secgroup_rule_v2" "ping" { 27 | direction = "ingress" 28 | ethertype = "IPv4" 29 | protocol = "icmp" 30 | port_range_min = 0 31 | port_range_max = 0 32 | remote_ip_prefix = "0.0.0.0/0" 33 | security_group_id = openstack_networking_secgroup_v2.minecraft_sg.id 34 | } 35 | -------------------------------------------------------------------------------- /terraform/openstack/vars.tf: -------------------------------------------------------------------------------- 1 | variable "keypair_path" { 2 | type = string 3 | default = "~/.ssh/id_rsa.pub" 4 | } 5 | --------------------------------------------------------------------------------