【AWS】つよいMinecraftサーバーをつくる2021年6月版（EC2 + S3）

# はじめに

Minecraftを遠隔の複数人で遊びたいとき、サーバーを立てることになる。
公式のRealmsも月額1000円ほどで用意されているが、MODを導入できないなど制約が多い。
AWSのEC2とS3を使ってデータを自動バックアップするMinecraftサーバーを立てる

サンプルコード↓

https://github.com/uni-ezobafun/ocean_minecraft_server_java

### AWSでMinecraftサーバーを立てるメリット
* 使うときだけ起動して、使っている間だけ課金される
* 公式のRealmsよりも拡張性が高い（全て自分で管理できる）
* 参加人数や導入MODに応じて、いつでもサーバーのスペックを変更できる

### やること
* EC2インスタンスを新規作成して、Minecraftサーバーを自動起動する仕組みをつくる
* EC2起動時にデータをS3にバックアップする仕組みをつくる

### 前提
* `Minecraft Java Edition 1.17.0`
* カスタムサーバーアプリケーションの`spigot`を使う

# もくじ
1. データをバックアップするS3 bucketを新規作成する
1. EC2に付与するIAMロールをつくる
1. EC2インスタンスを新規作成する
1. 固定IPアドレスを付与する
1. EC2にMinecraftをインストールする
1. EC2起動時の処理を設定する

# 1. データをバックアップするS3 bucketを新規作成する

```
uni-minecraft-artifact
```

本ページでは上記の名称でS3 bucketを新規作成する。
Minecraftのデータをバックアップするのに使う。

S3 bucketを作成する方法は下記リンク（手順1-1を参照）↓

https://qiita.com/uni_ezobafun/items/81978d1487790b46b8c4



# 2. EC2に付与するIAMロールをつくる

```
ec2-minecraft-server-role
```

本ページでは上記の名称でIAMロールを新規作成する。

IAMロールを設定する方法は下記リンク（手順2と6を参照）↓

https://qiita.com/uni_ezobafun/items/a5a92e6afef21e239f48

下記の通り`S3MinecraftArtifactManagePolicy`を作成し、`ec2-minecraft-server-role`にアタッチした。
このロールを付与されたリソースは、`uni-minecraft-artifact`に配置された全てのファイルを読み書きできるようになる。

``` S3MinecraftArtifactManagePolicy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObjectAcl",
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::uni-minecraft-artifact/*",
        "arn:aws:s3:::uni-minecraft-artifact"
      ]
    }
  ]
}
```


# 3. EC2インスタンスを新規作成する

EC2インスタンスのコンソール画面で、右上の`Launch Instances`をクリック。
![Screen Shot 2021-06-26 at 12.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/e2a447b3-a3f4-63de-c2fe-17c40b850a6b.png)

今回はAmazon LinuxのAMIで、アーキテクチャはx86を選択。
![Screen Shot 2021-06-26 at 12.44.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/1eb75444-7362-653f-6a59-3e8293435aef.png)

インスタンスタイプの選択はご自由に（あとから変更もできる）。
`t3a.medium`程度の性能があれば、重いMODをいれない限りは快適に遊べるはず。
（自分の環境では地図MODの負荷が高いため、`m5a.large`を使っている）
インスタンスタイプを決めたら、画面右下の`Configure Instance Details`をクリック。
![Screen Shot 2021-06-26 at 12.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/bb4d3c92-a748-d6ee-2105-f4f79440cc9a.png)

`IAM Role`で、手順1で作った`ec2-minecraft-server-role`を指定する。
画面右下の`Add Storage`をクリック。
![Screen Shot 2021-06-26 at 15.08.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/e2ca2ec6-6dba-3024-094d-f00c06f2907a.png)

外付けストレージを設定する。
本ページではAWS無料枠で最大容量となる30GBの`General Purpose SSD(gd3)`を選択した。
画面右下の`Add Tags`をクリック。
![Screen Shot 2021-06-26 at 15.09.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/231ac833-c980-5927-3e8a-428374855e43.png)

Tagは特に設定しなくてよい。
ほしければお好みで。
画面右下の`Configure Security Group`をクリック。
![Screen Shot 2021-06-26 at 15.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/9ec3f739-62cc-0c70-0bf4-84b7d4ceb393.png)

Java版のMinecraftはデフォルトでは`port:25565`を使うらしい。
`Add Rule`をクリックして、必要な設定を追加する。
通信を許可するIPアドレスの対象はご自由に。
（本ページでは全てのIPアドレスを許可している。）
画面右下の`Review and Launch`をクリック。
![Screen Shot 2021-06-26 at 15.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/49bbdd23-ed02-de7a-9a44-0527b43f1fc4.png)

内容に誤りがないことを確認したら、画面右下の`Launch`をクリック。
![Screen Shot 2021-06-26 at 15.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/ad86c0ef-a3f1-fad7-97e8-1b224c6a796e.png)

sshに必要な鍵を作成する。
`Create a new key pair`を選択して、好きな名前をつける。
本ページでは`uni-minecraft-server-key`とした。
`Download Key Pair`を押して、ローカルに鍵（.pemファイル）を落としておく（手順6で使う）。
`Launch Instances`をクリックして、EC2の新規作成が完了。
![Screen Shot 2021-06-26 at 15.15.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/59287041-d106-58db-3eec-caa8a23cb458.png)

`Instance state`が`Running`、`Status check`が`passed`になっていれば、EC2の起動が完了している。
新規作成したEC2の`Instance ID`を控えておく（手順4,5で使う）。
![Screen Shot 2021-06-27 at 15.21.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/5d80ab5d-739d-288e-bd59-cd54e94105df.png)



# 4. 固定IPアドレスを付与する
EC2はデフォルトでは再起動ごとに異なるIPアドレスが付与されてしまう。
毎回同じIPアドレスでアクセスできるように、`Elastic IPs`を設定する。

`Network & Security`のカテゴリから、`Elastic IPs`をクリック。
![Screen Shot 2021-06-27 at 15.21.24 copy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/130353da-87e4-6dbf-e89e-c411cef33e63.png)

EC2を設置したリージョンと同じリージョンを選択して、画面右下の`Allocate`をクリック。
これで自分専用のIPアドレスを該当リージョン内で確保できた。
![Screen Shot 2021-06-27 at 15.21.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/b183f8fe-1d6d-f53d-45b9-bfb24e98024c.png)

今回確保したIPアドレスにチェックを入れて、`Associate Elastic IP Address`をクリック。
![Screen Shot 2021-06-27 at 15.25.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/dc37c228-d92f-f788-596c-6323f12e5f10.png)

手順3で新規作成したEC2の`Instance ID`を選択して、画面右下の`Associate`をクリック。
これで、常に同じIPアドレスでMinecraftサーバー用のEC2にアクセスできるようになる。
![Screen Shot 2021-06-27 at 15.25.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/db1989fc-86d7-1baa-98bc-f01c127e8d57.png)

固定IPアドレスを反映するために、一旦EC2を再起動する。
`Instance state`から`Stop`→`Start`をクリックするか、もしくは`Reboot`をクリックする。
※`Terminate`をクリックするとEC2が削除されるので注意。

![Screen Shot 2021-06-27 at 16.30.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/fc2ddcda-8da7-7c33-4c71-f07ab99557b3.png)




# 5. EC2にMinecraftをインストールする

ここからはsshでEC2内部に潜って作業する。
このとき、手順3の最後にダウンロードしておいた鍵（.pemファイル）のパスを指定する。

``` bash
$ chmod 600 ~/.ssh/keys/uni-minecraft-server-key.pem
$ ssh ec2-user@46.51.230.42 -i ~/.ssh/keys/uni-minecraft-server-key.pem
# ssh ec2-user@${ElasticIP} -i ${手順3でダウンロードした.pemのファイルパス}
```

正常にsshできれば、下記の通りEC2のロゴが表示される。

```
       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-31-16-27 ~]$ 
```

以下は、Minecraftのカスタムサーバー`spigot`を取得&ビルドする`setup.sh`。

``` setup.sh
#!/bin/sh

rpm --import https://yum.corretto.aws/corretto.key 
curl -L -o /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo
yum install -y java-16-amazon-corretto-devel

yum install -yt git

mkdir minecraft
cd minecraft

wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
java -jar BuildTools.jar --rev 1.17
find . | grep -v 'spigot-1.17.jar' | xargs rm -rf

java -Xmx2048M -Xms2048M -jar spigot-1.17.jar nogui

```

EC2の中でsetup.shをsudoで実行する（MinecraftのバージョンやURLは適宜書き換える）。
その後`eula.txt`の中身を手動で`eula=true`に書き換えて、Minecraftサーバーを起動する。

```
# あらかじめEC2にsetup.shを配置しておく
[ec2-user@ip-172-31-16-27 ~]$ ls
setup.sh

# setup.shを実行する
[ec2-user@ip-172-31-16-27 ~]$ sudo sh setup.sh

# === shellの処理が実行される ===

# setup.shの実行結果を確認する
[ec2-user@ip-172-31-16-27 minecraft]$ ls
eula.txt  logs  server.properties  spigot-1.17.jar

# eula.txtの中身を、eula=trueに書き換える
[ec2-user@ip-172-31-16-27 minecraft]$ sudo vim eula.txt 

# Minecraftサーバーを起動する
[ec2-user@ip-172-31-16-27 minecraft]$ sudo java -Xmx2048M -Xms2048M -jar spigot-1.17.jar nogui
```

この状態でMinecraftのクライアントを起動してEC2のIPアドレスを入力すれば、サーバーにログインできるはず。
![Screen Shot 2021-06-27 at 17.16.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/676dc719-0ff6-ba29-57d8-9b505c65dbfd.png)

![Screen Shot 2021-06-27 at 17.16.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/3f3a189d-7398-02d3-1424-a8532d7b0fda.png)



# 6. EC2起動時の処理を設定する

無事にサーバへログインできるようになったが、現状だとEC2を再起動するたびにsshしてサーバーアプリケーションを手動実行する必要があり、とても面倒。
`userdata`を設定して、EC2起動時に以下2つの処理を行う`launch.sh`を自動実行させる。

```
1. セーブデータをzip化してS3にバックアップする
2. サーバーアプリケーションを実行する
```

あらかじめ以下の`launch.sh`をEC2の`minecraft`ディレクトリ内に配置しておく。

``` launch.sh
#!/bin/sh
cd /home/ec2-user/minecraft

NOW=`date "+%Y%m%d"`
zip ${NOW}.zip -r world world_nether world_the_end/
aws s3 cp ${NOW}.zip s3://uni-minecraft-artifact/world_backup/world/ --storage-class ONEZONE_IA
rm -f ${NOW}.zip

java -Xmx2048M -Xms2048M -jar spigot-1.17.jar nogui
```

対象のEC2インスタンスを停止して、`Instance state`が`Stopped`になったことを確認したら、`Actions/Instance settings/Edit user data`をクリック。

![Screen Shot 2021-06-27 at 17.31.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/0f375fca-4872-6313-35c8-7e503fe01a55.png)

今回設定するuserdataは下記の通り。
通常userdataは初回起動時にしか実行されないが、configからALWAYSオプションを設定すると再起動時にも実行される。

``` userdata.txt
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
sudo sh /home/ec2-user/minecraft/launch.sh
--//
```

ページ下部の枠内にuserdata.txtの内容をそのまま書きこんだら、画面右下の`Save`をクリック。
![Screen Shot 2021-06-27 at 17.32.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050582/fd7fba94-6e1f-6e31-4d0c-bea2ba847791.png)



EC2を再起動して、期待通りに動くか確認しておわり。

```
1. Minecraftサーバーが自動で実行されて、クライアントからログインできること
2. S3にデータがバックアップされること
```

# 参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/execute-user-data-ec2/