├── ec2gaming.cfg ├── scripts ├── ec2gaming-vnc.sh ├── ec2gaming-stop.sh ├── ec2gaming-vpndown.sh ├── ec2gaming-trustpolicy.json ├── ec2gaming-rdp.sh ├── ec2gaming.ovpn.template ├── ec2gaming-ip.sh ├── ec2gaming-reboot.sh ├── ec2gaming-terminate.sh ├── ec2gaming-vpnup.tunnelblick.scpt ├── ec2gaming-vpndown.tunnelblick.scpt ├── ec2gaming-price.sh ├── ec2gaming-vpndown.viscosity.scpt ├── ec2gaming-vpnup.viscosity.scpt ├── ec2gaming-permissionpolicy.json.template ├── ec2gaming.bat.template ├── ec2gaming.header ├── ec2gaming-instance.sh ├── ec2gaming.rdp.template ├── ec2gaming-vpnup.sh ├── ec2gaming-snapshot.sh ├── ec2gaming-ca.crt └── ec2gaming-start.sh ├── .gitignore ├── README.md └── ec2gaming /ec2gaming.cfg: -------------------------------------------------------------------------------- 1 | INSTANCE_TYPE="g2.2xlarge" 2 | SPOT_PRICE_BUFFER="0.10" 3 | VPN_CLIENT="tunnelblick" 4 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vnc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | open "vnc://$USERNAME:$PASSWORD@10.8.0.1" 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ec2gaming.auth 2 | ec2gaming.bat 3 | scripts/ec2gaming-permissionpolicy.json 4 | scripts/ec2gaming.ovpn 5 | scripts/ec2gaming.rdp 6 | 7 | -------------------------------------------------------------------------------- /scripts/ec2gaming-stop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | ./ec2gaming-vpndown.sh 5 | ./ec2gaming-terminate.sh 6 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vpndown.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | echo -n "Disconnecting VPN... " 5 | osascript "ec2gaming-vpndown.$VPN_CLIENT.scpt" 6 | -------------------------------------------------------------------------------- /scripts/ec2gaming-trustpolicy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": { 4 | "Effect": "Allow", 5 | "Principal": {"Service": "ec2.amazonaws.com"}, 6 | "Action": "sts:AssumeRole" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scripts/ec2gaming-rdp.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | echo "Starting Remote Desktop..." 5 | IP=$(./ec2gaming-ip.sh) 6 | sed "s/IP/$IP/g" ec2gaming.rdp.template > ec2gaming.rdp 7 | open ec2gaming.rdp 8 | -------------------------------------------------------------------------------- /scripts/ec2gaming.ovpn.template: -------------------------------------------------------------------------------- 1 | client 2 | dev tap 3 | proto udp 4 | remote IP 1194 5 | resolv-retry infinite 6 | nobind 7 | persist-key 8 | persist-tun 9 | ca ec2gaming-ca.crt 10 | verb 3 11 | auth-user-pass AUTH 12 | cipher none 13 | -------------------------------------------------------------------------------- /scripts/ec2gaming-ip.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | INSTANCE_ID=$(./ec2gaming-instance.sh) 5 | aws ec2 describe-instances --instance-ids "$INSTANCE_ID" | jq --raw-output '.Reservations[0].Instances[0].PublicIpAddress' 6 | -------------------------------------------------------------------------------- /scripts/ec2gaming-reboot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | INSTANCE_ID=$(./ec2gaming-instance.sh) 5 | echo "Rebooting gaming instance ($INSTANCE_ID)..." 6 | aws ec2 reboot-instances --instance-ids "$INSTANCE_ID" > /dev/null 7 | -------------------------------------------------------------------------------- /scripts/ec2gaming-terminate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | INSTANCE_ID=$(./ec2gaming-instance.sh) 5 | echo "Terminating gaming instance ($INSTANCE_ID)..." 6 | aws ec2 terminate-instances --instance-ids "$INSTANCE_ID" > /dev/null 7 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vpnup.tunnelblick.scpt: -------------------------------------------------------------------------------- 1 | tell application "Tunnelblick" 2 | connect "ec2gaming" 3 | get state of first configuration where name = "ec2gaming" 4 | repeat until result = "CONNECTED" 5 | delay 1 6 | get state of first configuration where name = "ec2gaming" 7 | end repeat 8 | end tell 9 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vpndown.tunnelblick.scpt: -------------------------------------------------------------------------------- 1 | tell application "Tunnelblick" 2 | disconnect "ec2gaming" 3 | get state of first configuration where name = "ec2gaming" 4 | repeat until result = "EXITING" 5 | delay 1 6 | get state of first configuration where name = "ec2gaming" 7 | end repeat 8 | end tell 9 | -------------------------------------------------------------------------------- /scripts/ec2gaming-price.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | aws ec2 describe-spot-price-history --instance-types "$INSTANCE_TYPE" --product-descriptions "Windows" --start-time `date +%s` | jq --raw-output '.SpotPriceHistory|=sort_by(.SpotPrice)|first(.SpotPriceHistory[].SpotPrice), first(.SpotPriceHistory[].AvailabilityZone)' 5 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vpndown.viscosity.scpt: -------------------------------------------------------------------------------- 1 | tell application "Viscosity" 2 | disconnect (connections where name is "ec2gaming") 3 | set currentState to state of connections where name is "ec2gaming" 4 | repeat until currentState = "Disconnected" 5 | delay 1 6 | set currentState to state of connections where name is "ec2gaming" 7 | set currentState to currentState as string 8 | end repeat 9 | end tell 10 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vpnup.viscosity.scpt: -------------------------------------------------------------------------------- 1 | tell application "Viscosity" 2 | set currentState to "Unknown" 3 | repeat until (currentState = "Connected") 4 | if currentState = "Disconnected" then 5 | connect (connections where name is "ec2gaming") 6 | end if 7 | set currentState to state of connections where name is "ec2gaming" 8 | set currentState to currentState as string 9 | delay 1 10 | end repeat 11 | end tell 12 | -------------------------------------------------------------------------------- /scripts/ec2gaming-permissionpolicy.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": ["s3:ListBucket"], 7 | "Resource": ["arn:aws:s3:::BUCKET"] 8 | }, 9 | { 10 | "Effect": "Allow", 11 | "Action": [ 12 | "s3:PutObject", 13 | "s3:GetObject", 14 | "s3:DeleteObject" 15 | ], 16 | "Resource": ["arn:aws:s3:::BUCKET/*"] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /scripts/ec2gaming.bat.template: -------------------------------------------------------------------------------- 1 | @echo off 2 | rmdir /Q /S "C:\Program Files (x86)\Steam\steamapps" 3 | md Z:\SteamLibrary\steamapps 4 | cmd /c mklink /j "C:\Program Files (x86)\Steam\steamapps" Z:\SteamLibrary\steamapps 5 | md Z:\Documents 6 | aws s3 sync Z:\Documents s3://BUCKET/Documents 7 | if %errorlevel% neq 0 exit /b %errorlevel% 8 | schtasks /Create /RU USERNAME /RP PASSWORD /F /SC MINUTE /MO 1 /TN "Sync Documents with S3" /TR "aws s3 sync Z:\Documents s3://ec2gaming-639801188054/Documents --delete" 9 | -------------------------------------------------------------------------------- /scripts/ec2gaming.header: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | cd "$(dirname "$0")" || exit 4 | source ../ec2gaming.cfg 5 | 6 | USERNAME=$(head -1 ../ec2gaming.auth) 7 | PASSWORD=$(tail -1 ../ec2gaming.auth) 8 | 9 | describe_gaming_image() { 10 | aws ec2 describe-images --owner "$1" --filters Name=name,Values=ec2gaming 11 | } 12 | 13 | num_images() { 14 | echo "$1" | jq '.Images | length' 15 | } 16 | 17 | describe_security_group() { 18 | aws ec2 describe-security-groups | jq -r '.SecurityGroups[] | select (.GroupName == "'"$1"'") | .GroupId' 19 | } 20 | -------------------------------------------------------------------------------- /scripts/ec2gaming-instance.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | # Verify that the gaming stane actually exists (and that there's only one) 5 | INSTANCES=$(aws ec2 describe-instances --filters Name=instance-state-code,Values=16 Name=instance-type,Values="$INSTANCE_TYPE") 6 | if [ "$(echo "$INSTANCES" | jq '.Reservations | length')" -ne "1" ]; then 7 | >&2 echo "didn't find an instance or there wasn't exactly one $INSTANCE_TYPE instance" 8 | exit 1 9 | fi 10 | echo "$INSTANCES" | jq --raw-output '.Reservations[0].Instances[0].InstanceId' 11 | -------------------------------------------------------------------------------- /scripts/ec2gaming.rdp.template: -------------------------------------------------------------------------------- 1 | screen mode id:i:1 2 | desktopwidth:i:1280 3 | desktopheight:i:1024 4 | use multimon:i:1 5 | session bpp:i:24 6 | full address:s:IP 7 | audiomode:i:0 8 | username:s:administrator 9 | disable wallpaper:i:0 10 | disable full window drag:i:0 11 | disable menu anims:i:0 12 | disable themes:i:0 13 | alternate shell:s: 14 | shell working directory:s: 15 | authentication level:i:2 16 | connect to console:i:1 17 | gatewayusagemethod:i:0 18 | disable cursor setting:i:0 19 | allow font smoothing:i:1 20 | allow desktop composition:i:1 21 | redirectprinters:i:0 22 | prompt for credentials on client:i:0 23 | autoreconnection enabled:i:1 24 | 25 | 26 | bookmarktype:i:3 27 | use redirection server name:i:0 28 | 29 | authoring tool:s:rdmac 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ec2gaming - EC2 Gaming on macOS 2 | 3 | Provides command line tools that makes gaming on EC2 simple and reliable. Includes steps to create an AMI that requires no intervention on startup, allows Steam remote installs and minimizes the amount of time game installs take. 4 | 5 | Full documentation is available on the [wiki](https://github.com/DanielThomas/ec2gaming/wiki). Based on [Larry Gadea's](http://lg.io/) excellent work. 6 | 7 | # Before you begin 8 | 9 | Follow the [first time configuration](https://github.com/DanielThomas/ec2gaming/wiki/First-time-configuration) steps. They help you setup the tools, and streamline creation of your personalized AMI. 10 | 11 | # Gaming! 12 | 13 | - Run `ec2gaming start`. The instance, VPN and Steam will automatically start 14 | - Wait for the notification that the remote gaming host is available for home streaming 15 | - Enjoy! 16 | - When you're done, run `ec2gaming stop` 17 | 18 | # Help 19 | 20 | The original blog posts and the cloudygamer subreddit are great resources: 21 | 22 | - http://lg.io/2015/07/05/revised-and-much-faster-run-your-own-highend-cloud-gaming-service-on-ec2.html 23 | - https://www.reddit.com/r/cloudygamer/ 24 | -------------------------------------------------------------------------------- /scripts/ec2gaming-vpnup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | echo "Connecting VPN (you may see an authentication prompt)... " 5 | IP=$(./ec2gaming-ip.sh) 6 | AUTH=$(realpath "$(pwd)/../ec2gaming.auth") 7 | CONFIG_EXISTS=0 8 | 9 | # Find if config exists 10 | if [ "$VPN_CLIENT" = "tunnelblick" ]; then 11 | BACKING_CONFIG=~/Library/Application\ Support/Tunnelblick/Configurations/ec2gaming.tblk/Contents/Resources/config.ovpn 12 | if [ -f "$BACKING_CONFIG" ]; then 13 | CONFIG_EXISTS=1 14 | # the authentication prompt on copy will block, avoids the messy sleep 15 | sed "s#IP#$IP#g;s#AUTH#$AUTH#g" ec2gaming.ovpn.template > "$BACKING_CONFIG" 16 | fi 17 | elif [ "$VPN_CLIENT" = "viscosity" ]; then 18 | grep -R ec2gaming ~/Library/Application\ Support/Viscosity/OpenVPN > /dev/null 19 | if [ $? -eq 0 ]; then 20 | CONFIG_EXISTS=1 21 | fi 22 | fi 23 | 24 | # Create config if needed 25 | if [ $CONFIG_EXISTS -eq 0 ]; then 26 | sed "s#IP#$IP#g;s#AUTH#$AUTH#g" ec2gaming.ovpn.template > ec2gaming.ovpn 27 | open ec2gaming.ovpn 28 | echo "Waiting 10 seconds for import..." 29 | sleep 10 30 | fi 31 | 32 | osascript "ec2gaming-vpnup.$VPN_CLIENT.scpt" 33 | -------------------------------------------------------------------------------- /scripts/ec2gaming-snapshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | INSTANCE_ID=$(./ec2gaming-instance.sh) 5 | 6 | # Only allow one ec2gaming AMI to exist 7 | echo -n "Checking if an AMI 'ec2gaming' already exists... " 8 | AMIS=$( aws ec2 describe-images --owner self --filters Name=name,Values=ec2gaming ) 9 | if [ $( echo "$AMIS" | jq '.Images | length' ) -ne "0" ]; then 10 | AMI_ID=$( echo "$AMIS" | jq --raw-output '.Images[0].ImageId' ) 11 | echo "yes, $AMI_ID" 12 | echo "Deregistering that AMI..." 13 | aws ec2 deregister-image --image-id $AMI_ID 14 | echo "Deleting AMI's backing Snapshot..." 15 | aws ec2 delete-snapshot --snapshot-id $( echo "$AMIS" | jq --raw-output '.Images[0].BlockDeviceMappings[0].Ebs.SnapshotId' ) 16 | else 17 | echo "no" 18 | fi 19 | 20 | # Create an AMI from the existing instance (so we can restore it next time) 21 | echo -n "Starting AMI creation... " 22 | AMI_ID=$( aws ec2 create-image --instance-id "$INSTANCE_ID" --name "ec2gaming" | jq --raw-output '.ImageId' ) 23 | echo "$AMI_ID" 24 | 25 | echo "Waiting for AMI to be created..." 26 | if ! aws ec2 wait image-available --image-id "$AMI_ID"; then 27 | echo "AMI never finished being created!"; 28 | exit 29 | fi 30 | -------------------------------------------------------------------------------- /scripts/ec2gaming-ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDwjCCAyugAwIBAgIJAIh6dpQmAO9rMA0GCSqGSIb3DQEBBQUAMIGdMQswCQYD 3 | VQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEQMA4G 4 | A1UEChMHT3BlblZQTjERMA8GA1UECxMIY2hhbmdlbWUxETAPBgNVBAMTCGNoYW5n 5 | ZW1lMREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0 6 | LmRvbWFpbjAeFw0xNTA3MDQwNDQwNTdaFw0yNTA3MDEwNDQwNTdaMIGdMQswCQYD 7 | VQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEQMA4G 8 | A1UEChMHT3BlblZQTjERMA8GA1UECxMIY2hhbmdlbWUxETAPBgNVBAMTCGNoYW5n 9 | ZW1lMREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0 10 | LmRvbWFpbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw/kwLjXwgwhxldz6 11 | e1oGHbqlVScp2eq09PxNqOOw8j9SH1blCsEyjDzPxUtX7rw1lwkcG7RjouuSHLaT 12 | eS/95mpK+OEij5UXWf3oQQx+ioL2Lmg1tmmrVrmP01mTmVpzSXHbqgXvN1mYD1U4 13 | FtQ4znI8JJw6uYbJ8E1Gjn3p0sMCAwEAAaOCAQYwggECMB0GA1UdDgQWBBQ470iz 14 | KT+UIK92e/m2EBu4micARjCB0gYDVR0jBIHKMIHHgBQ470izKT+UIK92e/m2EBu4 15 | micARqGBo6SBoDCBnTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRUwEwYDVQQH 16 | EwxTYW5GcmFuY2lzY28xEDAOBgNVBAoTB09wZW5WUE4xETAPBgNVBAsTCGNoYW5n 17 | ZW1lMREwDwYDVQQDEwhjaGFuZ2VtZTERMA8GA1UEKRMIY2hhbmdlbWUxHzAdBgkq 18 | hkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQCIenaUJgDvazAMBgNVHRMEBTAD 19 | AQH/MA0GCSqGSIb3DQEBBQUAA4GBAAiK1y+lUlNgNNVHyh/IL0ChuHtki1tw8lr9 20 | 0j97jsSBWZlEWoszlijKlMnRGzWBBlhPag+qo5yuRdArcpFtyI6W3IrA85CjONrF 21 | meO94N/UMqbdNA44TX7ZxIJVj8orXIeH4oWcOFBl8fFlB3tS9N3TH/KNnNMglB1g 22 | TBR/CvR6 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /ec2gaming: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | cd "$(dirname "$0")/scripts" || exit 4 | 5 | COMMANDS=($(find . -name 'ec2gaming-*.sh' | sed 's/.*ec2gaming-//;s/\.sh//')) 6 | 7 | if [ -z ${1+x} ]; then 8 | echo "macOS EC2 Gaming with Steam In-Home Streaming" 9 | echo 10 | echo "usage: ec2gaming " 11 | echo 12 | echo "Gaming commands" 13 | echo "start Start gaming - starts instance, VPN and Steam" 14 | echo "stop Stop gaming - stops instance and VPN" 15 | echo 16 | echo "Remote access commands" 17 | echo "rdp Remote desktop connection (no VPN, requires login)" 18 | echo "vnc VNC session (requires VPN, automatic login)" 19 | echo "vpndown Disconnect VPN" 20 | echo "vpnup Connect VPN" 21 | echo 22 | echo "EC2 commands" 23 | echo "instance Get the instance id" 24 | echo "ip Get the IP address of the instance" 25 | echo "price Get the current lowest spot price" 26 | echo "reboot Reboot the instance" 27 | echo "snapshot Snapshot the instance and recreate AMI" 28 | echo "terminate Terminate the instance" 29 | echo 30 | echo "All supported commands" 31 | printf '%s\n' "${COMMANDS[@]}" 32 | echo 33 | echo "For help, go to https://www.reddit.com/r/cloudygamer/" 34 | exit 35 | fi 36 | 37 | if [[ ! " ${COMMANDS[@]} " =~ " ${1} " ]]; then 38 | echo "Unknown command '$1'. Supported commands:" 39 | printf '%s\n' "${COMMANDS[@]}" 40 | exit 1 41 | else 42 | ./ec2gaming-$1.sh 43 | fi 44 | -------------------------------------------------------------------------------- /scripts/ec2gaming-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source "$(dirname "$0")/ec2gaming.header" 3 | 4 | BOOTSTRAP=0 5 | 6 | echo -n "Getting lowest $INSTANCE_TYPE bid... " 7 | PRICE_AND_ZONE=($(./ec2gaming-price.sh)) 8 | PRICE=${PRICE_AND_ZONE[0]} 9 | ZONE=${PRICE_AND_ZONE[1]} 10 | echo "$PRICE in $ZONE" 11 | 12 | FINAL_SPOT_PRICE=$(bc <<< "$PRICE + $SPOT_PRICE_BUFFER") 13 | echo "Setting price for spot instance at $FINAL_SPOT_PRICE ($SPOT_PRICE_BUFFER higher than lowest spot price)" 14 | 15 | echo -n "Looking for the ec2gaming AMI... " 16 | AMI_SEARCH=$(describe_gaming_image self) 17 | if [ "$(num_images "$AMI_SEARCH")" -eq "0" ]; then 18 | echo -n "not found. Going into bootstrap mode... " 19 | BOOTSTRAP=1 20 | AMI_SEARCH=$(describe_gaming_image 255191696678) 21 | if [ "$(num_images "$AMI_SEARCH")" -eq "0" ]; then 22 | echo "not found. Exiting." 23 | exit 1 24 | fi 25 | fi 26 | AMI_ID="$(echo "$AMI_SEARCH" | jq --raw-output '.Images[0].ImageId')" 27 | echo "$AMI_ID" 28 | 29 | echo -n "Looking for security groups... " 30 | EC2_SECURITY_GROUP_ID=$(describe_security_group ec2gaming) 31 | if [ -z "$EC2_SECURITY_GROUP_ID" ]; then 32 | echo -n "not found. Creating security group... " 33 | aws ec2 create-security-group --group-name ec2gaming --description "EC2 Gaming" > /dev/null 34 | aws ec2 authorize-security-group-ingress --group-name ec2gaming --protocol tcp --port 3389 --cidr "0.0.0.0/0" 35 | aws ec2 authorize-security-group-ingress --group-name ec2gaming --protocol tcp --port 1194 --cidr "0.0.0.0/0" 36 | aws ec2 authorize-security-group-ingress --group-name ec2gaming --protocol udp --port 1194 --cidr "0.0.0.0/0" 37 | EC2_SECURITY_GROUP_ID=$(describe_security_group ec2gaming) 38 | fi 39 | echo "$EC2_SECURITY_GROUP_ID" 40 | 41 | echo -n "Looking for S3 bucket... " 42 | ACCOUNT_ID=$(aws iam get-user | jq '.User.Arn' | cut -d ':' -f 5) 43 | BUCKET="ec2gaming-$ACCOUNT_ID" 44 | if ! aws s3api head-bucket --bucket "$BUCKET" &> /dev/null; then 45 | echo -n "not found. Creating... " 46 | REGION=$(aws configure get region) 47 | 48 | if REGION == 'us-east-1'; then 49 | REGION='' 50 | fi 51 | 52 | aws s3api create-bucket --bucket "$BUCKET" --region "$REGION" --create-bucket-configuration LocationConstraint="$REGION" > /dev/null 53 | fi 54 | sed "s/BUCKET/$BUCKET/g;s/USERNAME/$USERNAME/g;s/PASSWORD/$PASSWORD/g" ec2gaming.bat.template > ../ec2gaming.bat 55 | echo "$BUCKET" 56 | 57 | PROFILE_NAME="ec2gaming" 58 | echo -n "Looking for instance profile... " 59 | if ! aws iam get-instance-profile --instance-profile-name ec2gaming &> /dev/null; then 60 | echo -n "not found. Creating... " 61 | aws iam create-role --role-name "$PROFILE_NAME" --assume-role-policy-document file://ec2gaming-trustpolicy.json > /dev/null 62 | sed "s/BUCKET/$BUCKET/g" ec2gaming-permissionpolicy.json.template > ec2gaming-permissionpolicy.json 63 | aws iam put-role-policy --role-name "$PROFILE_NAME" --policy-name "$PROFILE_NAME" --policy-document file://ec2gaming-permissionpolicy.json > /dev/null 64 | aws iam create-instance-profile --instance-profile-name "$PROFILE_NAME" > /dev/null 65 | aws iam add-role-to-instance-profile --instance-profile-name "$PROFILE_NAME" --role-name "$PROFILE_NAME" > /dev/null 66 | aws iam wait instance-profile-exists --instance-profile-name ec2gaming 67 | fi 68 | INSTANCE_PROFILE_ARN=$(aws iam get-instance-profile --instance-profile-name ec2gaming | jq -r '.InstanceProfile.Arn') 69 | echo "$INSTANCE_PROFILE_ARN" 70 | 71 | echo -n "Creating spot instance request... " 72 | SPOT_INSTANCE_ID=$(aws ec2 request-spot-instances --spot-price "$FINAL_SPOT_PRICE" --launch-specification " 73 | { 74 | \"SecurityGroupIds\": [\"$EC2_SECURITY_GROUP_ID\"], 75 | \"ImageId\": \"$AMI_ID\", 76 | \"InstanceType\": \"$INSTANCE_TYPE\", 77 | \"Placement\": { 78 | \"AvailabilityZone\": \"$ZONE\" 79 | }, 80 | \"IamInstanceProfile\": { 81 | \"Arn\": \"$INSTANCE_PROFILE_ARN\" 82 | } 83 | }" | jq --raw-output '.SpotInstanceRequests[0].SpotInstanceRequestId') 84 | echo "$SPOT_INSTANCE_ID" 85 | 86 | echo -n "Waiting for instance to be launched... " 87 | aws ec2 wait spot-instance-request-fulfilled --spot-instance-request-ids "$SPOT_INSTANCE_ID" 88 | 89 | INSTANCE_ID=$(aws ec2 describe-spot-instance-requests --spot-instance-request-ids "$SPOT_INSTANCE_ID" | jq --raw-output '.SpotInstanceRequests[0].InstanceId') 90 | echo "$INSTANCE_ID" 91 | 92 | echo -n "Removing the spot instance request... " 93 | aws ec2 cancel-spot-instance-requests --spot-instance-request-ids "$SPOT_INSTANCE_ID" > /dev/null 94 | echo "done" 95 | 96 | echo -n "Waiting for instance IP... " 97 | aws ec2 wait instance-running --instance-ids "$INSTANCE_ID" 98 | IP=$(./ec2gaming-ip.sh) 99 | echo "$IP" 100 | 101 | echo -n "Waiting for server to become available... " 102 | while ! nc -z "$IP" 3389 &> /dev/null; do sleep 5; done; 103 | echo "up!" 104 | 105 | if [ "$BOOTSTRAP" -eq "1" ]; then 106 | ./ec2gaming-rdp.sh 107 | else 108 | ./ec2gaming-vpnup.sh 109 | 110 | echo "Starting Steam..." 111 | open steam:// 112 | fi 113 | --------------------------------------------------------------------------------