AWSTemplateFormatVersion: 2010-09-09 Description: This template instantiates an EC2 instance with Teradici installed and a prompt to install Adobe Premier Pro via Adobe Creative Cloud (qs-1s0p493im) Metadata: AWSAMIRegionMap: Filters: TERADICIWIN: name: graphics-agent-windows-2019-aws-market* owner-alias: aws-marketplace product-code.type: marketplace product-code: 4af6zv023dsu3c28day09b2a9 Parameters: FirstStation: Type: String WorkstationNumber: Type: String RootURL: Type: String pcoipRegistrationCode: Type: String domainName: Type: String adServiceAccountUsername: Type: String adServiceAccountPassword: Type: String NoEcho: "True" gfxworkstationSubnet: Type: String gfxworkstationSG: Type: String gfxworkstationKeyName: Type: String windowsGrxInstanceType: Type: String workstationAdminPassword: Type: String NoEcho: "True" pcoipAgentLocationUrl: Type: String pcoipAgentFilename: Type: String SMBShareName: Type: String FloatDNSName: Type: String DomainControllerSecretsName: Type: String BucketName: Type: String Conditions: FirstWS: !Equals - !Ref FirstStation - "TRUE" ProvVPC: !Equals - !Select [1, !Split ["-", !Ref "AWS::StackName"]] - "StudioQStack" Mappings: AWSAMIRegionMap: us-east-1: TERADICIWIN: ami-03e5c2b6b8649b63f us-east-2: TERADICIWIN: ami-0aa95af6f33ef4028 us-west-1: TERADICIWIN: ami-083b55f84f495751b us-west-2: TERADICIWIN: ami-0bd4d5ba065ed3cd5 us-gov-west-1: TERADICIWIN: ami-09200b4bf77b723cd us-gov-east-1: TERADICIWIN: ami-0b77d9d273cd3f149 ca-central-1: TERADICIWIN: ami-04f7bf99fe5281be2 eu-central-1: TERADICIWIN: ami-02562d034cdc0feaf eu-west-1: TERADICIWIN: ami-0eae3fbb9e3560a65 eu-west-2: TERADICIWIN: ami-0b8e91503fc3c224a eu-west-3: TERADICIWIN: ami-0446e9d63c6c1a7b0 eu-north-1: TERADICIWIN: ami-07a118936af551076 eu-south-1: TERADICIWIN: ami-0eba84a66612523da ap-southeast-1: TERADICIWIN: ami-04693ac630ab11aea ap-southeast-2: TERADICIWIN: ami-056704a526e11b3aa ap-south-1: TERADICIWIN: ami-03775637c9cc8a248 ap-northeast-1: TERADICIWIN: ami-01f2388db2b94352f ap-northeast-2: TERADICIWIN: ami-0b92f3e1f66a54c46 ap-east-1: TERADICIWIN: ami-0222efe52c0cdd1f4 sa-east-1: TERADICIWIN: ami-0b1f25b0e02a13b30 me-south-1: TERADICIWIN: ami-09dcb073fa7ce6ce3 af-south-1: TERADICIWIN: ami-001e706b63010bd51 Resources: WorkstationEIP: Type: "AWS::EC2::EIP" Properties: Domain: vpc Tags: - Key: Name Value: !If - ProvVPC - !Join - "-" - - !Select [0, !Split ["-", !Ref "AWS::StackName"]] - !Select [1, !Split ["-", !Ref "AWS::StackName"]] - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Select [3, !Split ["-", !Ref "AWS::StackName"]] - !Select [4, !Split ["-", !Ref "AWS::StackName"]] - !Sub " Windows Adobe Workstation #${WorkstationNumber}" - !Join - "-" - - !Select [0, !Split ["-", !Ref "AWS::StackName"]] - !Select [1, !Split ["-", !Ref "AWS::StackName"]] - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Sub " Windows Adobe Workstation #${WorkstationNumber}" AssociateEIP: Type: "AWS::EC2::EIPAssociation" Properties: AllocationId: !GetAtt WorkstationEIP.AllocationId NetworkInterfaceId: !Ref WorkstationNI WorkstationNI: Type: "AWS::EC2::NetworkInterface" Properties: SubnetId: !Ref gfxworkstationSubnet GroupSet: - !Ref gfxworkstationSG WorkstationAccessRole: Type: "AWS::IAM::Role" Metadata: cfn-lint: config: ignore_checks: - EIAMPolicyWildcardResource #KMS policy requires wildcard Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - "sts:AssumeRole" Path: / Policies: - PolicyName: WorkstationS3Access PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "s3:Get*" - "s3:List*" Resource: - !Sub "arn:aws:s3:::${BucketName}" - !Sub "arn:aws:s3:::${BucketName}/*" - "arn:aws:s3:::ec2-windows-nvidia-drivers" - "arn:aws:s3:::ec2-windows-nvidia-drivers/*" - PolicyName: WorkstationSecretsAccess PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue - secretsmanager:DescribeSecret Resource: "*" WorkstationAccessProfile: Type: "AWS::IAM::InstanceProfile" Properties: Path: / Roles: - !Ref WorkstationAccessRole windowsGfxWorkstation: Type: 'AWS::EC2::Instance' Metadata: "AWS::CloudFormation::Authentication": rolebased: buckets: - qumuloadobe roleName: !Ref WorkstationAccessRole type: S3 "AWS::CloudFormation::Init": configSets: config: - "1-setup" - "2-run" "1-setup": files: "C:\\cfn\\cfn-hup.conf": authentication: rolebased context: Region: !Ref "AWS::Region" StackId: !Ref "AWS::StackId" source: !Join ["", [!Ref RootURL, "cfn-init/cfn-hup.conf"]] "C:\\cfn\\hooks.d\\cfn-auto-reloader.conf": authentication: rolebased context: Region: !Ref "AWS::Region" ResourceName: windowsGfxWorkstation StackId: !Ref "AWS::StackId" source: !Join ["", [!Ref RootURL, "cfn-init/cfn-auto-reloader.conf"]] "C:\\cfn\\install\\studioq-desktop.jpg": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/studioq-desktop.jpg"]] "C:\\cfn\\install\\qumulo.ico": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/qumulo.ico"]] "C:\\cfn\\install\\disk.ico": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/disk.ico"]] "C:\\cfn\\install\\CleanupFiles.cmd": content: !Sub | del /f /q c:\cfn\\install\workstation.conf "C:\\cfn\\install\\workstation.conf": authentication: rolebased context: pcoipAgentLocationUrl: !Ref pcoipAgentLocationUrl pcoipRegistrationCode: !Ref pcoipRegistrationCode workstationAdminPassword: !Ref workstationAdminPassword adServiceAccountPassword: !Ref adServiceAccountPassword domainName: !Ref domainName adServiceAccountUsername: !Ref adServiceAccountUsername FloatDNSName: !Ref FloatDNSName SMBShareName: !Ref SMBShareName source: !Join ["", [!Ref RootURL, "cfn-init/workstation.conf"]] "C:\\cfn\\install\\workstationrename.ps1": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/workstationrename.ps1"]] "C:\\cfn\\install\\workstationsetup.ps1": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/workstationsetup.ps1"]] "C:\\cfn\\install\\install-gpu-drivers.ps1": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/install-gpu-drivers.ps1"]] "C:\\cfn\\install\\set-wallpaper.ps1": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/set-wallpaper.ps1"]] "C:\\mapdrive.ps1": content: !Sub | New-PSDrive -Name Q -PSProvider FileSystem -Root "\\${FloatDNSName}\${SMBShareName}" -Scope Global -Persist "C:\\cfn\\install\\launch-adobe.ps1": content: !Sub | Start-Process -FilePath "C:\Program Files\Google\Chrome\Application\chrome.exe" -ArgumentList "https://creativecloud.adobe.com" "C:\\cfn\\install\\disable-defender.ps1": authentication: rolebased source: !Join ["", [!Ref RootURL, "cfn-init/disable-defender.ps1"]] services: windows: cfn-hup: enabled: "true" ensureRunning: "true" files: - "c:\\cfn\\cfn-hup.conf" - "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" "2-run": commands: "01-rename-workstation": command: "powershell.exe -ExecutionPolicy Unrestricted -File C:\\cfn\\install\\workstationrename.ps1" waitAfterCompletion: "forever" "02-setup-workstation": command: "powershell.exe -ExecutionPolicy Unrestricted -File C:\\cfn\\install\\workstationsetup.ps1 -WorkstationConf c:\\cfn\\install\\workstation.conf" waitAfterCompletion: "forever" "03-configure-task-set-wallpaper": command: !Join - "" - - "schtasks /create /tn \"Set Wallpaper\" /ru \"" - !Ref domainName - "\\Domain Users\" /sc ONLOGON /tr \"powershell.exe -WindowStyle Hidden -File C:\\cfn\\install\\set-wallpaper.ps1\"" waitAfterCompletion: 0 "04-configure-task-map-drive": command: !Join - "" - - "schtasks /create /tn \"Map Q Drive\" /ru \"" - !Ref domainName - "\\Domain Users\" /sc ONLOGON /tr \"powershell.exe -WindowStyle Hidden -File c:\\mapdrive.ps1\"" waitAfterCompletion: 0 "05-configure-task-launch-adobe": command: !Join - "" - - "schtasks /create /tn \"Launch Adobe Webpage\" /ru \"" - !Ref domainName - "\\Domain Users\" /sc ONLOGON /tr \"powershell.exe -WindowStyle Hidden -File c:\\cfn\\install\\launch-adobe.ps1\"" waitAfterCompletion: 0 "06-configure-task-disable-defender": command: !Join - "" - - "schtasks /create /tn \"Disable Defender\" /ru \"" - !Ref domainName - "\\Domain Users\" /sc ONLOGON /tr \"powershell.exe -WindowStyle Hidden -File C:\\cfn\\install\\disable-defender.ps1 -DomainControllerSecrets " - !Ref DomainControllerSecretsName - " -DomainName " - !Ref domainName - "\" /rl HIGHEST" waitAfterCompletion: 0 "07-cleanup-files": command: "C:\\cfn\\install\\CleanupFiles.cmd" waitAfterCompletion: 0 Properties: ImageId: !FindInMap [AWSAMIRegionMap, !Ref "AWS::Region", TERADICIWIN] InstanceType: !Ref windowsGrxInstanceType Monitoring: false IamInstanceProfile: !Ref WorkstationAccessProfile NetworkInterfaces: - NetworkInterfaceId: !Ref WorkstationNI DeviceIndex: 0 KeyName: !Ref gfxworkstationKeyName BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeType: gp2 VolumeSize: '100' DeleteOnTermination: 'true' Encrypted: 'false' Tags: - Key: Name Value: !If - ProvVPC - !Join - "-" - - !Select [0, !Split ["-", !Ref "AWS::StackName"]] - !Select [1, !Split ["-", !Ref "AWS::StackName"]] - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Select [3, !Split ["-", !Ref "AWS::StackName"]] - !Select [4, !Split ["-", !Ref "AWS::StackName"]] - !Sub " Windows Adobe Workstation #${WorkstationNumber}" - !Join - "-" - - !Select [0, !Split ["-", !Ref "AWS::StackName"]] - !Select [1, !Split ["-", !Ref "AWS::StackName"]] - !Select [2, !Split ["-", !Ref "AWS::StackName"]] - !Sub " Windows Adobe Workstation #${WorkstationNumber}" UserData: Fn::Base64: !Sub | cfn-init.exe -v -c config --stack ${AWS::StackName} --resource windowsGfxWorkstation --region ${AWS::Region} cfn-signal.exe -e $lastexitcode --stack ${AWS::StackName} --resource windowsGfxWorkstation --region ${AWS::Region} domainNameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-domainName" Value: !Ref domainName Type: String gfxworkstationKeyNameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-gfxworkstationKeyName" Value: !Ref gfxworkstationKeyName Type: String gfxworkstationSGSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-gfxworkstationSG" Value: !Ref gfxworkstationSG Type: String gfxworkstationSubnetSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-gfxworkstationSubnet" Value: !Ref gfxworkstationSubnet Type: String pcoipAgentFilenameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-pcoipAgentFilename" Value: !Ref pcoipAgentFilename Type: String pcoipAgentLocationUrlSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-pcoipAgentLocationUrl" Value: !Ref pcoipAgentLocationUrl Type: String pcoipRegistrationCodeSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-pcoipRegistrationCode" Value: !Ref pcoipRegistrationCode Type: String windowsGfxInstanceAMISSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-windowsGfxInstanceAMI" Value: !FindInMap [AWSAMIRegionMap, !Ref "AWS::Region", TERADICIWIN] Type: String windowsGrxInstanceTypeSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-windowsGrxInstanceType" Value: !Ref windowsGrxInstanceType Type: String SMBShareNameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-SMBShareName" Value: !Ref SMBShareName Type: String FloatDNSNameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-FloatDNSName" Value: !Ref FloatDNSName Type: String DomainControllerSecretsNameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-DomainControllerSecretsName" Value: !Ref DomainControllerSecretsName Type: String RootURLSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-RootURL" Value: !Ref RootURL Type: String BuccketNameSSM: Type: AWS::SSM::Parameter Condition: FirstWS Properties: Name: !Sub "${AWS::StackName}-BucketName" Value: !Ref BucketName Type: String Outputs: GFXWorkstationHostname: Description: "The public dns hostname of the Workstation Instance" Value: !GetAtt windowsGfxWorkstation.PublicDnsName GFXWorkstationPublicIP: Description: "The Public IP Address of the Workstation Instance" Value: !GetAtt windowsGfxWorkstation.PublicIp GFXWorkstationNumber: Description: "Workstation Instance Number" Value: !Ref WorkstationNumber GFXWorkstationStackName: Description: The Name of this AWS Stack Value: !Ref "AWS::StackName" Condition: FirstWS