{"id":16927832,"url":"https://github.com/dirien/pulumi-scala-minecraft","last_synced_at":"2026-04-13T21:31:16.680Z","repository":{"id":103803879,"uuid":"570685151","full_name":"dirien/pulumi-scala-minecraft","owner":"dirien","description":"Playing around with Pulumi, Scala and Minecraft","archived":false,"fork":false,"pushed_at":"2022-11-25T21:38:56.000Z","size":14,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-31T19:55:49.443Z","etag":null,"topics":["minecraft","pulumi","scala"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dirien.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-25T20:22:09.000Z","updated_at":"2022-12-14T15:50:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"da8f9a1d-7da3-4b79-8729-e510ed161df4","html_url":"https://github.com/dirien/pulumi-scala-minecraft","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dirien/pulumi-scala-minecraft","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fpulumi-scala-minecraft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fpulumi-scala-minecraft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fpulumi-scala-minecraft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fpulumi-scala-minecraft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dirien","download_url":"https://codeload.github.com/dirien/pulumi-scala-minecraft/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirien%2Fpulumi-scala-minecraft/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31771795,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T20:17:16.280Z","status":"ssl_error","status_checked_at":"2026-04-13T20:17:08.216Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["minecraft","pulumi","scala"],"created_at":"2024-10-13T20:35:15.164Z","updated_at":"2026-04-13T21:31:16.662Z","avatar_url":"https://github.com/dirien.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# How to use Pulumi and Scala to deploy a Minecraft Server on a DigitalOcean Droplet\n\n## Introduction\n\nSince I am a big fan of Minecraft and Pulumi I wanted to combine both and see If I am able to use Scala as programming\nlanguage. As we all know, Pulumi is a multi-language framework and supports many languages. And since now a while, also\nJava. Scala is a JVM language and compiles to Java bytecode. So I thought, why not give it a try.\n\n### Prerequisites\n\nTo follow this tutorial you need to have the following installed:\n\n- The [Pulumi](https://www.pulumi.com/docs/get-started/install/) CLI and a backend to host your state. I am using the\n  [Pulumi Service](https://app.pulumi.com/). It is free for open source projects.\n- [Scala](https://www.scala-lang.org/download/)\n- DigitalOcean Account and API Token. You can create here an account and\n  get [$200 credit for 60 days](https://www.digitalocean.com/go/developer-brand).\n- IDE of your choice. I am using [IntelliJ IDEA](https://www.jetbrains.com/idea/download/). Add the Scala plugin to\n  your IDE, for a more pleasant experience.\n\n### What is Scala?\n\nI shamelessly copied this from the [Scala website](https://www.scala-lang.org/):\n\n\u003e Scala combines object-oriented and functional programming in one concise, high-level language. Scala's static types\n\u003e help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems\n\u003e with easy access to huge ecosystems of libraries.\n\nThere you go, I could not better explain this myself.\n\n### Install Scala\n\nI am using homebrew to install Scala on my Mac. So the installation is as easy as:\n\n```bash\nbrew install coursier/formulas/coursier \u0026\u0026 cs setup\n```\n\n### Create a new Pulumi project\n\nAfter the installation of Scala I create a new Scala project with the following command:\n\n```bash\nsbt new scala/scala3.g8\n```\n\nAnd use as project name `pulumi-scala-minecraft`. This will create a new directory with the\nname `pulumi-scala-minecraft` and some files in it. We will change this files, no worries.\n\nTo add Pulumi, I just added a `Pulumi.yaml` file with the following content:\n\n```yaml\nname: pulumi-scala-minecraft\ndescription: A minimal Java Pulumi program with Maven builds\nruntime:\n  name: java\n```\n\nNow we can add the Pulumi dependencies to our project. We need the Pulumi core library and the Pulumi DigitalOcean\nprovider.\n\nOpen the `build.sbt` file and add the following dependencies after the exiting `libraryDependencies` line:\n\n```scala\nval scala3Version = \"3.2.1\"\n\nlazy val root = project.in(file(\".\")).settings(\n  name := \"pulumi-scala-minecraft\",\n  version := \"0.1.0-SNAPSHOT\",\n\n  scalaVersion := scala3Version,\n\n  libraryDependencies += \"org.scalameta\" %% \"munit\" % \"0.7.29\" % Test,\n  libraryDependencies += \"com.pulumi\" % \"pulumi\" % \"0.6.0\",\n  libraryDependencies += \"com.pulumi\" % \"digitalocean\" % \"4.16.0\",\n  libraryDependencies += \"com.pulumi\" % \"command\" % \"4.5.0\",\n)\n```\n\nSome remarks: I am using Scala `3.2.1` for this tutorial.\n\nNow I create a package `io.dirien.minecraft` in the `src/main/scala` directory and add a file `App$.scala` to it. This\nwill be our main class. Add the following content to the file:\n\n```scala\npackage io.dirien.minecraft\n\n\nimport com.pulumi.{Context, Pulumi}\nimport io.dirien.minecraft.MinecraftServer\n\nobject App {\n\n  final val region = \"fra1\"\n  final val size = \"c2-4vcpu-8gb\"\n  final val image = \"ubuntu-22-04-x64\"\n\n\n  def main(args: Array[String]): Unit = {\n    Pulumi.run { (ctx: Context) =\u003e\n\n      val minecraftServer = new MinecraftServer(image, region, size)\n      val ip = minecraftServer.infrastructure()\n\n      ctx.`export`(\"public ip\", ip)\n    }\n  }\n}\n```\n\nAs you can see, we created a new Object `App` with a main method. In this method we create a new instance of\nour `MinecraftServer` class and call the `infrastructure` method. This method will create the infrastructure for our\nMinecraft Server. The `infrastructure` method returns the public IP address of the Droplet. We export this IP address\nwith the `export` method of the `Context` class. This will make the IP address available as output of our Pulumi\nprogram.\n\n### Create the MinecraftServer class\n\nThe `MinecraftServer` class is the heart of our Pulumi program. It will create the infrastructure for our Minecraft\nServer. We will use the DigitalOcean provider to create a Droplet and a Floating IP. The Droplet will use cloud-init to\ndownload, install and configure the Minecraft Server.\n\nCreate a new file `MinecraftServer.scala` in the `src/main/scala/io/dirien/minecraft` directory and add the following\ncontent:\n\n```scala\npackage io.dirien.minecraft\n\nimport com.pulumi.core.Output\nimport com.pulumi.digitalocean.{Droplet, DropletArgs, SshKey, SshKeyArgs}\nimport com.pulumi.{Context, Pulumi}\nimport com.pulumi.command.remote.{Command, CommandArgs}\nimport com.pulumi.command.remote.inputs.ConnectionArgs\n\nimport scala.io.Source\n\nclass MinecraftServer(image: String, region: String, size: String) {\n\n  def readFile(path: String): String = {\n    val file = Source.fromFile(path)\n    val fileContent = try file.mkString finally file.close()\n    fileContent\n  }\n\n  def infrastructure(): Output[String] = {\n    val cloudInit = readFile(\"src/main/resources/cloud-init.yaml\")\n    val sshPublicKeyString = readFile(\"src/main/resources/minecraft.pub\")\n\n    val sshKey = new SshKey(\"minecraft-scala\", SshKeyArgs.builder\n      .publicKey(sshPublicKeyString)\n      .build())\n\n    val fingerprints: Output[java.util.List[String]] = sshKey.fingerprint().apply(fingerprint =\u003e {\n      Output.listBuilder().add(fingerprint).build()\n    })\n\n    val minecraftServer = new Droplet(\"minecraft\", DropletArgs.builder\n      .image(this.image)\n      .region(this.region)\n      .size(this.size)\n      .userData(cloudInit)\n      .sshKeys(\n        fingerprints\n      )\n      .build())\n\n    val privateKey = readFile(\"src/main/resources/minecraft\")\n\n    new Command(\"install-minecraft\", CommandArgs.builder()\n      .connection(ConnectionArgs.builder()\n        .host(minecraftServer.ipv4Address())\n        .privateKey(privateKey)\n        .user(\"root\")\n        .build())\n      .create(\"cloud-init status --wait\")\n      .build())\n\n    minecraftServer.ipv4Address()\n  }\n}\n```\n\nYou can see that we have a constructor with three parameters: `image`, `region` and `size`. These parameters are used to\ncreate the Droplet.\n\nAs you may have spotted, we have a method `readFile` which reads a file from any given path and takes care of closing\nthe Source.\n\nThere is one convenience Pulumi resource called `Command`. This resource allows us to execute a command on a remote\nhost. In this case, we use it to wait for the cloud-init script to finish.\n\nBefore I forget, you need to create an ssh key pair. You can do this with the following command:\n\n```bash\nssh-keygen -f $PWD/minecraft\n```\n\nand copy both files `minecraft` and `minecraft.pub` to the `src/main/resources` directory. Of course, you can use any\nother name and path, but you need to adjust the calls to `readFile` in the `MinecraftServer` class.\n\nThat's it from the code side. Now we can run our Pulumi program.\n\n### Run the Pulumi program\n\nSet the `DIGITALOCEAN_TOKEN` environment variable to your DigitalOcean API token.\n\n```bash\nexport DIGITALOCEAN_TOKEN=your-token\n```\n\nNow you can run the Pulumi program with the following command:\n\n```bash\nsbt update\npulumi up -f -y\n```\n\nThe first command will download all dependencies. The second command will run the Pulumi program.\n\nAfter a few minutes, you should see the following output:\n\n```bash\n❯ pulumi up -f -y     \nPlease choose a stack, or create a new one: dev\nUpdating (dev)\n\nView Live: https://app.pulumi.com/dirien/pulumi-scala-minecraft/dev/updates/22\n\n     Type                           Name                        Status             \n +   pulumi:pulumi:Stack            pulumi-scala-minecraft-dev  created (44s)      \n +   ├─ digitalocean:index:SshKey   minecraft-scala             created (1s)       \n +   ├─ digitalocean:index:Droplet  minecraft                   created (41s)      \n +   └─ command:remote:Command      install-minecraft           created (122s)     \n\n\nOutputs:\n    public ip: \"xx.yy.zz.aa\"\n\nResources:\n    + 4 created\n\nDuration: 2m53s\n```\n\nYou can see that we created a new stack called `dev`. The stack contains the resources we created. You can see the IP\naddress of the Droplet in the output section.\n\n### Connect to the Minecraft Server\n\nCopy the IP address from the output section and connect to the server in your Minecraft client.\n\nEnjoy your Minecraft Server!\n\n### Clean up\n\nTo clean up the resources, run the following command:\n\n```bash\npulumi destroy -f -y\n```\n\n## Conclusion\n\nIt was very interesting to create a Pulumi program with Scala. I can see why so many developers love Scala. And it works\nreally well with Pulumi. I hope you enjoyed this article. If you have any questions or comments, please let me know in\nthe comments section.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirien%2Fpulumi-scala-minecraft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdirien%2Fpulumi-scala-minecraft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirien%2Fpulumi-scala-minecraft/lists"}