Blog de Amazon Web Services (AWS)

Creación de dominios y perfiles de usuario de Amazon SageMaker Studio mediante AWS CloudFormation

Por Qingwei Li, David Ping e Joseph Jegan

 

Amazon SageMaker Studio es el primer entorno de desarrollo (IDE) totalmente integrado para machine learning (ML). Proporciona una interfaz visual unificada, basada en web, donde puede realizar todos los pasos de desarrollo de ML necesarios para construir, entrenar, ajustar, depurar, implementar y monitorear modelos. En esta publicación, demostramos cómo puede crear un dominio y un perfil de usuario de SageMaker Studio mediante AWS CloudFormation. AWS CloudFormation le ofrece una forma sencilla de modelar una colección de recursos relacionados de AWS y de terceros, aprovisionarlos de forma rápida y consistente y administrarlos durante todo su ciclo de vida mediante el tratamiento de la infraestructura como código.

Dado que AWS CloudFormation no se integra de forma nativa con SageMaker Studio en el momento de escribir este documento, utilizamos AWS CloudFormation para aprovisionar dos funciones de AWS Lambda y, a continuación, invocar estas funciones para crear, eliminar y actualizar el dominio y el perfil de usuario de Studio. En el resto de esta publicación, recorremos la función Lambda para crear el dominio de Studio (el código para crear un perfil de usuario de Studio funciona de manera similar) y luego la plantilla CloudFormation. Todo el código está disponible en el repositorio de GitHub.

 

Función Lambda para crear, eliminar y actualizar un dominio de Studio

En la función Lambda, lambda_handler llama a una de las tres funciones, handle_create, handle_update y handle_delete, para crear, actualizar y eliminar el dominio de Studio, respectivamente. Dado que invocamos esta función utilizando un recurso personalizado de AWS CloudFormation, el tipo de solicitud de recurso personalizado se envía en el campo RequestType desde AWS CloudFormation. RequestType determina qué función llamar dentro de la función lambda_handler . Por ejemplo, cuando AWS CloudFormation detecta cambios en la sección custom::StudioDomain de nuestra plantilla CloudFormation, el servicio establece el campo RequestType como Update y se llama a la función handle_update. El siguiente es el código para lambda_handler :

 

def handle_create(event, context):
    print("**Starting running the SageMaker workshop setup code")
    resource_config = event['ResourceProperties']
    print("**Creating studio domain")
    response_data = create_studio_domain(resource_config)
    cfnresponse.send(event, context, cfnresponse.SUCCESS,
                     {}, physicalResourceId=response_data['DomainArn'])

Las tres funciones para crear, actualizar y eliminar el dominio funcionan de manera similar. Para este post, recorremos el código responsable por la creación de un dominio. Al invocar la función Lambda a través de un recurso personalizado de AWS CloudFormation, pasamos parámetros clave que ayudan a definir nuestro dominio Studio a través de las Properties del recurso personalizado. En la función Lambda, extraemos estos parámetros desde el origen de eventos (event source) de AWS CloudFormation. En la función handle_create, los parámetros se leen desde el evento y se pasan a la función create_studio_domain. Vea el siguiente código para handle_create:

 

def handle_create(event, context):
    print("**Starting running the SageMaker workshop setup code")
    resource_config = event['ResourceProperties']
    print("**Creating studio domain")
    response_data = create_studio_domain(resource_config)
    cfnresponse.send(event, context, cfnresponse.SUCCESS,
                     {}, physicalResourceId=response_data['DomainArn'])

 

Utilizamos un cliente boto3 de SageMaker para crear dominios de Studio. Para esta publicación, establecemos el nombre de dominio, la VPC y la subred que utiliza Studio, y el rol de ejecución de SageMaker para el dominio de Studio. Después de realizar la llamada create_domain, verificamos el estado de creación cada 5 segundos. Una vez completada la creación, devolvemos el Amazon Resource Name (ARN) y la URL del dominio creado. Por defecto, la cantidad de tiempo que Lambda permite que una función se ejecute antes de detenerla es de 3 segundos. Por lo tanto, asegúrese de que el límite de timeout de su función Lambda esté establecido adecuadamente. Establecemos el límite de timeout en 900 segundos. El siguiente es el código create_studio_domain (las funciones para eliminar y actualizar dominios también se implementan usando boto3 y se construyen de manera similar):

 

client = boto3.client('sagemaker')
def create_studio_domain(config):
    vpc_id = config['VPC']
    subnet_ids = config['SubnetIds']
    default_user_settings = config['DefaultUserSettings']
    domain_name = config['DomainName']

    response = client.create_domain(
        DomainName=domain_name,
        AuthMode='IAM',
        DefaultUserSettings=default_user_settings,
        SubnetIds=subnet_ids.split(','),
        VpcId=vpc_id
    )

    domain_id = response['DomainArn'].split('/')[-1]
    created = False
    while not created:
        response = client.describe_domain(DomainId=domain_id)
        time.sleep(5)
        if response['Status'] == 'InService':
            created = True

    logging.info("**SageMaker domain created successfully: %s", domain_id)
    return response
 
       

Por último, comprimimos el script de Python en un .zip, lo guardamos como domain_function.zip y lo subimos a Amazon Simple Storage Service (Amazon S3).

La función Lambda utilizada para crear un perfil de usuario se construye de manera similar. Para obtener más información, vea el script UserProfile_function.py en el repositorio de GitHub.

 

Plantilla CloudFormation

En la plantilla CloudFormation, creamos un rol de ejecución para Lambda, un rol de ejecución para SageMaker Studio y la función Lambda utilizando el código explicado en la sección anterior. Invocamos esta función especificándola como destino de un recurso personalizado. Para obtener más información sobre cómo invocar una función Lambda con AWS CloudFormation, consulte Uso de AWS Lambda con AWS CloudFormation.

Rol de ejecución de Lambda

Este rol le da a nuestra función Lambda el permiso para crear una stream de Amazon CloudWatch Logs y escribir registros en CloudWatch. Debido a que creamos, eliminamos y actualizamos dominios de Studio en nuestra función, también otorgamos a este rol el permiso para hacerlo. Vea el siguiente código:

 

LambdaExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - "sts:AssumeRole"
      Path: /

  LambdaExecutionPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Path: /
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: CloudWatchLogsPermissions
            Effect: Allow
            Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource: !Sub "arn:${AWS::Partition}:logs:*:*:*"
          - Sid: SageMakerDomainPermission
            Effect: Allow
            Action:
              - sagemaker:CreateDomain
              - sagemaker:DescribeDomain
              - sagemaker:DeleteDomain
              - sagemaker:UpdateDomain
              - sagemaker:CreateUserProfile
              - sagemaker:UpdateUserProfile
              - sagemaker:DeleteUserProfile
              - sagemaker:DescribeUserProfile
            Resource:
              - !Sub "arn:${AWS::Partition}:sagemaker:*:*:domain/*"
              - !Sub "arn:${AWS::Partition}:sagemaker:*:*:user-profile/*"
          - Sid: SageMakerExecPassRole
            Effect: Allow
            Action:
              - iam:PassRole
            Resource: !GetAtt  SageMakerExecutionRole.Arn
      Roles:
        - !Ref LambdaExecutionRole

 

Rol de ejecución de SageMaker

El siguiente rol de ejecución de SageMaker se adjunta a Studio (para fines de demostración, asociaremos a este rol la política AmazonSageMakerFullAccess):

 

SageMakerExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - sagemaker.amazonaws.com
            Action:
              - "sts:AssumeRole"
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSageMakerFullAccess

 

Función Lambda

El recurso AWW::Lambda::Function crea una función Lambda. Para crear una función, necesitamos un paquete de implementación y un rol de ejecución. El paquete de implementación contiene el código de nuestra función (function.zip). El rol de ejecución, que es el LambdaExecutionRole creado en el paso anterior, concede permiso a la función para crear una función Lambda. También agregamos el recurso  CFNResponseLayer al entorno de ejecución de nuestra función. CFNResponseLayer permite que la función interactúe con un recurso personalizado de AWS CloudFormation. Contiene un método de envío para enviar respuestas desde Lambda a AWS CloudFormation. Vea el siguiente código:

 
       
Resources:
...
 StudioDomainFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        S3Bucket: !Ref S3Bucket
        S3Key: function.zip
        S3ObjectVersion: !Ref S3ObjectVersion
      Runtime: python3.8
      Timeout: 900
      Layers:
        - !Ref CfnResponseLayer
       
  CfnResponseLayer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      CompatibleRuntimes:
        - python3.8
      Content:
        S3Bucket: !Ref S3Bucket
        S3Key: cfnResponse-layer.zip
      Description: cfn-response layer
      LayerName: cfn-response

Invocación de la función Lambda con un recurso personalizado de AWS CloudFormation

Los recursos personalizados proporcionan una forma de escribir lógica de aprovisionamiento personalizada en una plantilla de CloudFormation y hacer que AWS CloudFormation la ejecute durante una operación sobre el stack, como cuando se crea, actualiza o elimina un stack. Para obtener más información, vea Recursos personalizados. Obtenemos el ARN de la función Lambda creado a partir del paso anterior y lo pasamos a AWS CloudFormation como nuestro token de servicio (service token). Esto permite a AWS CloudFormation invocar la función Lambda. En Properties, pasamos los parámetros necesarios para crear, actualizar y eliminar nuestro dominio. Vea el siguiente código:

 

StudioDomain:
    Type: Custom::StudioDomain
    Properties:
      ServiceToken: !GetAtt StudioDomainFunction.Arn
      VPC: !Ref VPCId
      SubnetIds: !Ref SubnetIds
      DomainName: "MyDomainName"
      DefaultUserSettings:
        ExecutionRole: !GetAtt SageMakerExecutionRole.Arn

De la misma manera, invocamos la función Lambda para crear un perfil de usuario:

UserProfile:
    Type: Custom::UserProfile
    Properties:
      ServiceToken: !GetAtt UserProfileFunction.Arn
      DomainId: !GetAtt StudioDomain.DomainId
      UserProfileName: !Ref UserProfileName
      UserSettings:
        ExecutionRole: !GetAtt SageMakerExecutionRole.Arn

 

Conclusión

En esta publicación, hemos recorrido los pasos para crear, eliminar y actualizar dominios de SageMaker Studio mediante AWS CloudFormation y AWS Lambda. Los archivos de ejemplo están disponibles en el repositorio de GitHub. Para más información acerca de cómo crear un dominio de Studio dentro de una VPC, vea Securing Amazon SageMaker Studio connectivity using a private VPC. Para más información acerca de SageMaker Studio, consulte Introducción a Amazon SageMaker Studio.

 

Este artigo foi traduzido do Blog da AWS em Inglês.

 


Sobre os autores

Qingwei Li es Especialista en Machine Learning en Amazon Web Services. Recibió su doctorado en Investigación Operativa después de romper la cuenta de la beca de investigación de su asesor y no entregar el Premio Nobel que prometió. Actualmente ayuda a clientes de la industria de servicios financieros y seguros a crear soluciones de machine learning en AWS. En su tiempo libre, le gusta leer y enseñar.

 

 

 

Joseph Jegan es Arquitecto de Aplicaciones de nube en Amazon Web Services. Ayuda a los clientes de AWS a utilizar los servicios de AWS para diseñar aplicaciones escalables y seguras. Previo a AWS, cuenta con más de 20 años de experiencia en desarrollo de software, trabajando en el desarrollo de una plataforma de comercio electrónico para grandes clientes minoristas. Está basado fuera del área metropolitana de Nueva York y disfruta aprender tecnologías nativas de nube emergentes.

 

 

 

David Ping es Arquitecto Principal de Soluciones de Machine Learning y Gerente senior de Arquitectura de Soluciones AI/ML en Amazon Web Services. Ayuda a los clientes empresariales a crear y operar soluciones de machine learning en AWS. En su tiempo libre, David disfruta caminar y leer los últimos artículos de machine learning.

 

 

 

Revisor

Rodrigo Alarcón es Arquitecto de Soluciones senior en AWS. En su rol, ayuda a empresas de distinto tamaño a generar valor para su negocio mediante tecnologías de computación en la nube. Sus intereses incluyen machine learning y ciberseguridad.