paws icon indicating copy to clipboard operation
paws copied to clipboard

Equivalent of `get_execution_role()` from Python SDK?

Open juliasilge opened this issue 2 years ago • 4 comments

Hello! 👋 Thank you so much for your investment in this package.

Is there an equivalent from paws for doing this via the Python SDK?

library(reticulate)
sagemaker <- import("sagemaker")
role <- sagemaker$get_execution_role()

I find myself needing to know this role when using create_model() in SageMaker.

juliasilge avatar Jun 28 '22 22:06 juliasilge

You might want to consider the sagemaker sdk for R built off paws. I am currently getting the unit tests built for it before releasing it fully to the cran. But feel free to have a look in how to mimic it's python counter part:

https://github.com/DyfanJones/sagemaker-r-core/blob/4bc1e1051f690120897dabfb9178da0c6e34b1a9/R/session.R#L3548-L3559

get_execution_role <- function(sagemaker_session = NULL){
  sagemaker_session <- if(!inherits(sagemaker_session, "Session")) Session$new() else sagemaker_session


  arn <- sagemaker_session$get_caller_identity_arn()


  if (grepl(":role/", arn)) {
    return(arn)
  } else {
    message <- sprintf("The current AWS identity is not a role: %s, therefore it cannot be used as a SageMaker execution role", arn)
    ValueError$new(message)
  }
}

DyfanJones avatar Jun 28 '22 23:06 DyfanJones

get_caller_identity_arn method is found here:

https://github.com/DyfanJones/sagemaker-r-core/blob/4bc1e1051f690120897dabfb9178da0c6e34b1a9/R/session.R#L2077-L2146

    get_caller_identity_arn = function(){


      if(file.exists(NOTEBOOK_METADATA_FILE)){
        metadata = read_json(NOTEBOOK_METADATA_FILE)
        instance_name = metadata[["ResourceName"]]
        domain_id = metadata[["DomainId"]]
        user_profile_name = metadata[["UserProfileName"]]


        tryCatch({
          if(is.null(domain_id)){
            instance_desc = self$sagemaker$describe_notebook_instance(NotebookInstanceName=instance_name)
            return(instance_desc$RoleArn)
          }
          user_profile_desc = self$sagemaker$describe_user_profile(
            DomainId=domain_id, UserProfileName=user_profile_name
          )


          # First, try to find role in userSettings
          if (!is.null(user_profile_desc[["UserSettings"]][["ExecutionRole"]]))
            return(user_profile_desc[["UserSettings"]][["ExecutionRole"]])


          # If not found, fallback to the domain
          domain_desc = self$sagemaker$describe_domain(DomainId=domain_id)
          return(domain_desc[["DefaultUserSettings"]][["ExecutionRole"]])
          }, error=function(e) {
            LOGGER$debug(
              "Couldn't call 'describe_notebook_instance' to get the Role \nARN of the instance %s.",
              instance_name)
        })
      }
      assumed_role = self$paws_session$client(
        "sts",
        config = list(
          region = self$paws_region_name,
          endpoint = sts_regional_endpoint(self$paws_region_name)
          )
      )$get_caller_identity()[["Arn"]]


      role = gsub("^(.+)sts::(\\d+):assumed-role/(.+?)/.*$", "\\1iam::\\2:role/\\3", assumed_role)


      # Call IAM to get the role's path
      role_name = substr(role, gregexpr("/",role)[[1]][1] + 1, nchar(role))
      tryCatch({
        role = self$paws_session$client("iam")$get_role(RoleName=role_name)[["Role"]][["Arn"]]
      }, error = function(e){
        LOGGER$warn(
          "Couldn't call 'get_role' to get Role ARN from role name %s to get Role path.",
          role_name
        )
        # This conditional has been present since the inception of SageMaker
        # Guessing this conditional's purpose was to handle lack of IAM permissions
        # https://github.com/aws/sagemaker-python-sdk/issues/2089#issuecomment-791802713
        if (grepl("AmazonSageMaker-ExecutionRole", assumed_role)){
          LOGGER$warn(paste(
            "Assuming role was created in SageMaker AWS console,",
            "as the name contains `AmazonSageMaker-ExecutionRole`.",
            "Defaulting to Role ARN with service-role in path.",
            "If this Role ARN is incorrect, please add",
            "IAM read permissions to your role or supply the",
            "Role Arn directly.")
          )
          role = gsub(
            "^(.+)sts::(\\d+):assumed-role/(.+?)/.*$",
            "\\1iam::\\2:role/service-role/\\3",
            assumed_role
          )
        }
      })
      return(role)
    },

I will be continue development for it, soon just took a short breaks as I was going a little crazy with the sheer amount of work is needed to mimic the sagemaker sdk :P

DyfanJones avatar Jun 28 '22 23:06 DyfanJones

In case folks are interested, I have a demo here for deploying a vetiver model to SageMaker. I'd like to streamline this more in the future, so I'm definitely interested in work here in paws or in the SageMaker SDK package you are building @DyfanJones. I'd love to stay in touch on this!

juliasilge avatar Jul 19 '22 18:07 juliasilge

@juliasilge perfect :) i was planning in reaching out at some point. The initial goal of sagemaker is to replicate the python equivalent. Next would be to allow extensions to r ml frameworks, so linking it to vetiver would be great :)

DyfanJones avatar Jul 19 '22 19:07 DyfanJones

@juliasilge is it ok to close this? As it supported in smdocker::sagemaker_get_execution_role

DyfanJones avatar Jun 14 '23 21:06 DyfanJones

Yes, thank you again so much for your work on this! 🙌

juliasilge avatar Jun 14 '23 21:06 juliasilge