Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 55 additions & 49 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,42 @@ provider "aws" {

data "aws_ami" "windows_ami" {
most_recent = true
owners = ["amazon"]
owners = ["amazon"]

filter {
name = "name"
name = "name"
values = ["Windows_Server-2019-English-Full-Base-*"]
}
}

data "external" "local_ip" {
# curl should (hopefully) be available everywhere
program = ["curl", "https://api.ipify.org?format=json"]
data "http" "local_ip" {
url = "https://api.ipify.org?format=json"
}

data "aws_availability_zones" "available" {
state = "available"
}

locals {
availability_zone = "${var.region}${element(var.allowed_availability_zone_identifier, random_integer.az_id.result)}"
local_ip = jsondecode(data.http.local_ip.response_body).ip
availability_zones = length(var.allowed_availability_zone_identifier) != 0 ? var.allowed_availability_zone_identifier : [for az in data.aws_availability_zones.available.names : substr(az, -1, 1)]
availability_zone_identifier = element(local.availability_zones, random_integer.az_id.result)
availability_zone = "${var.region}${local.availability_zone_identifier}"
}

resource "random_integer" "az_id" {
resource "random_integer" "az_id" {
min = 0
max = length(var.allowed_availability_zone_identifier)
max = length(local.availability_zones)
}

resource "random_password" "password" {
length = 32
length = 32
special = true
}

resource "aws_ssm_parameter" "password" {
name = "${var.resource_name}-administrator-password"
type = "SecureString"
name = "${var.resource_name}-administrator-password"
type = "SecureString"
value = random_password.password.result

tags = {
Expand All @@ -51,39 +57,39 @@ resource "aws_security_group" "default" {

# Allow rdp connections from the local ip
resource "aws_security_group_rule" "rdp_ingress" {
type = "ingress"
description = "Allow rdp connections (port 3389)"
from_port = 3389
to_port = 3389
protocol = "tcp"
cidr_blocks = ["${data.external.local_ip.result.ip}/32"]
type = "ingress"
description = "Allow rdp connections (port 3389)"
from_port = 3389
to_port = 3389
protocol = "tcp"
cidr_blocks = ["${data.external.local_ip.result.ip}/32"]
security_group_id = aws_security_group.default.id
}

# Allow vnc connections from the local ip
resource "aws_security_group_rule" "vnc_ingress" {
type = "ingress"
description = "Allow vnc connections (port 5900)"
from_port = 5900
to_port = 5900
protocol = "tcp"
cidr_blocks = ["${data.external.local_ip.result.ip}/32"]
type = "ingress"
description = "Allow vnc connections (port 5900)"
from_port = 5900
to_port = 5900
protocol = "tcp"
cidr_blocks = ["${data.external.local_ip.result.ip}/32"]
security_group_id = aws_security_group.default.id
}


# Allow outbound connection to everywhere
resource "aws_security_group_rule" "default" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.default.id
}

resource "aws_iam_role" "windows_instance_role" {
name = "${var.resource_name}-instance-role"
name = "${var.resource_name}-instance-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
Expand All @@ -106,7 +112,7 @@ EOF
}

resource "aws_iam_policy" "password_get_parameter_policy" {
name = "${var.resource_name}-password-get-parameter-policy"
name = "${var.resource_name}-password-get-parameter-policy"
policy = <<EOF
{
"Version": "2012-10-17",
Expand All @@ -126,12 +132,12 @@ data "aws_iam_policy" "driver_get_object_policy" {
}

resource "aws_iam_role_policy_attachment" "password_get_parameter_policy_attachment" {
role = aws_iam_role.windows_instance_role.name
role = aws_iam_role.windows_instance_role.name
policy_arn = aws_iam_policy.password_get_parameter_policy.arn
}

resource "aws_iam_role_policy_attachment" "driver_get_object_policy_attachment" {
role = aws_iam_role.windows_instance_role.name
role = aws_iam_role.windows_instance_role.name
policy_arn = data.aws_iam_policy.driver_get_object_policy.arn
}

Expand All @@ -141,28 +147,28 @@ resource "aws_iam_instance_profile" "windows_instance_profile" {
}

resource "aws_spot_instance_request" "windows_instance" {
instance_type = var.instance_type
instance_type = var.instance_type
availability_zone = local.availability_zone
ami = (length(var.custom_ami) > 0) ? var.custom_ami : data.aws_ami.windows_ami.image_id
security_groups = [aws_security_group.default.name]
ami = (length(var.custom_ami) > 0) ? var.custom_ami : data.aws_ami.windows_ami.image_id
security_groups = [aws_security_group.default.name]
user_data = var.skip_install ? "" : templatefile("${path.module}/templates/user_data.tpl", {
password_ssm_parameter=aws_ssm_parameter.password.name,
var={
instance_type=var.instance_type,
install_parsec=var.install_parsec,
install_auto_login=var.install_auto_login,
install_graphic_card_driver=var.install_graphic_card_driver,
install_steam=var.install_steam,
install_gog_galaxy=var.install_gog_galaxy,
install_origin=var.install_origin,
install_epic_games_launcher=var.install_epic_games_launcher,
install_uplay=var.install_uplay,
password_ssm_parameter = aws_ssm_parameter.password.name,
var = {
instance_type = var.instance_type,
install_parsec = var.install_parsec,
install_auto_login = var.install_auto_login,
install_graphic_card_driver = var.install_graphic_card_driver,
install_steam = var.install_steam,
install_gog_galaxy = var.install_gog_galaxy,
install_origin = var.install_origin,
install_epic_games_launcher = var.install_epic_games_launcher,
install_uplay = var.install_uplay,
}
})
iam_instance_profile = aws_iam_instance_profile.windows_instance_profile.id

# Spot configuration
spot_type = "one-time"
spot_type = "one-time"
wait_for_fulfillment = true

# EBS configuration
Expand All @@ -173,7 +179,7 @@ resource "aws_spot_instance_request" "windows_instance" {

tags = {
Name = "${var.resource_name}-instance"
App = "aws-cloud-gaming"
App = "aws-cloud-gaming"
}
}

Expand All @@ -190,6 +196,6 @@ output "instance_public_dns" {
}

output "instance_password" {
value = random_password.password.result
value = random_password.password.result
sensitive = true
}
58 changes: 29 additions & 29 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,89 +1,89 @@
variable "region" {
description = "The aws region. Choose the one closest to you: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions"
type = string
type = string
}

variable "resource_name" {
description = "Name with which to prefix resources in AWS"
type = string
default = "cloud-gaming"
type = string
default = "cloud-gaming"
}

variable "allowed_availability_zone_identifier" {
description = "The allowed availability zone identify (the letter suffixing the region). Choose ones that allows you to request the desired instance as spot instance in your region. An availability zone will be selected at random and the instance will be booted in it."
type = list(string)
default = ["a", "b"]
type = list(string)
default = ["a", "b"]
}

variable "instance_type" {
description = "The aws instance type, Choose one with a CPU/GPU that fits your need: https://aws.amazon.com/ec2/instance-types/#Accelerated_Computing"
type = string
default = "g4dn.xlarge"
type = string
default = "g4dn.xlarge"
}

variable "root_block_device_size_gb" {
description = "The size of the root block device (C:\\ drive) attached to the instance"
type = number
default = 120
type = number
default = 120
}

variable "custom_ami" {
description = "Use the specified AMI instead of the most recent windows AMI in available in the region"
type = string
default = ""
type = string
default = ""
}


variable "skip_install" {
description = "Skip installation step on startup. Useful when using a custom AMI that is already setup"
type = bool
default = false
type = bool
default = false
}

variable "install_parsec" {
description = "Download and run Parsec-Cloud-Preparation-Tool on first login"
type = bool
default = true
type = bool
default = true
}

variable "install_auto_login" {
description = "Configure auto-login on first boot"
type = bool
default = true
type = bool
default = true
}

variable "install_graphic_card_driver" {
description = "Download and install the Nvidia driver on first boot"
type = bool
default = true
type = bool
default = true
}

variable "install_steam" {
description = "Download and install Valve Steam on first boot"
type = bool
default = true
type = bool
default = true
}

variable "install_gog_galaxy" {
description = "Download and install GOG Galaxy on first boot"
type = bool
default = false
type = bool
default = false
}

variable "install_uplay" {
description = "Download and install Ubisoft Uplay on first boot"
type = bool
default = false
type = bool
default = false
}

variable "install_origin" {
description = "Download and install EA Origin on first boot"
type = bool
default = false
type = bool
default = false
}

variable "install_epic_games_launcher" {
description = "Download and install EPIC Games Launcher on first boot"
type = bool
default = false
type = bool
default = false
}