AWSTemplateFormatVersion: "2010-09-09" Description: Provides configuration for a Deadline workstation instance. Parameters: SubnetID: Type: AWS::EC2::Subnet::Id CreateVPNEndpoint: Type: String WorkstationSecurityGroup: Type: AWS::EC2::SecurityGroup::Id InstanceType: Type: String InstanceAMI: Type: AWS::EC2::Image::Id WorkstationEBSVolumeSize: Type: Number Environment: Type: String WorkstationInstanceProfile: Type: String AppVersion: Type: String LicenseServerInstancePrivateIp: Type: String EC2UserPassword: Type: String NoEcho: true ArtefactBucketName: Type: String EfsFileSystem: Type: String WorkstationConnectionManager: Type: String Conditions: CreateClientVPN: !Equals [!Ref CreateVPNEndpoint, true] IsTeradici: !Equals [!Ref WorkstationConnectionManager, teradici] Resources: WorkstationInstance: CreationPolicy: ResourceSignal: Count: 1 Timeout: PT30M Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: configSets: dcc_install: - instance_prep - artefacts_download - blender_download - app_install - post_install instance_prep: packages: !If - IsTeradici - yum: redhat-lsb: [] cifs-utils: [] - yum: system-lsb: [] cifs-utils: [] files: /sbin/ebsnvme-id: !If - IsTeradici - source: https://raw.githubusercontent.com/aws-samples/aws-digital-content-creation-render-environment/master/scripts/ebsnvme-id mode: "000755" owner: root group: root - !Ref AWS::NoValue /etc/udev/rules.d/70-ec2-nvme-devices.rules: !If - IsTeradici - source: https://raw.githubusercontent.com/aws-samples/aws-digital-content-creation-render-environment/master/scripts/70-ec2-nvme-devices.rules mode: "000755" owner: root group: root - !Ref AWS::NoValue /opt/scripts/ec2-mount-ebs-volume.sh: content: | #!/usr/bin/env bash mkdir -p /data while [ ! -b $(readlink -f /dev/xvdh) ]; do echo "waiting for device /dev/xvdh"; sleep 5 ; done blkid $(readlink -f /dev/xvdh) || mkfs -t ext4 $(readlink -f /dev/xvdh) e2label $(readlink -f /dev/xvdh) dcc-data grep -q ^LABEL=dcc-data /etc/fstab || echo 'LABEL=dcc-data /data ext4 defaults' >> /etc/fstab grep -q "^$(readlink -f /dev/xvdh) /data " /proc/mounts || mount /data mode: "000755" owner: root group: root /opt/scripts/dns.sh: content: !Sub | #!/usr/bin/env bash results=1 while [[ $results != 0 ]]; do nslookup ${EfsFileSystem}.efs.${AWS::Region}.amazonaws.com results=$? if [[ $results = 1 ]]; then sleep 30s fi done mode: "000755" owner: root group: root /etc/dcv/dcv.conf: !If - IsTeradici - !Ref AWS::NoValue - content: | [session-management] create-session = true [session-management/automatic-console-session] owner="ec2-user" [display] cuda-devices=['0'] [display/linux] gl-displays=[':0.0'] /etc/cfn/cfn-hup.conf: content: !Sub | [main] stack=${AWS::StackId} region=${AWS::Region} interval=1 mode: "000400" owner: root group: root /etc/cfn/hooks.d/cfn-auto-reloader.conf: content: !Sub | [cfn-auto-reloader-hook] triggers=post.update path=Resources.WorkstationInstance.Metadata.AWS::CloudFormation::Init action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WorkstationInstance --configsets dcc_install --region ${AWS::Region} runas=root mode: "000400" owner: root group: root commands: 00-reload-udev-rules: command: udevadm control --reload-rules && udevadm trigger 01-mount-ebs-volume: command: sh /opt/scripts/ec2-mount-ebs-volume.sh > /opt/scripts/ec2-mount-ebs-volume.log 2>&1 test: test -x /opt/scripts/ec2-mount-ebs-volume.sh # check if filename exists and is executable ignoreErrors: false 02-wait_for_dns_propogation: command: sh /opt/scripts/dns.sh test: test -x /opt/scripts/dns.sh 03-mount_efs: command: !Sub | #!/bin/bash -xe EFS_DIRECTORY=/mnt/efs mkdir $EFS_DIRECTORY echo "${EfsFileSystem}:/ $EFS_DIRECTORY efs _netdev" >> /etc/fstab mount -a -t efs defaults ignoreErrors: false 04-add-ec2-user: !If - IsTeradici - command: !Sub | userdel centos useradd ec2-user echo ${EC2UserPassword} | tee - | passwd ec2-user usermod -a -G adm,wheel,systemd-journal ec2-user systemctl restart pcoip - command: !Sub | echo ${EC2UserPassword} | tee - | passwd ec2-user services: sysvinit: dcvserver: !If - IsTeradici - !Ref AWS::NoValue - enabled: true ensureRunning: true files: - /etc/dcv/dcv.conf cfn-hup: enabled: true ensureRunning: true files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf amazon-ssm-agent: enabled: true ensureRunning: true artefacts_download: sources: /data/thinkbox: !Sub https://${ArtefactBucketName}.s3.amazonaws.com/Deadline-${AppVersion}-linux-installers.tar blender_download: sources: /usr/local: !Sub https://${ArtefactBucketName}.s3.amazonaws.com/Blender.zip app_install: commands: 05-install-client: command: !Sub | ls /data/thinkbox | grep DeadlineClient | \ (read data; /data/thinkbox/$data \ --mode unattended \ --prefix "/data/thinkbox/Deadline10" \ --connectiontype Repository \ --repositorydir "/mnt/efs/DeadlineRepository10" \ --licensemode Standard \ --licenseserver @${LicenseServerInstancePrivateIp} \ --launcherstartup true \ --slavestartup false) ignoreErrors: true post_install: packages: !If - IsTeradici - yum: gimp: [] - amazon-linux-extras: gimp: [] sources: /mnt/efs/assets: !Sub https://${ArtefactBucketName}.s3.amazonaws.com/BMW27_2.blend.zip commands: 06-set-assets-folder-permissions: command: chown -R ec2-user:root /mnt/efs/assets 07-install-google-chrome: command: | cd ~/ wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm yum localinstall -y google-chrome-stable_current_x86_64.rpm ignoreErrors: true 08-set-permission-on-efs: command: chown -R ec2-user:root /mnt/efs Properties: BlockDeviceMappings: - DeviceName: /dev/xvdh Ebs: VolumeSize: !Ref WorkstationEBSVolumeSize VolumeType: gp2 Encrypted: true DeleteOnTermination: true IamInstanceProfile: !Ref WorkstationInstanceProfile ImageId: !Ref InstanceAMI InstanceType: !Ref InstanceType SecurityGroupIds: - !Ref WorkstationSecurityGroup SubnetId: !Ref SubnetID Tags: - Key: Name Value: deadline-workstation - Key: Environment Value: !Ref Environment UserData: !If - IsTeradici - !Base64 Fn::Sub: | #!/bin/bash -xe # add extras for yum repo yum -y --enablerepo=extras install epel-release # grab the latest cfn bootstrap and install it sudo yum install -y https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.amzn1.noarch.rpm sudo ln -s /usr/local/lib/python2.7/site-packages/cfnbootstrap /usr/lib/python2.7/site-packages/cfnbootstrap # install efs-utils git clone https://github.com/aws/efs-utils make rpm --directory ./efs-utils/ yum -y install ./efs-utils/build/amazon-efs-utils*.rpm # install amazon-ssm-agent yum install -y https://s3.${AWS::Region}.amazonaws.com/amazon-ssm-${AWS::Region}/latest/linux_amd64/amazon-ssm-agent.rpm # Call cfn-init script to install files and packages /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WorkstationInstance --configsets dcc_install --region ${AWS::Region} # Call cfn-signal script to send a signal with exit code /opt/aws/bin/cfn-signal --exit-code $? --stack ${AWS::StackName} --resource WorkstationInstance --region ${AWS::Region} - !Base64 Fn::Sub: | #!/bin/bash -xe # Update aws-cfn-bootstrap to the latest yum install -y aws-cfn-bootstrap # Install efs-utils yum install -y amazon-efs-utils # Call cfn-init script to install files and packages /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WorkstationInstance --configsets dcc_install --region ${AWS::Region} # Call cfn-signal script to send a signal with exit code /opt/aws/bin/cfn-signal --exit-code $? --stack ${AWS::StackName} --resource WorkstationInstance --region ${AWS::Region} Outputs: WorkstationInstancePrivateIp: Value: !GetAtt WorkstationInstance.PrivateIp DeadlineVersion: Value: !Ref AppVersion WorkstationIP: Value: !If [CreateClientVPN, !GetAtt WorkstationInstance.PrivateIp, !GetAtt WorkstationInstance.PublicIp]