如果所有实例都使用相同的 IAM 角色,如何确定哪个 SageMaker 笔记本实例进行了特定 API 调用?

上次更新时间:2021 年 3 月 17 日

我有多个 Amazon SageMaker 笔记本实例。它们都使用相同的 AWS Identity and Access Management (IAM) 角色。无论哪个笔记本实例执行了操作,每个 API 操作的 AWS CloudTrail 事件都会显示相同的 PrincipalID(会话名称)。我如何判断哪个笔记本实例执行了哪些 API 操作?

简短描述

当您有多个具有相同 IAM 角色的 SageMaker 实例时,您无法通过 CloudTrail 事件确定哪个笔记本实例执行了特定 API 操作。

示例:

{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AAAAAAAAAAAAAAAAAA:SageMaker",
       
    "arn": "arn:aws:sts::111122223333:assumed-role/AmazonSageMaker-ExecutionRole/SageMaker",

解决方法

1.    为 SageMaker 笔记本实例创建 IAM 执行角色。或者,使用现有的执行角色。在以下步骤中,执行角色的 Amazon 资源名称 (ARN) 为 arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole

2.    附加执行角色中包括 sts:AssumeRole 的 IAM 策略。sts:AssumeRole 操作允许执行角色使用不同的会话名称代入自己。示例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole"
        }
    ]
}

3.    创建开始笔记本生命周期配置脚本,类似于下面的示例。此示例脚本检索笔记本实例名称,然后使用该名称作为会话名称。

Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#!/bin/bash
# Create a new bash script file using the cat command
# The new bash script will be used to set up the cron job at the end of this script
cat >/home/ec2-user/scriptAssumeRole.sh <<'EOF'
#!/bin/bash

set -e

# Obtain the name of the notebook instance
nbname=$(jq -r '.ResourceName' /opt/ml/metadata/resource-metadata.json)

# Use the AWS Command Line Interface (AWS CLI) to obtain the Amazon Resource Name (ARN) of the IAM execution role
nbinfo=$(aws sagemaker describe-notebook-instance --notebook-instance-name $nbname)
nbrole=$(jq -r '.RoleArn' <<< "$nbinfo")

# Use the AWS CLI to get the new credentials and create a session name based on the notebook instance name
cred=$(aws sts assume-role --role-arn $nbrole --role-session-name $nbname)

# Initialize variables
AccessKeyId=""
SecretAccessKey=""
SessionToken=""

# Obtain individual values from credentials
AccessKeyId=$(jq -r '.Credentials.AccessKeyId' <<< "$cred")
SecretAccessKey=$(jq -r '.Credentials.SecretAccessKey' <<< "$cred")
SessionToken=$(jq -r '.Credentials.SessionToken' <<< "$cred")

# Obtain the Region of the notebook instance
nbregion=$(aws configure get region)

# Obtain the length of each variable for conditional testing
len1=${#AccessKeyId}
len2=${#SecretAccessKey}
len3=${#SessionToken}

# Write credentials to a new config file
cat > /home/ec2-user/.aws/config.new <<EOF1
[default]
region=$nbregion
aws_access_key_id=$AccessKeyId
aws_secret_access_key=$SecretAccessKey
aws_session_token=$SessionToken
EOF1

if [[ ($len1 -gt 0) && ($len2 -gt 0) && ($len3 -gt 0) ]];
then
  # Overwrite the config with a new config file only if credentials are obtained
  echo "Credentials obtained."
sudo mv /home/ec2-user/.aws/config.new /home/ec2-user/.aws/config
else
  echo "No credentials are available."
fi
EOF
chmod +x /home/ec2-user/scriptAssumeRole.sh

# Now run the script:
echo "Running Assume Role Script"
/home/ec2-user/scriptAssumeRole.sh

echo "Setting up cron job every 15 minutes"
(crontab -l 2>/dev/null; echo "*/15 * * * * /home/ec2-user/scriptAssumeRole.sh") | crontab -

4.    创建 SageMaker 笔记本实例并附上您在上一步中创建的生命周期配置脚本。对于此示例,假设笔记本实例被命名为 test-2

5.    要识别执行 API 操作的笔记本实例,请查看 CloudTrail 事件。在 userIdentity 对象中,principalIdarn 显示笔记本实例名称。例如,以下事件详细信息显示名为 test-2 的 SageMaker 笔记本实例进行了 API 调用。

{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AAAAAAAAAAAAAAAAAAAA:test-2",
        "arn": "arn:aws:sts::111122223333:assumed-role/AmazonSageMaker-ExecutionRole/test-2",
        "accountId": "111122223333",
        "accessKeyId": "AAAAAAAAAAAAAAAAAAAA",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AAAAAAAAAAAAAAAAAAAA",
                "arn": "arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole",
                "accountId": "111122223333",
                "userName": "AmazonSageMaker-ExecutionRole"
            },
            "webIdFederationData": {},
            "attributes": {
                "mfaAuthenticated": "false",
                "creationDate": "2020-09-12T00:45:04Z"
            }
        },
        "invokedBy": "im.amazonaws.com"
    },
    "eventTime": "2020-09-12T00:49:04Z",
    "eventSource": "sagemaker.amazonaws.com",
    "eventName": "CreateEndpoint",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "im.amazonaws.com",
    "userAgent": "im.amazonaws.com",
    "requestParameters": {
        "endpointName": "sagemaker-mxnet-ep",
        "endpointConfigName": "sagemaker-mxnet-epc",
        "tags": []
    },
    "responseElements": {
        "endpointArn": "arn:aws:sagemaker:us-east-1:111122223333:endpoint/sagemaker-mxnet-ep"
    },
    "requestID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "eventID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "eventType": "AwsApiCall",
    "recipientAccountId": "111122223333"
}

这篇文章对您有帮助吗?


您是否需要账单或技术支持?