├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Documentation ├── Unreal-Engine-Pixel-Streaming-Architecture.png └── Unreal-Engine-Pixel-Streaming-Deployment-Guide.pdf ├── LICENSE ├── README.md ├── UE4-Pixel-Streamer-Bootstrap.ps1 └── UE4-Pixel-Streamer.json /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /Documentation/Unreal-Engine-Pixel-Streaming-Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/deploying-unreal-engine-pixel-streaming-server-on-ec2/1f017bd71095a3443beced25f6f7c411e4878ce6/Documentation/Unreal-Engine-Pixel-Streaming-Architecture.png -------------------------------------------------------------------------------- /Documentation/Unreal-Engine-Pixel-Streaming-Deployment-Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/deploying-unreal-engine-pixel-streaming-server-on-ec2/1f017bd71095a3443beced25f6f7c411e4878ce6/Documentation/Unreal-Engine-Pixel-Streaming-Deployment-Guide.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deploying Unreal Engine Pixel Streaming Server on EC2 2 | 3 | This sample is for those who use Unreal Engine 4 to build content and wish to deploy this content to an audience via UE4 pixel streams. Content examples include but are not limited to: interactive entertainment, architectural visualization, high fidelity car configurators, or anyone who needs to let users access high quality interactive content via thin clients such as web browsers. 4 | 5 | This sample deployment should take about 1 hour to complete, assuming you have an application with Pixel Streaming enabled. The 1-hour deployment includes: 6 | 1. Creating an AWS account with proper permissions 7 | 1. Creating the S3 bucket and uploading required files to S3 8 | 1. Configuring CloudFormation template to be launched 9 | 10 | If you do not have an application with Pixel Streaming, please go to [the getting started with Pixel Streaming guide](https://docs.unrealengine.com/4.26/en-US/SharingAndReleasing/PixelStreaming/PixelStreamingIntro/). 11 | 12 | ## Working with UE4 Pixel Streaming on AWS 13 | 14 | Using AWS and Unreal Engine 4’s Pixel Streaming solution, developers can create content with Unreal Engine and deploy on AWS so users can engage with the content from any modern Web browser. A build of the UE4 content is run on an Amazon Elastic Compute Cloud (Amazon EC2) G4 instance. G4 instances are GPU instances that are designed for graphics-intensive workloads and offer a powerful, low-cost, pay-as-you-go model which is ideal for on-demand interactive content. 15 | 16 | This Quick Start deployment sets up an EC2 environment on AWS that includes the following: 17 | 18 | * [Unreal Engine 4 Pixel Streaming](https://docs.unrealengine.com/en-US/Platforms/PixelStreaming/index.html) components from your pixel streaming build are installed and run on startup. Components include UE4 Windows build with pixel streaming plug-in executable, Stun Server, Turn Server, and Signaling Web Server. 19 | * [Nice DCV](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjegIuN6YLsAhUIna0KHdNXCBwQFjAAegQIAxAB&url=https%3A%2F%2Faws.amazon.com%2Fhpc%2Fdcv%2F&usg=AOvVaw3zloCNRymwGNnFAuD7OP3M) is installed allowing developers to connect to the G4 instance, for a low latency remote desktop experience that supports resolutions up to 4k. This allows a developer to remote in to test the build and optionally installUnreal Engine 4 directly on the machine. 20 | 21 | ## Deployment Guide 22 | 23 | Follow the steps outlined in the [Unreal Engine Pixel Streaming Deployment Guide](Documentation/Unreal-Engine-Pixel-Streaming-Deployment-Guide.pdf). Once deployed the CloudFormation stack will deploy the below architecture: 24 | 25 | ![Architecture Diagram](Documentation/Unreal-Engine-Pixel-Streaming-Architecture.png) 26 | 27 | ## CloudFormation Template Parameters 28 | 29 | | Parameters | Details | Default Value | 30 | | --------------------------- |:------------------------------------------------------------------------------------------|:-------------------| 31 | |InstanceType | Amazon EC2 instance type for the pixel streaming server. Size should be smallest instance size that achieves required performance. | g4dn.xlarge | 32 | |OsVersion | Specify the version of Windows(Windows Server 2019) OS to use. Valid values are “WindowsServer2019”, “WindowsServer2016”, or “WindowsServer2012R2”. | Windows Server 2019 | 33 | |DiskSize | Volume size for the host, in GB. | 50 | 34 | |KeyPairName | Name of AWS EC2 Key Pair. This is not used when logging into machine, but needed to secure instance on VPC. | Requires input | 35 | |UserPasswd | Windows Administrator password used for logging into EC2 via NICE DCV or other administration. It is recommended that you change this default password. | Ch4ng3M3! | 36 | |PixelStreamerBootstrapLocation | Specify the location of bootstrap file in S3 which is executed upon initial launch of EC2 instance. | Requires input | 37 | |PixelStreamerBuildLocation | Specify the location of UE4 Pixel Streamer build zip file in S3. | Requires input | 38 | |PixelStreamingAccessCIDR | IP address range, as an access CIDR, of pixel stream viewers. If your viewers are coming from a specific range, limit the access. | 0.0.0.0/0 | 39 | |NiceDCVAccessCIDR | IP address range, as an access CIDR, of admins and developers to access server via NICE DCV. It is recommended that you limit this to only trusted IPs, such as specifying your own IP. | 0.0.0.0/0 | 40 | |Windows AMIs | Default values ensure that the latest Windows AMI published by AWS is used. You can also define a different AMI to use with a different path. | AWS Defined AMI Paths | 41 | 42 | ## Additional Resources 43 | 44 | * Unreal Engine Pixel Streaming Documentation - 45 | * Amazon EC2 - 46 | * AWS CloudFormation - 47 | 48 | ## Solution Notes 49 | 50 | * This solution supports launching of one instance of a UE4 Pixel Streamer. Once you have a successful instance you can create an AMI and setup an Auto Scaling group following AWS best practices. You would need to track the launched instances and IP addresses that are available to suit your use case. Refer to the links below to get started: 51 | * Create a custom Windows AMI - 52 | * Getting started with Amazon EC2 Auto Scaling - 53 | * NVIDIA driver used is the default Tesla drivers. DirectX drivers are installed by the Unreal Engine prerequisite installer. NVIDIA gaming drivers can be used by remoting into the instance and installing based on the steps in the [NVIDIA EC2 driver documentation](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/install-nvidia-driver.html#nvidia-gaming-driver). 54 | 55 | ## Security 56 | 57 | There are several security-related aspects of the architecture in this sample. The solution is deployed into the default VPC. It creates a security group that allows fine-grained control of traffic in and out of the EC2 hosting the Pixel Streaming server. You can limit access to IP addresses that need to access the host (see the HostAccessCIDR parameter earlier in this guide). This helps keep the host protected from malicious attacks and helps protect the data (UE4 Pixel Streaming build, in this case). 58 | 59 | ## License 60 | 61 | This library is licensed under the MIT-0 License. See the LICENSE file. 62 | -------------------------------------------------------------------------------- /UE4-Pixel-Streamer-Bootstrap.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .SYNOPSIS 4 | Script to automate setup of environment and download of exported project. Streamer launched from StartPixelStreaming.ps1 file in project automatically. 5 | 6 | .DESCRIPTION 7 | 8 | .NOTES 9 | You will need to modify the $buildExecutable variable below to match the file name for your executable in your build. 10 | 11 | .LINK 12 | 13 | #> 14 | 15 | $buildExecutable = "ProjectBuild.exe" 16 | $basePath = "C:\PixelStreamer\Downloads" 17 | 18 | Write-Output "Starting UE4-Pixel-Streamer-Bootstrap.ps1 from:", $basePath 19 | 20 | # Create basePath if unless it already exists. 21 | if(!(Test-Path -Path $basePath )){ 22 | New-Item -ItemType directory -Path $basePath 23 | } 24 | 25 | Write-Output "Installing Node.js" 26 | Invoke-WebRequest -Uri "https://nodejs.org/dist/v12.8.1/node-v12.8.1-x64.msi" -OutFile "$basePath\node-v12.8.1-x64.msi" 27 | Start-Process -FilePath "$basePath\node-v12.8.1-x64.msi" -ArgumentList "/quiet" -Wait 28 | $env:Path += ";C:\Program Files\nodejs\;C:\Users\Administrator\AppData\Roaming\npm" 29 | Write-Output "Node.js Installed" 30 | 31 | Write-Output "Adding Windows Firewall Rules for UE4 Pixel Streaming" 32 | New-NetFirewallRule -DisplayName 'UE4 Pixel Streamer' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 80 33 | New-NetFirewallRule -DisplayName 'UE4 Pixel Streamer' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 443 34 | New-NetFirewallRule -DisplayName 'UE4 Pixel Streamer' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 19302-19303 35 | New-NetFirewallRule -DisplayName 'UE4 Pixel Streamer' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8888 36 | New-NetFirewallRule -DisplayName 'UE4 Pixel Streamer' -Direction Inbound -Action Allow -Protocol UDP -LocalPort 8888 37 | New-NetFirewallRule -DisplayName 'UE4 Pixel Streamer' -Direction Inbound -Action Allow -Protocol UDP -LocalPort 19302-19303 38 | Write-Output "Windows Firewall Rules Added for UE4 Pixel Streaming" 39 | 40 | Write-Output "Beginning UE4 Project Extraction" 41 | Expand-Archive -Force -LiteralPath "$basePath\PixelStreamerProject.zip" -DestinationPath C:\PixelStreamer 42 | Write-Output "UE4 Project Downloaded and Extracted" 43 | 44 | Write-Output "Install UE4 Prerequisites" 45 | Install-WindowsFeature NET-Framework-Core 46 | Start-Process -FilePath "C:\PixelStreamer\WindowsNoEditor\Engine\Extras\Redist\en-us\UE4PrereqSetup_x64.exe" -ArgumentList "/passive /quiet /norestart /log C:\PixelStreamer\WindowsNoEditor\Engine\Extras\Redist\en-us\UE4PreReqInstall.log" -Wait 47 | Write-Output "UE4 Prerequisites Installed" 48 | 49 | # Run Pixel Streamer as SYSTEM and on startup 50 | $principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest 51 | $action = New-ScheduledTaskAction -Execute "C:\PixelStreamer\WindowsNoEditor\$buildExecutable" -Argument "-PixelStreamingIP=localhost -PixelStreamingPort=8888 -RenderOffScreen" 52 | $trigger = New-ScheduledTaskTrigger -AtStartup 53 | Register-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -TaskName "UE4PixelStreamer-Project-Launch" -Description "UE4PixelStreamer-Project-Launch" 54 | 55 | $principal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest 56 | $action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "C:\PixelStreamer\WindowsNoEditor\Samples\PixelStreaming\WebServers\SignallingWebServer\platform_scripts\cmd\Start_SignallingServer.ps1" 57 | $trigger = New-ScheduledTaskTrigger -AtStartup 58 | Register-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -TaskName "UE4PixelStreamer-SignallingServer-Launch" -Description "UE4PixelStreamer-SignallingServer-Launch" 59 | 60 | Write-Output "UE4-Pixel-Streamer-Bootstrap.ps1 Complete" 61 | -------------------------------------------------------------------------------- /UE4-Pixel-Streamer.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Unreal Engine 4 Pixel Streaming on AWS Solution", 4 | "Parameters": { 5 | "KeyPairName": { 6 | "Description": "Keypair associated with the EC2 instance", 7 | "Type": "AWS::EC2::KeyPair::KeyName", 8 | "MinLength": "1", 9 | "ConstraintDescription": "Must provide a keypair to be associated with the EC2 instance" 10 | }, 11 | "InstanceType": { 12 | "Description": "EC2 instance type", 13 | "Type": "String", 14 | "Default": "g4dn.4xlarge", 15 | "AllowedValues": [ 16 | "g3s.xlarge", 17 | "g3.4xlarge", 18 | "g3.8xlarge", 19 | "g3.16xlarge", 20 | "g4dn.xlarge", 21 | "g4dn.2xlarge", 22 | "g4dn.4xlarge", 23 | "g4dn.8xlarge", 24 | "g4dn.12xlarge", 25 | "g4dn.16xlarge" 26 | ] 27 | }, 28 | "DiskSize" : { 29 | "Description": "Disk size in GB", 30 | "Type": "Number", 31 | "Default": "50", 32 | "MinValue": "30" 33 | }, 34 | "UserPasswd": { 35 | "Description": "Password for the \"Administrator\" user on Windows instances. The default password is Ch4ng3M3! ", 36 | "Default": "Ch4ng3M3!", 37 | "MinLength": "8", 38 | "Type": "String", 39 | "AllowedPattern": "^((?=.*[a-z])(?=.*[A-Z])(?=.*[\\d])|(?=.*[a-z])(?=.*[A-Z])(?=.*[\\W_])|(?=.*[a-z])(?=.*[\\d])(?=.*[\\W_])|(?=.*[A-Z])(?=.*[\\d])(?=.*[\\W_])).+$", 40 | "ConstraintDescription": "Password must contain at least one element from three of the following sets: lowercase letters, uppercase letters, base 10 digits, non-alphanumeric characters", 41 | "NoEcho" : "true" 42 | }, 43 | "OsVersion": { 44 | "Type": "String", 45 | "AllowedValues": [ 46 | "WindowsServer2012R2", 47 | "WindowsServer2016", 48 | "WindowsServer2019" 49 | ], 50 | "Default": "WindowsServer2019" 51 | }, 52 | "PixelStreamingAccessCIDR": { 53 | "Description": "CIDR Block from which the Pixel Streaming Server will be accessible.", 54 | "Default": "0.0.0.0/0", 55 | "Type": "String", 56 | "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", 57 | "ConstraintDescription": "CIDR block parameter must be in the form x.x.x.x/16-32" 58 | }, 59 | "NiceDCVAccessCIDR": { 60 | "Description": "CIDR Block from which the NICE DCV Remote Desktop will be accessible.", 61 | "Default": "0.0.0.0/0", 62 | "Type": "String", 63 | "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", 64 | "ConstraintDescription": "CIDR block parameter must be in the form x.x.x.x/16-32" 65 | }, 66 | "PixelStreamerBuildLocation": { 67 | "Type": "String", 68 | "Description": "Location of zip file of UE4 Pixel Streaming exported project. Format of https://bucket-name.region.amazonaws.com/Path/UE4PixelStreamingProject.zip" 69 | }, 70 | "PixelStreamerBootstrapLocation": { 71 | "Type": "String", 72 | "Description": "Location of bootstrap Powershell script. Format of https://bucket-name.region.amazonaws.com/Path/UE4-Pixel-Streamer-Bootstrap.ps1" 73 | }, 74 | "LatestWindows2019AmiId":{ 75 | "Type": "AWS::SSM::Parameter::Value", 76 | "Default": "/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base" 77 | }, 78 | "LatestWindows2016AmiId":{ 79 | "Type": "AWS::SSM::Parameter::Value", 80 | "Default": "/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base" 81 | }, 82 | "LatestWindows2012AmiId":{ 83 | "Type": "AWS::SSM::Parameter::Value", 84 | "Default": "/aws/service/ami-windows-latest/Windows_Server-2012-R2_RTM-English-64Bit-Base" 85 | } 86 | }, 87 | "Mappings": { 88 | "VersionMap": { 89 | "firefox": { 90 | "default": "Firefox_Setup_57.0.exe" 91 | } 92 | } 93 | }, 94 | "Conditions": { 95 | "IsWindows2019": { "Fn::Equals": [{"Ref" : "OsVersion"}, "WindowsServer2019"] }, 96 | "IsWindows2016": { "Fn::Equals": [{"Ref" : "OsVersion"}, "WindowsServer2016"] }, 97 | "IsWindows2012": { "Fn::Equals": [{"Ref" : "OsVersion"}, "WindowsServer2012R2"] }, 98 | "CreateWindows" : { 99 | "Fn::Or" : [ 100 | { "Condition" : "IsWindows2019" }, 101 | { "Condition" : "IsWindows2016" }, 102 | { "Condition" : "IsWindows2012" } 103 | ] 104 | } 105 | }, 106 | "Resources": { 107 | "WindowsInstance": { 108 | "Type": "AWS::EC2::Instance", 109 | "Condition" : "CreateWindows", 110 | "Properties": { 111 | "InstanceType": { 112 | "Ref": "InstanceType" 113 | }, 114 | "IamInstanceProfile": { 115 | "Ref": "RootInstanceProfile" 116 | }, 117 | "ImageId": { 118 | "Fn::If": [ 119 | "IsWindows2019", 120 | {"Ref": "LatestWindows2019AmiId"}, 121 | { 122 | "Fn::If": [ 123 | "IsWindows2016", 124 | {"Ref": "LatestWindows2016AmiId"}, 125 | { 126 | "Fn::If": [ 127 | "IsWindows2016", 128 | {"Ref": "LatestWindows2012AmiId"}, 129 | "None" 130 | ] 131 | } 132 | ] 133 | } 134 | ] 135 | }, 136 | "SecurityGroupIds": [{ 137 | "Ref": "DCVSecurityGroup" 138 | }], 139 | "Tags" : [ 140 | { 141 | "Key" : "RemoteVisualization", 142 | "Value" : "DCV-preview" 143 | }, 144 | { 145 | "Key" : "Name", 146 | "Value" : { "Ref": "AWS::StackName" } 147 | }, 148 | { 149 | "Key" : "DCV", 150 | "Value" : "DCV" 151 | } 152 | ], 153 | "KeyName": { 154 | "Ref": "KeyPairName" 155 | }, 156 | "BlockDeviceMappings" : [ 157 | { 158 | "DeviceName" : "/dev/sda1", 159 | "Ebs" : { 160 | "VolumeSize" : { 161 | "Ref" : "DiskSize" 162 | }, 163 | "VolumeType" : "gp2" 164 | } 165 | } 166 | ], 167 | "UserData": { 168 | "Fn::Base64": { 169 | "Fn::Join": [ 170 | "", 171 | [ 172 | "\n" 180 | ] 181 | ] 182 | } 183 | } 184 | }, 185 | "Metadata": { 186 | "AWS::CloudFormation::Authentication": { 187 | "S3AccessCreds": { 188 | "type": "S3", 189 | "roleName": { 190 | "Ref": "RootRole" 191 | } 192 | } 193 | }, 194 | "AWS::CloudFormation::Init": { 195 | "configSets": { 196 | "initialize": [ 197 | "download", 198 | "install", 199 | "restart" 200 | ] 201 | }, 202 | "download": { 203 | "files": { 204 | "C:\\PixelStreamer\\Downloads\\UE4-Pixel-Streamer-Bootstrap.ps1": { 205 | "source": { 206 | "Fn::Join": [ 207 | "", 208 | [ 209 | { "Ref": "PixelStreamerBootstrapLocation" } 210 | ] 211 | ] 212 | }, 213 | "authentication": "S3AccessCreds" 214 | }, 215 | "C:\\PixelStreamer\\Downloads\\PixelStreamerProject.zip": { 216 | "source": { 217 | "Fn::Join": [ 218 | "", 219 | [ 220 | { "Ref": "PixelStreamerBuildLocation" } 221 | ] 222 | ] 223 | }, 224 | "authentication": "S3AccessCreds" 225 | }, 226 | "C:\\dcv-install\\install.ps1": { 227 | "source": { 228 | "Fn::Join": [ 229 | "", 230 | [ 231 | "https://s3-eu-west-1.amazonaws.com/nice-dcv-cfn/dcv-server-install.ps1" 232 | ] 233 | ] 234 | }, 235 | "authentication": "S3AccessCreds" 236 | }, 237 | "C:\\dcv-install\\conf.ps1": { 238 | "content": { 239 | "Fn::Join": [ 240 | "", 241 | [ 242 | "$dcvBucket = \"nice-dcv-cfn\"\r\n", 243 | "$depBucket = \"nice-dcv-cfn\"\r\n", 244 | "$devConPackage = \"DevCon.zip\"\r\n", 245 | "$dcvPackageName = \"nice-dcv-server-x64-Release-2020.0-latest.msi\"\r\n", 246 | "$firefoxPackage = \"", { "Fn::FindInMap": [ "VersionMap", "firefox", "default" ] }, "\"\r\n", 247 | "$userName = \"Administrator\"\r\n", 248 | "$userPasswd = \"", { "Ref": "UserPasswd" }, "\"\r\n", 249 | "$logLevel = \"info\"\r\n", 250 | "$waitHandle = \"", { "Ref": "InstanceWaitHandle" }, "\"\r\n", 251 | "$windowsVersion = \"", { "Ref": "OsVersion" }, "\"\r\n" 252 | ] 253 | ] 254 | } 255 | } 256 | }, 257 | "services": { 258 | "windows": { 259 | "cfn-hup": { 260 | "enabled": "true", 261 | "ensureRunning": "true", 262 | "files": [ 263 | "c:\\cfn\\cfn-hup.conf", 264 | "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" 265 | ] 266 | }, 267 | "audiosrv": { 268 | "enabled": "true", 269 | "ensureRunning": "true" 270 | } 271 | } 272 | }, 273 | "packages": { 274 | "msi": { 275 | "awscli": "https://s3.amazonaws.com/aws-cli/AWSCLI64.msi", 276 | "awstools": "http://sdk-for-net.amazonwebservices.com/latest/AWSToolsAndSDKForNet.msi" 277 | } 278 | } 279 | }, 280 | "install": { 281 | "commands": { 282 | "install-dcv": { 283 | "command": "powershell.exe -noprofile -executionpolicy bypass C:\\dcv-install\\install.ps1 > C:\\dcv-install\\install.log", 284 | "waitAfterCompletion": "0", 285 | "ignoreErrors": "true" 286 | }, 287 | "install-UE4-Pixel-Streaming": { 288 | "command": "powershell.exe -noprofile -executionpolicy bypass C:\\PixelStreamer\\Downloads\\UE4-Pixel-Streamer-Bootstrap.ps1 > C:\\PixelStreamer\\Downloads\\UE4-Pixel-Streamer-Bootstrap.log", 289 | "waitAfterCompletion": "0", 290 | "ignoreErrors": "true" 291 | } 292 | } 293 | }, 294 | "restart": { 295 | "commands": { 296 | "restart": { 297 | "command": "shutdown /r /t 10 /d p:4:1 /c \"CloudFormation Restart\"", 298 | "waitAfterCompletion": "forever" 299 | } 300 | } 301 | } 302 | }, 303 | "AWS::CloudFormation::Designer": { 304 | "id": "e5cac32e-b5c6-46ba-9430-1f9b7275b5b6" 305 | } 306 | } 307 | }, 308 | "RootRole": { 309 | "Type": "AWS::IAM::Role", 310 | "Properties": { 311 | "AssumeRolePolicyDocument": { 312 | "Version": "2012-10-17", 313 | "Statement": [ 314 | { 315 | "Effect": "Allow", 316 | "Principal": { 317 | "Service": [ 318 | "ec2.amazonaws.com" 319 | ] 320 | }, 321 | "Action": [ 322 | "sts:AssumeRole" 323 | ] 324 | } 325 | ] 326 | }, 327 | "Path": "/" 328 | }, 329 | "Metadata": { 330 | "AWS::CloudFormation::Designer": { 331 | "id": "6f9e3cf3-dc65-4bcc-a7aa-298486effe69" 332 | } 333 | } 334 | }, 335 | "RolePolicies": { 336 | "Type": "AWS::IAM::Policy", 337 | "Properties": { 338 | "PolicyName": "DcvInstallAccess", 339 | "PolicyDocument": { 340 | "Version": "2012-10-17", 341 | "Statement": [ 342 | { 343 | "Effect": "Allow", 344 | "Action": [ 345 | "logs:*", 346 | "s3:*" 347 | ], 348 | "Resource": "*" 349 | }, 350 | { 351 | "Effect": "Allow", 352 | "Action": [ 353 | "s3:GetObject" 354 | ], 355 | "Resource": "arn:aws:s3:::nice-dcv-cfn/*" 356 | } 357 | ] 358 | }, 359 | "Roles": [ 360 | { 361 | "Ref": "RootRole" 362 | } 363 | ] 364 | }, 365 | "Metadata": { 366 | "AWS::CloudFormation::Designer": { 367 | "id": "7160187f-0a7e-451f-bcb1-85783245c504" 368 | } 369 | } 370 | }, 371 | "RootInstanceProfile": { 372 | "Type": "AWS::IAM::InstanceProfile", 373 | "Properties": { 374 | "Path": "/", 375 | "Roles": [ 376 | { 377 | "Ref": "RootRole" 378 | } 379 | ] 380 | }, 381 | "Metadata": { 382 | "AWS::CloudFormation::Designer": { 383 | "id": "a36c5fb2-26ae-49c8-bffb-628118f2cd10" 384 | } 385 | } 386 | }, 387 | "WindowsInstanceWaitCondition": { 388 | "Type": "AWS::CloudFormation::WaitCondition", 389 | "Condition" : "CreateWindows", 390 | "DependsOn": "WindowsInstance", 391 | "Properties": { 392 | "Handle": { 393 | "Ref": "InstanceWaitHandle" 394 | }, 395 | "Timeout": "5400" 396 | } 397 | }, 398 | "InstanceWaitHandle": { 399 | "Type": "AWS::CloudFormation::WaitConditionHandle" 400 | }, 401 | "DCVSecurityGroup" : { 402 | "Type" : "AWS::EC2::SecurityGroup", 403 | "Properties" : { 404 | "GroupDescription" : "DCV Security Group", 405 | "SecurityGroupIngress" : [ 406 | {"IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": {"Ref": "NiceDCVAccessCIDR"}, "Description": "SSH Port"}, 407 | {"IpProtocol": "tcp", "FromPort": "3389", "ToPort": "3389", "CidrIp": {"Ref": "NiceDCVAccessCIDR"}, "Description": "Remote Desktop Port"}, 408 | {"IpProtocol": "tcp", "FromPort": "8443", "ToPort": "8443", "CidrIp": {"Ref": "NiceDCVAccessCIDR"}, "Description": "NICE DCV Port"}, 409 | {"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": {"Ref": "PixelStreamingAccessCIDR"}, "Description": "UE4 Pixel Streamer - Webserver Port"}, 410 | {"IpProtocol": "tcp", "FromPort": "443", "ToPort": "443", "CidrIp": {"Ref": "PixelStreamingAccessCIDR"}, "Description": "UE4 Pixel Streamer - Secure Webserver Port"}, 411 | {"IpProtocol": "tcp", "FromPort": "8888", "ToPort": "8888", "CidrIp": {"Ref": "PixelStreamingAccessCIDR"}, "Description": "UE4 Pixel Streamer - Application Streaming Port"}, 412 | {"IpProtocol": "udp", "FromPort": "8888", "ToPort": "8888", "CidrIp": {"Ref": "PixelStreamingAccessCIDR"}, "Description": "UE4 Pixel Streamer - Application Streaming Port"}, 413 | {"IpProtocol": "tcp", "FromPort": "19302", "ToPort": "19303", "CidrIp": {"Ref": "PixelStreamingAccessCIDR"}, "Description": "UE4 Pixel Streamer - STUN/TURN Ports"}, 414 | {"IpProtocol": "udp", "FromPort": "19302", "ToPort": "19303", "CidrIp": {"Ref": "PixelStreamingAccessCIDR"}, "Description": "UE4 Pixel Streamer - STUN/TURN Ports"} 415 | ] 416 | } 417 | } 418 | }, 419 | "Outputs": { 420 | "WindowsInstanceId": { 421 | "Value": { "Ref": "WindowsInstance" }, 422 | "Condition" : "CreateWindows", 423 | "Description": "Instance ID for the newly created EC2 instance" 424 | }, 425 | "WindowsPublicDNS": { 426 | "Value": { "Fn::GetAtt": [ "WindowsInstance", "PublicDnsName" ] }, 427 | "Condition" : "CreateWindows", 428 | "Description": "Web URL for Streaming Server, using DNS Name of the newly created EC2 instance" 429 | }, 430 | "WindowsPublicIp": { 431 | "Value": { "Fn::GetAtt": [ "WindowsInstance", "PublicIp" ] }, 432 | "Condition" : "CreateWindows", 433 | "Description": "Public IP address of the newly created EC2 instance" 434 | }, 435 | "WindowsDcvURL": { 436 | "Value": { "Fn::Join": [ "", [ "https://", { "Fn::GetAtt": [ "WindowsInstance", "PublicIp" ] }, ":8443" ] ] }, 437 | "Condition" : "CreateWindows", 438 | "Description": "Connection URL for web access to the newly created EC2 instance via NICE DCV" 439 | } 440 | }, 441 | "Metadata": { 442 | "AWS::CloudFormation::Interface" : { 443 | "ParameterGroups" : [ 444 | { 445 | "Label" : { "default": "EC2" }, 446 | "Parameters" : [ "InstanceType", "OsVersion", "DiskSize", "KeyPairName" ] 447 | }, 448 | { 449 | "Label" : { "default": "Credentials" }, 450 | "Parameters" : [ "UserPasswd" ] 451 | }, 452 | { 453 | "Label" : { "default": "Pixel Streamer Properties" }, 454 | "Parameters" : [ "PixelStreamerBootstrapLocation", "PixelStreamerBuildLocation", "PixelStreamingAccessCIDR", "NiceDCVAccessCIDR" ] 455 | }, 456 | { 457 | "Label" : { "default": "Windows AMIs" }, 458 | "Parameters" : [ "LatestWindows2019AmiId", "LatestWindows2016AmiId", "LatestWindows2012AmiId" ] 459 | } 460 | ], 461 | "ParameterLabels" : { 462 | "InstanceType": {"default": "Instance Type:"}, 463 | "DiskSize": {"default": "Disk Size:"}, 464 | "KeyPairName": {"default": "Key pair name:"}, 465 | "UserPasswd": {"default": "Password:"}, 466 | "OsVersion": {"default": "Operating System:"}, 467 | "PixelStreamingAccessCIDR": {"default": "Pixel Streaming Access CIDR:"}, 468 | "NiceDCVAccessCIDR": {"default": "NICE DCV Access CIDR:"}, 469 | "PixelStreamerBuildLocation": {"default": "Pixel Streamer Build Location:"}, 470 | "PixelStreamerBootstrapLocation": {"default": "Pixel Streamer Bootstrap Location:"}, 471 | "LatestWindows2019AmiId": {"default": "Windows 2019 AMI:"}, 472 | "LatestWindows2016AmiId": {"default": "Windows 2016 AMI:"}, 473 | "LatestWindows2012AmiId": {"default": "Windows 2012 AMI:"} 474 | } 475 | } 476 | } 477 | } 478 | --------------------------------------------------------------------------------