

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Connect las flotas gestionadas por el servicio a un servidor de licencias personalizado
<a name="smf-byol"></a>

Puedes usar tu propio servidor de licencias con una flota gestionada por el servicio de Deadline Cloud. Para traer su propia licencia, puede configurar un servidor de licencias mediante un entorno de colas en su granja. Para configurar el servidor de licencias, ya debe tener una granja y una cola configuradas.

La forma de conectarse a un servidor de licencias de software depende de la configuración de su flota y de los requisitos del proveedor del software. Por lo general, se accede al servidor de dos maneras:
+ Directamente al servidor de licencias. Sus trabajadores obtienen una licencia del servidor de licencias del proveedor de software a través de Internet. Todos sus trabajadores deben poder conectarse al servidor.
+ A través de un proxy de licencia. Sus trabajadores se conectan a un servidor proxy de su red local. Solo el servidor proxy puede conectarse al servidor de licencias del proveedor a través de Internet.

Siguiendo las instrucciones que aparecen a continuación, utilizará Amazon EC2 Systems Manager (SSM) para reenviar los puertos de una instancia de trabajo a su servidor de licencias o instancia proxy. En el siguiente ejemplo, si su servidor de licencias no puede proporcionar una licencia, se utilizarán las licencias basadas en el uso de Deadline Cloud. Elimine las secciones que no se apliquen a su cartera o a los productos para los que no desee utilizar licencias basadas en el uso una vez agotadas las licencias.

**Topics**
+ [Paso 1: Configurar el entorno de colas](#configure-queue-environment)
+ [Paso 2: Configuración (opcional) de la instancia de proxy de licencia](#license-proxy)
+ [Paso 3: configuración de la plantilla CloudFormation](#byol-cfn-template)

## Paso 1: Configurar el entorno de colas
<a name="configure-queue-environment"></a>



Puede configurar un entorno de colas en su cola para acceder a su servidor de licencias. En primer lugar, asegúrese de tener una AWS instancia configurada con acceso al servidor de licencias mediante uno de los siguientes métodos:
+ Servidor de licencias: la instancia aloja los servidores de licencias directamente.
+ Proxy de licencias: la instancia tiene acceso de red al servidor de licencias y reenvía los puertos del servidor de licencias al servidor de licencias. Para obtener más información sobre cómo configurar una instancia de proxy de licencias, consulte[Paso 2: Configuración (opcional) de la instancia de proxy de licencia](#license-proxy).

Para obtener información sobre la configuración de las variables de entorno de licencia, consulte[Paso 3: Conectar una aplicación de renderizado a un punto final](cmf-ubl.md). Para una configuración de servidor de licencias personalizada, la dirección del servidor de licencias sigue siendo localhost en lugar del punto final de Amazon VPC.

**Para añadir los permisos necesarios a la función de cola**

1. En la [consola de Deadline Cloud](https://console.aws.amazon.com/deadlinecloud/home), selecciona **Ir al panel de control**.

1. En el panel de control, selecciona la granja y, a continuación, la cola que deseas configurar.

1. En los detalles de la cola > función de servicio, seleccione la función.

1. Selecciona **Añadir permiso** y, a continuación, selecciona **Crear política integrada.**

1. Selecciona el editor de políticas JSON y, a continuación, copia y pega el siguiente texto en el editor.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Action": [
                   "ssm:StartSession"
               ],
               "Resource": [
                   "arn:aws:ssm:us-east-1::document/AWS-StartPortForwardingSession",
                   "arn:aws:ec2:us-east-1:111122223333:instance/instance_id"
               ]
           }
       ]
   }
   ```

------

1. Antes de guardar la nueva política, sustituya los siguientes valores en el texto de la política:
   + `region`Sustitúyalos por la AWS región en la que se encuentra su granja
   + `instance_id`Sustitúyalo por el ID de instancia del servidor de licencias o la instancia proxy que estés utilizando
   + `account_id`Sustitúyalo por el número de AWS cuenta que contiene tu granja

1. Elija **Siguiente**.

1. Para el nombre de la póliza, introduzca**LicenseForwarding**.

1. Seleccione **Crear política** para guardar los cambios y crear la política con los permisos necesarios.

**Para añadir un nuevo entorno de colas a la cola**

1. En la [consola de Deadline Cloud](https://console.aws.amazon.com/deadlinecloud/home), selecciona **Ir al panel de control** si aún no lo has hecho.

1. En el panel de control, selecciona la granja y, a continuación, la cola que deseas configurar.

1. Selecciona **Entornos de cola** > **Acciones** > **Crear nuevos con** YAML.

1. Copia y pega el siguiente texto en el editor de scripts de YAML.

------
#### [ Windows ]

   ```
   specificationVersion: "environment-2023-09"
   parameterDefinitions:
    - name: LicenseInstanceId
      type: STRING
      description: >
       The Instance ID of the license server/proxy instance
      default: ""
    - name: LicenseInstanceRegion
      type: STRING
      description: >
       The region containing this farm
      default: ""
    - name: LicensePorts
      type: STRING
      description: >
       Comma-separated list of ports to be forwarded to the license server/proxy
       instance. Example: "2701,2702,7075,2703,6101,1715,1716,1717,7054,7055,30304"
      default: "2701,2702,7075,2703,6101,1715,1716,1717,7054,7055,30304"
   environment:
    name: BYOL License Forwarding
    variables:
     example_LICENSE: 2701@localhost
    script:
     actions:
      onEnter:
       command: bash
       args: [ "{{Env.File.Enter}}" ]
      onExit:
       command: bash
       args: [ "{{Env.File.Exit}}" ]
     embeddedFiles:
      - name: Enter
        type: TEXT
        runnable: True
        data: |
         curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows/SessionManagerPlugin.zip" -o "{{Session.WorkingDirectory}}/ssm-plugin.zip"
         powershell -Command "Expand-Archive -Path '{{Session.WorkingDirectory}}/ssm-plugin.zip' -DestinationPath '{{Session.WorkingDirectory}}/ssm-plugin' -Force; Expand-Archive -Path '{{Session.WorkingDirectory}}/ssm-plugin/package.zip' -DestinationPath '{{Session.WorkingDirectory}}/ssm-plugin/package' -Force"
         conda activate
         python "{{Env.File.StartSession}}" "{{Session.WorkingDirectory}}/ssm-plugin/package/bin/session-manager-plugin.exe"
      - name: Exit
        type: TEXT
        runnable: True
        data: |
         echo Killing SSM Manager Plugin PIDs: $BYOL_SSM_PIDS
         for pid in ${BYOL_SSM_PIDS//,/ }; do kill $pid; done
      - name: StartSession
        type: TEXT
        data: |
         import boto3
         import json
         import subprocess
         import sys
         import os
         import tempfile
   
         instance_id = "{{Param.LicenseInstanceId}}"
         region = "{{Param.LicenseInstanceRegion}}"
         license_ports_list = "{{Param.LicensePorts}}".split(",")
   
         ssm_client = boto3.client("ssm", region_name=region)
         pids = []
   
         for port in license_ports_list:
           session_response = ssm_client.start_session(
             Target=instance_id,
             DocumentName="AWS-StartPortForwardingSession",
             Parameters={"portNumber": [port], "localPortNumber": [port]}
           )
   
           cmd = [
             sys.argv[1],
             json.dumps(session_response),
             region,
             "StartSession",
             "",
             json.dumps({"Target": instance_id}),
             f"https://ssm.{region}.amazonaws.com"
           ]
   
           process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
           pids.append(process.pid)
           print(f"SSM Port Forwarding Session started for port {port}")
   
         print(f"openjd_env: BYOL_SSM_PIDS={','.join(str(pid) for pid in pids)}")
   
         # Enabling UBL after the BYOL has run out requires prepending the BYOL configuration to the existing license setup
         # Remove the sections that do not apply to your pipeline, or you do not want to use UBL after exhausting the BYOL licenses.
         # The port numbers used may not match what your license server is serving.
   
         # Arnold
         os.environ["ADSKFLEX_LICENSE_FILE"] = f"2701@localhost;{os.environ.get('ADSKFLEX_LICENSE_FILE', '')}"
         print(f"openjd_env: ADSKFLEX_LICENSE_FILE={os.environ['ADSKFLEX_LICENSE_FILE']}")
   
         # Cinema4D
         os.environ["g_licenseServerRLM"] = f"localhost:7057;{os.environ.get('g_licenseServerRLM', '')}"
         print(f"openjd_env: g_licenseServerRLM={os.environ['g_licenseServerRLM']}")
   
         # Nuke
         os.environ["foundry_LICENSE"] = f"6101@localhost;{os.environ.get('foundry_LICENSE', '')}"
         print(f"openjd_env: foundry_LICENSE={os.environ['foundry_LICENSE']}")
   
         # SideFX
         os.environ["SESI_LMHOST"] = f"localhost:1715;{os.environ.get('SESI_LMHOST', '')}"
         print(f"openjd_env: SESI_LMHOST={os.environ['SESI_LMHOST']}")
   
         # Redshift and Red Giant
         os.environ["redshift_LICENSE"] = f"7054@localhost;7055@localhost;{os.environ.get('redshift_LICENSE', '')}"
         print(f"openjd_env: redshift_LICENSE={os.environ['redshift_LICENSE']}")
   
         # V-Ray doesn't support multiple license servers in a single environment variable
         # See https://documentation.chaos.com/space/LIC5/125050770/Sharing+a+License+Configuration+in+a+Network
         vray_license = os.environ.get('VRAY_AUTH_CLIENT_SETTINGS', '')
         xml_content = """<VRLClient>
           <LicServer>
             <Host>localhost</Host>
             <Port>30304</Port>"""
   
         if vray_license and vray_license.startswith('licset://'):
             server_parts = vray_license.removeprefix('licset://').split(':')
             if len(server_parts) >= 2:
                 xml_content += f"""
             <Host1>{server_parts[0]}</Host1>
             <Port1>{server_parts[1]}</Port1>"""
   
         xml_content += """
             <User></User>
             <Pass></Pass>
           </LicServer>
         </VRLClient>"""
   
         temp_dir = tempfile.gettempdir()
         xml_path = os.path.join(temp_dir, 'vrlclient.xml')
         
         with open(xml_path, 'w') as f:
             f.write(xml_content)
   
         os.environ["VRAY_AUTH_CLIENT_FILE_PATH"] = temp_dir
         print(f"openjd_env: VRAY_AUTH_CLIENT_FILE_PATH={os.environ['VRAY_AUTH_CLIENT_FILE_PATH']}")
   
         # Clear the existing VRAY_AUTH_CLIENT_SETTINGS so only the vrlclient.xml file is used.
         os.environ["VRAY_AUTH_CLIENT_SETTINGS"] = ''
         print(f"openjd_env: VRAY_AUTH_CLIENT_SETTINGS={os.environ['VRAY_AUTH_CLIENT_SETTINGS']}")
   
         # Print out the created xml file's contents
         print(f"V-Ray configuration file: {xml_path}")
         with open(xml_path, 'r') as f:
             print(f"{f.read()}")
   ```

------
#### [ Linux ]

   ```
   specificationVersion: "environment-2023-09"
   parameterDefinitions:
    - name: LicenseInstanceId
      type: STRING
      description: >
       The Instance ID of the license server/proxy instance
      default: ""
    - name: LicenseInstanceRegion
      type: STRING
      description: >
       The region containing this farm
      default: ""
    - name: LicensePorts
      type: STRING
      description: >
       Comma-separated list of ports to be forwarded to the license server/proxy
       instance. Example: "2701,2702,7075,2703,6101,1715,1716,1717,7054,7055,30304"
      default: "2701,2702,7075,2703,6101,1715,1716,1717,7054,7055,30304"
   environment:
    name: BYOL License Forwarding
    variables:
     example_LICENSE: 2701@localhost
    script:
     actions:
      onEnter:
       command: bash
       args: [ "{{Env.File.Enter}}" ]
      onExit:
       command: bash
       args: [ "{{Env.File.Exit}}" ]
     embeddedFiles:
      - name: Enter
        type: TEXT
        runnable: True
        data: |
         curl https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm -Ls | rpm2cpio - | cpio -iv --to-stdout ./usr/local/sessionmanagerplugin/bin/session-manager-plugin > {{Session.WorkingDirectory}}/session-manager-plugin
         chmod +x {{Session.WorkingDirectory}}/session-manager-plugin
         conda activate
         python {{Env.File.StartSession}} {{Session.WorkingDirectory}}/session-manager-plugin
      - name: Exit
        type: TEXT
        runnable: True
        data: |
         echo Killing SSM Manager Plugin PIDs: $BYOL_SSM_PIDS
         for pid in ${BYOL_SSM_PIDS//,/ }; do kill $pid; done
      - name: StartSession
        type: TEXT
        data: |
         import boto3
         import json
         import subprocess
         import sys
         import os
         import tempfile
   
         instance_id = "{{Param.LicenseInstanceId}}"
         region = "{{Param.LicenseInstanceRegion}}"
         license_ports_list = "{{Param.LicensePorts}}".split(",")
   
         ssm_client = boto3.client("ssm", region_name=region)
         pids = []
   
         for port in license_ports_list:
           session_response = ssm_client.start_session(
             Target=instance_id,
             DocumentName="AWS-StartPortForwardingSession",
             Parameters={"portNumber": [port], "localPortNumber": [port]}
           )
   
           cmd = [
             sys.argv[1],
             json.dumps(session_response),
             region,
             "StartSession",
             "",
             json.dumps({"Target": instance_id}),
             f"https://ssm.{region}.amazonaws.com"
           ]
   
           process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
           pids.append(process.pid)
           print(f"SSM Port Forwarding Session started for port {port}")
   
         print(f"openjd_env: BYOL_SSM_PIDS={','.join(str(pid) for pid in pids)}")
   
         # Enabling UBL after the BYOL has run out requires prepending the BYOL configuration to the existing license setup
         # Remove the sections that do not apply to your pipeline, or you do not want to use UBL after exhausting the BYOL licenses.
         # The port numbers used may not match what your license server is serving.
   
         # Arnold
         os.environ["ADSKFLEX_LICENSE_FILE"] = f"2701@localhost:{os.environ.get('ADSKFLEX_LICENSE_FILE', '')}"
         print(f"openjd_env: ADSKFLEX_LICENSE_FILE={os.environ['ADSKFLEX_LICENSE_FILE']}")
   
         # Nuke
         os.environ["foundry_LICENSE"] = f"6101@localhost:{os.environ.get('foundry_LICENSE', '')}"
         print(f"openjd_env: foundry_LICENSE={os.environ['foundry_LICENSE']}")
   
         # SideFX
         os.environ["SESI_LMHOST"] = f"localhost:1715;{os.environ.get('SESI_LMHOST', '')}"
         print(f"openjd_env: SESI_LMHOST={os.environ['SESI_LMHOST']}")
   
         # Redshift and Red Giant
         os.environ["redshift_LICENSE"] = f"7054@localhost:7055@localhost:{os.environ.get('redshift_LICENSE', '')}"
         print(f"openjd_env: redshift_LICENSE={os.environ['redshift_LICENSE']}")
   
         # V-Ray doesn't support multiple license servers in a single environment variable
         # See https://documentation.chaos.com/space/LIC5/125050770/Sharing+a+License+Configuration+in+a+Network
         vray_license = os.environ.get('VRAY_AUTH_CLIENT_SETTINGS', '')
         xml_content = """<VRLClient>
           <LicServer>
             <Host>localhost</Host>
             <Port>30304</Port>"""
   
         if vray_license and vray_license.startswith('licset://'):
             server_parts = vray_license.removeprefix('licset://').split(':')
             if len(server_parts) >= 2:
                 xml_content += f"""
             <Host1>{server_parts[0]}</Host1>
             <Port1>{server_parts[1]}</Port1>"""
   
         xml_content += """
             <User></User>
             <Pass></Pass>
           </LicServer>
         </VRLClient>"""
   
         temp_dir = tempfile.gettempdir()
         xml_path = os.path.join(temp_dir, 'vrlclient.xml')
         
         with open(xml_path, 'w') as f:
             f.write(xml_content)
   
         os.environ["VRAY_AUTH_CLIENT_FILE_PATH"] = temp_dir
         print(f"openjd_env: VRAY_AUTH_CLIENT_FILE_PATH={os.environ['VRAY_AUTH_CLIENT_FILE_PATH']}")
   
         # Clear the existing VRAY_AUTH_CLIENT_SETTINGS so only the vrlclient.xml file is used.
         os.environ["VRAY_AUTH_CLIENT_SETTINGS"] = ''
         print(f"openjd_env: VRAY_AUTH_CLIENT_SETTINGS={os.environ['VRAY_AUTH_CLIENT_SETTINGS']}")
   
         # Print out the created xml file's contents
         print(f"V-Ray configuration file: {xml_path}")
         with open(xml_path, 'r') as f:
             print(f"{f.read()}")
   ```

------

1. Antes de guardar el entorno de colas, realice los siguientes cambios en el texto del entorno según sea necesario:
   + Actualice los valores predeterminados de los siguientes parámetros para que reflejen su entorno:
     + **LicenseInstanceID**: el ID de instancia de Amazon EC2 de su servidor de licencias o instancia proxy
     + **LicenseInstanceRegion**— La AWS región en la que se encuentra su granja
     + **LicensePorts**— Una lista de puertos separados por comas que se reenviará al servidor de licencias o a la instancia proxy (por ejemplo, 2700,2701)
   + Si desea utilizar las licencias basadas en el uso (UBL) una vez agotada la licencia Bring your own (BYOL), asegúrese de que el puerto es el correcto para su servidor de licencias. Si no desea utilizar la UBL después de quedarse sin BYOL, añada las variables de entorno de licencias necesarias a la sección de variables.

      Estas variables deberían dirigirla DCCs a localhost en el puerto del servidor de licencias. Por ejemplo, si su servidor de licencias de Foundry escucha en el puerto 6101, debe añadir la variable como. **foundry\$1LICENSE: 6101@localhost**

1. (Opcional) Puede dejar la **prioridad** establecida en **0** o puede cambiarla para ordenar la prioridad de forma diferente entre varios entornos de colas.

1. Seleccione **Crear entorno de cola** para guardar el nuevo entorno.

   Con el entorno de colas configurado, los trabajos enviados a esta cola recuperarán las licencias del servidor de licencias configurado.

## Paso 2: Configuración (opcional) de la instancia de proxy de licencia
<a name="license-proxy"></a>

Como alternativa al uso de un servidor de licencias, puede utilizar un proxy de licencias. Para crear un proxy de licencias, cree una nueva instancia de Amazon Linux 2023 que tenga acceso de red al servidor de licencias. Si es necesario, puede configurar este acceso mediante una conexión VPN. Para obtener más información, consulte [Conexiones VPN](https://docs.aws.amazon.com/vpc/latest/userguide/vpn-connections.html) en la Guía del *usuario de Amazon VPC*.

Para configurar una instancia de proxy con licencia para Deadline Cloud, siga los pasos de este procedimiento. Realice los siguientes pasos de configuración en esta nueva instancia para permitir el reenvío del tráfico de licencias a su servidor de licencias

1. Para instalar el HAProxy paquete, introduzca

   ```
   sudo yum install haproxy
   ```

1. Actualice la sección listen license-server del archivo de configuración**/etc/haproxy/haproxy.cfg** con lo siguiente:

   1. Sustituya **LicensePort1** y **LicensePort2** por los números de puerto que se van a reenviar al servidor de licencias. Añada o elimine valores separados por comas para acomodar la cantidad de puertos requerida.

   1. **LicenseServerHost**Sustitúyalo por el nombre de host o la dirección IP del servidor de licencias.

   ```
   lobal
       log         127.0.0.1 local2
       chroot      /var/lib/haproxy
       user        haproxy
       group       haproxy
       daemon
   
   defaults
       timeout queue           1m
       timeout connect         10s
       timeout client          1m
       timeout server          1m
       timeout http-keep-alive 10s
       timeout check           10s
   
   listen license-server
        bind *:LicensePort1,*:LicensePort2
        server license-server LicenseServerHost
   ```

1. Para habilitar e iniciar el HAProxy servicio, ejecute los siguientes comandos:

   ```
   sudo systemctl enable haproxy
   sudo service haproxy start
   ```

Tras completar los pasos, las solicitudes de licencia enviadas a localhost desde el entorno de cola de reenvío deben reenviarse al servidor de licencias especificado.

## Paso 3: configuración de la plantilla CloudFormation
<a name="byol-cfn-template"></a>

Puede usar una CloudFormation plantilla para configurar una granja completa para que utilice sus propias licencias.

1. Modifique la plantilla proporcionada en el siguiente paso para añadir las variables de entorno de licencias necesarias a la sección de **variables** de **BYOLQueueEntorno**.

1. Utilice la siguiente CloudFormation plantilla.

   ```
   AWSTemplateFormatVersion: 2010-09-09
   Description: "Create &ADC; resources for BYOL"
   
   Parameters:
     LicenseInstanceId:
       Type: AWS::EC2::Instance::Id
       Description: Instance ID for the license server/proxy instance
     LicensePorts:
       Type: String
       Description: Comma-separated list of ports to forward to the license instance
   
   Resources:
     JobAttachmentBucket:
       Type: AWS::S3::Bucket
       Properties:
         BucketName: !Sub byol-example-ja-bucket-${AWS::AccountId}-${AWS::Region}
         BucketEncryption:
           ServerSideEncryptionConfiguration:
             - ServerSideEncryptionByDefault:
                 SSEAlgorithm: AES256
   
     Farm:
       Type: AWS::Deadline::Farm
       Properties:
         DisplayName: BYOLFarm
   
     QueuePolicy:
       Type: AWS::IAM::ManagedPolicy
       Properties:
         ManagedPolicyName: BYOLQueuePolicy
         PolicyDocument:
           Version: 2012-10-17
           Statement:
             - Effect: Allow
               Action:
                 - s3:GetObject
                 - s3:PutObject
                 - s3:ListBucket
                 - s3:GetBucketLocation
               Resource:
                 - !Sub ${JobAttachmentBucket.Arn}
                 - !Sub ${JobAttachmentBucket.Arn}/job-attachments/*
               Condition:
                 StringEquals:
                   aws:ResourceAccount: !Sub ${AWS::AccountId}
             - Effect: Allow
               Action: logs:GetLogEvents
               Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/deadline/${Farm.FarmId}/*
             - Effect: Allow
               Action:
                 - s3:ListBucket
                 - s3:GetObject
               Resource:
                 - "*"
               Condition:
                 ArnLike:
                   s3:DataAccessPointArn:
                     - arn:aws:s3:*:*:accesspoint/deadline-software-*
                 StringEquals:
                   s3:AccessPointNetworkOrigin: VPC
     
     BYOLSSMPolicy:
       Type: AWS::IAM::ManagedPolicy
       Properties:
         ManagedPolicyName: BYOLSSMPolicy
         PolicyDocument:
           Version: 2012-10-17
           Statement:
             - Effect: Allow
               Action:
                 - ssm:StartSession
               Resource:
                 - !Sub arn:aws:ssm:${AWS::Region}::document/AWS-StartPortForwardingSession
                 - !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/${LicenseInstanceId}
   
   
     WorkerPolicy:
       Type: AWS::IAM::ManagedPolicy
       Properties:
         ManagedPolicyName: BYOLWorkerPolicy
         PolicyDocument:
           Version: 2012-10-17
           Statement:
             - Effect: Allow
               Action:
                 - logs:CreateLogStream
               Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/deadline/${Farm.FarmId}/*
               Condition:
                 ForAnyValue:StringEquals:
                   aws:CalledVia:
                     - deadline.amazonaws.com
             - Effect: Allow
               Action:
                 - logs:PutLogEvents
                 - logs:GetLogEvents
               Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/deadline/${Farm.FarmId}/*
               
   
     QueueRole:
       Type: AWS::IAM::Role
       Properties:
         RoleName: BYOLQueueRole
         ManagedPolicyArns:
           - !Ref QueuePolicy
           - !Ref BYOLSSMPolicy
         AssumeRolePolicyDocument:
           Version: 2012-10-17
           Statement:
             - Effect: Allow
               Action:
                 - sts:AssumeRole
               Principal:
                 Service:
                   - credentials.deadline.amazonaws.com
                   - deadline.amazonaws.com
               Condition:
                 StringEquals:
                   aws:SourceAccount: !Sub ${AWS::AccountId}
                 ArnEquals:
                   aws:SourceArn: !Ref Farm
   
     WorkerRole:
       Type: AWS::IAM::Role
       Properties:
         RoleName: BYOLWorkerRole
         ManagedPolicyArns:
           - arn:aws:iam::aws:policy/AWSDeadlineCloud-FleetWorker
           - !Ref WorkerPolicy
         AssumeRolePolicyDocument:
           Version: 2012-10-17
           Statement:
             - Effect: Allow
               Action:
                 - sts:AssumeRole
               Principal:
                 Service: credentials.deadline.amazonaws.com
   
   
     Queue:
       Type: AWS::Deadline::Queue
       Properties:
         DisplayName: BYOLQueue
         FarmId: !GetAtt Farm.FarmId
         RoleArn: !GetAtt QueueRole.Arn
         JobRunAsUser:
           Posix:
             Group: ""
             User: ""
           RunAs: WORKER_AGENT_USER
         JobAttachmentSettings:
           RootPrefix: job-attachments
           S3BucketName: !Ref JobAttachmentBucket
     
     Fleet:
       Type: AWS::Deadline::Fleet
       Properties:
         DisplayName: BYOLFleet
         FarmId: !GetAtt Farm.FarmId
         MinWorkerCount: 1
         MaxWorkerCount: 2
         Configuration:
           ServiceManagedEc2:
             InstanceCapabilities:
               VCpuCount:
                 Min: 4
                 Max: 16
               MemoryMiB:
                 Min: 4096
                 Max: 16384
               OsFamily: LINUX
               CpuArchitectureType: x86_64
             InstanceMarketOptions:
               Type: on-demand
         RoleArn: !GetAtt WorkerRole.Arn
   
     QFA:
       Type: AWS::Deadline::QueueFleetAssociation
       Properties:
         FarmId: !GetAtt Farm.FarmId
         FleetId: !GetAtt Fleet.FleetId
         QueueId: !GetAtt Queue.QueueId
     
     CondaQueueEnvironment:
       Type: AWS::Deadline::QueueEnvironment
       Properties:
         FarmId: !GetAtt Farm.FarmId
         Priority: 5
         QueueId: !GetAtt Queue.QueueId
         TemplateType: YAML
         Template: |
           specificationVersion: 'environment-2023-09'
           parameterDefinitions:
           - name: CondaPackages
             type: STRING
             description: >
               This is a space-separated list of conda package match specifications to install for the job.
               E.g. "blender=3.6" for a job that renders frames in Blender 3.6.
   
               See https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-specs.html#package-match-specifications
             default: ""
             userInterface:
               control: LINE_EDIT
               label: Conda Packages
           - name: CondaChannels
             type: STRING
             description: >
               This is a space-separated list of conda channels from which to install packages. &ADC; SMF packages are
               installed from the "deadline-cloud" channel that is configured by &ADC;.
   
               Add "conda-forge" to get packages from the https://conda-forge.org/ community, and "defaults" to get packages
               from Anaconda Inc (make sure your usage complies with https://www.anaconda.com/terms-of-use).
             default: "deadline-cloud"
             userInterface:
               control: LINE_EDIT
               label: Conda Channels
           environment:
             name: Conda
             script:
               actions:
                 onEnter:
                   command: "conda-queue-env-enter"
                   args: ["{{Session.WorkingDirectory}}/.env", "--packages", "{{Param.CondaPackages}}", "--channels", "{{Param.CondaChannels}}"]
                 onExit:
                   command: "conda-queue-env-exit"
     
     BYOLQueueEnvironment:
       Type: AWS::Deadline::QueueEnvironment
       Properties:
         FarmId: !GetAtt Farm.FarmId
         Priority: 10
         QueueId: !GetAtt Queue.QueueId
         TemplateType: YAML
         Template: !Sub |
           specificationVersion: "environment-2023-09"
           parameterDefinitions:
           - name: LicenseInstanceId
             type: STRING
             description: >
               The Instance ID of the license server/proxy instance
             default: ""
           - name: LicenseInstanceRegion
             type: STRING
             description: >
               The region containing this farm
             default: ""
           - name: LicensePorts
             type: STRING
             description: >
               Comma-separated list of ports to be forwarded to the license server/proxy
               instance. Example: "2701,2702,7075,2703,6101,1715,1716,1717,7054,7055,30304"
             default: "2701,2702,7075,2703,6101,1715,1716,1717,7054,7055,30304"
           environment:
           name: BYOL License Forwarding
           variables:
             example_LICENSE: 2701@localhost
           script:
             actions:
             onEnter:
               command: bash
               args: [ "{{Env.File.Enter}}" ]
             onExit:
               command: bash
               args: [ "{{Env.File.Exit}}" ]
             embeddedFiles:
             - name: Enter
               type: TEXT
               runnable: True
               data: |
                 curl https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm -Ls | rpm2cpio - | cpio -iv --to-stdout ./usr/local/sessionmanagerplugin/bin/session-manager-plugin > {{Session.WorkingDirectory}}/session-manager-plugin
                 chmod +x {{Session.WorkingDirectory}}/session-manager-plugin
                 conda activate
                 python {{Env.File.StartSession}} {{Session.WorkingDirectory}}/session-manager-plugin
             - name: Exit
               type: TEXT
               runnable: True
               data: |
                 echo Killing SSM Manager Plugin PIDs: $BYOL_SSM_PIDS
                 for pid in ${BYOL_SSM_PIDS//,/ }; do kill $pid; done
             - name: StartSession
               type: TEXT
               data: |
                 import boto3
                 import json
                 import subprocess
                 import sys
                 import os
                 import tempfile
   
                 instance_id = "{{Param.LicenseInstanceId}}"
                 region = "{{Param.LicenseInstanceRegion}}"
                 license_ports_list = "{{Param.LicensePorts}}".split(",")
   
                 ssm_client = boto3.client("ssm", region_name=region)
                 pids = []
   
                 for port in license_ports_list:
                   session_response = ssm_client.start_session(
                     Target=instance_id,
                     DocumentName="AWS-StartPortForwardingSession",
                     Parameters={"portNumber": [port], "localPortNumber": [port]}
                   )
   
                   cmd = [
                     sys.argv[1],
                     json.dumps(session_response),
                     region,
                     "StartSession",
                     "",
                     json.dumps({"Target": instance_id}),
                     f"https://ssm.{region}.amazonaws.com"
                   ]
   
                   process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
                   pids.append(process.pid)
                   print(f"SSM Port Forwarding Session started for port {port}")
   
                 print(f"openjd_env: BYOL_SSM_PIDS={','.join(str(pid) for pid in pids)}")
   
                 # Enabling UBL after the "bring your own license" (BYOL) has run out requires prepending the BYOL configuration to the existing license setup
                 # Remove the sections that do not apply to your pipeline, or you do not want to use UBL after exhausting the BYOL licenses.
                 # The port numbers used may not match what your license server is serving.
   
                 # Arnold
                 os.environ["ADSKFLEX_LICENSE_FILE"] = f"2701@localhost:{os.environ.get('ADSKFLEX_LICENSE_FILE', '')}"
                 print(f"openjd_env: ADSKFLEX_LICENSE_FILE={os.environ['ADSKFLEX_LICENSE_FILE']}")
   
                 # Nuke
                 os.environ["foundry_LICENSE"] = f"6101@localhost:{os.environ.get('foundry_LICENSE', '')}"
                 print(f"openjd_env: foundry_LICENSE={os.environ['foundry_LICENSE']}")
   
                 # SideFX
                 os.environ["SESI_LMHOST"] = f"localhost:1715;{os.environ.get('SESI_LMHOST', '')}"
                 print(f"openjd_env: SESI_LMHOST={os.environ['SESI_LMHOST']}")
   
                 # Redshift and Red Giant
                 os.environ["redshift_LICENSE"] = f"7054@localhost:7055@localhost:{os.environ.get('redshift_LICENSE', '')}"
                 print(f"openjd_env: redshift_LICENSE={os.environ['redshift_LICENSE']}")
   
                 # V-Ray doesn't support multiple license servers in a single environment variable
                 # See https://documentation.chaos.com/space/LIC5/125050770/Sharing+a+License+Configuration+in+a+Network
                 vray_license = os.environ.get('VRAY_AUTH_CLIENT_SETTINGS', '')
                 xml_content = """<VRLClient>
                   <LicServer>
                     <Host>localhost</Host>
                     <Port>30304</Port>"""
   
                 if vray_license and vray_license.startswith('licset://'):
                     server_parts = vray_license.removeprefix('licset://').split(':')
                     if len(server_parts) >= 2:
                         xml_content += f"""
                     <Host1>{server_parts[0]}</Host1>
                     <Port1>{server_parts[1]}</Port1>"""
   
                 xml_content += """
                     <User></User>
                     <Pass></Pass>
                   </LicServer>
                 </VRLClient>"""
   
                 temp_dir = tempfile.gettempdir()
                 xml_path = os.path.join(temp_dir, 'vrlclient.xml')
                 
                 with open(xml_path, 'w') as f:
                     f.write(xml_content)
   
                 os.environ["VRAY_AUTH_CLIENT_FILE_PATH"] = temp_dir
                 print(f"openjd_env: VRAY_AUTH_CLIENT_FILE_PATH={os.environ['VRAY_AUTH_CLIENT_FILE_PATH']}")
   
                 # Clear the existing VRAY_AUTH_CLIENT_SETTINGS so only the vrlclient.xml file is used.
                 os.environ["VRAY_AUTH_CLIENT_SETTINGS"] = ''
                 print(f"openjd_env: VRAY_AUTH_CLIENT_SETTINGS={os.environ['VRAY_AUTH_CLIENT_SETTINGS']}")
   
                 # Print out the created xml file's contents
                 print(f"V-Ray configuration file: {xml_path}")
                 with open(xml_path, 'r') as f:
                     print(f"{f.read()}")
   ```

1. Al implementar la CloudFormation plantilla, proporcione los siguientes parámetros:
   + Actualice el **LicenseInstanceID** con el ID de instancia de Amazon EC2 de su servidor de licencias o instancia proxy
   + **LicensePorts**Actualícelo con una lista de puertos separados por comas para reenviarlos al servidor de licencias o a la instancia proxy (por ejemplo, 2700,2701)
   + Agregue las variables de entorno de la licencia sustituyéndolas en la plantilla **example\$1LICENSE: 2700@localhost**

1. Implemente la plantilla para configurar su granja con la capacidad de traer su propia licencia.