Skip to content

Commit 0838bf0

Browse files
laurenyuDan
authored andcommitted
change: allow ModelMonitor and Processor to take IAM role names (in addition to ARNs) (#1150)
1 parent d33663c commit 0838bf0

File tree

10 files changed

+68
-81
lines changed

10 files changed

+68
-81
lines changed

src/sagemaker/automl/automl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13-
"""A class for SageMaker AutoML Job."""
13+
"""A class for SageMaker AutoML Jobs."""
1414
from __future__ import absolute_import
1515

1616
from six import string_types

src/sagemaker/model_monitor/model_monitoring.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,17 @@
2222
import logging
2323
import uuid
2424

25-
from six.moves.urllib.parse import urlparse
2625
from six import string_types
27-
26+
from six.moves.urllib.parse import urlparse
2827
from botocore.exceptions import ClientError
2928

29+
from sagemaker.exceptions import UnexpectedStatusException
30+
from sagemaker.model_monitor.monitoring_files import Constraints, ConstraintViolations, Statistics
3031
from sagemaker.network import NetworkConfig
32+
from sagemaker.processing import Processor, ProcessingInput, ProcessingJob, ProcessingOutput
3133
from sagemaker.s3 import S3Uploader
32-
33-
from sagemaker.utils import name_from_base
3434
from sagemaker.session import Session
35-
from sagemaker.processing import Processor
36-
from sagemaker.processing import ProcessingJob
37-
from sagemaker.processing import ProcessingInput
38-
from sagemaker.processing import ProcessingOutput
39-
from sagemaker.model_monitor.monitoring_files import Constraints, ConstraintViolations
40-
from sagemaker.model_monitor.monitoring_files import Statistics
41-
from sagemaker.exceptions import UnexpectedStatusException
42-
from sagemaker.utils import retries
35+
from sagemaker.utils import name_from_base, retries
4336

4437
_DEFAULT_MONITOR_IMAGE_URI_WITH_PLACEHOLDERS = (
4538
"{}.dkr.ecr.{}.amazonaws.com/sagemaker-model-monitor-analyzer"
@@ -331,7 +324,7 @@ def create_monitoring_schedule(
331324
max_runtime_in_seconds=self.max_runtime_in_seconds,
332325
environment=self.env,
333326
network_config=network_config_dict,
334-
role_arn=self.role,
327+
role_arn=self.sagemaker_session.expand_role(self.role),
335328
tags=self.tags,
336329
)
337330

@@ -390,7 +383,7 @@ def update_monitoring_schedule(
390383
network_config (sagemaker.network.NetworkConfig): A NetworkConfig
391384
object that configures network isolation, encryption of
392385
inter-container traffic, security group IDs, and subnets.
393-
role (str): An AWS IAM role. The Amazon SageMaker jobs use this role.
386+
role (str): An AWS IAM role name or ARN. The Amazon SageMaker jobs use this role.
394387
image_uri (str): The uri of the image to use for the jobs started by
395388
the Monitor.
396389
@@ -478,7 +471,7 @@ def update_monitoring_schedule(
478471
max_runtime_in_seconds=max_runtime_in_seconds,
479472
environment=env,
480473
network_config=network_config_dict,
481-
role_arn=role,
474+
role_arn=self.sagemaker_session.expand_role(self.role),
482475
)
483476

484477
self._wait_for_schedule_changes_to_apply()
@@ -988,7 +981,7 @@ def __init__(
988981
creating Amazon SageMaker Monitoring Schedules to monitor SageMaker endpoints.
989982
990983
Args:
991-
role (str): An AWS IAM role. The Amazon SageMaker jobs use this role.
984+
role (str): An AWS IAM role name or ARN. The Amazon SageMaker jobs use this role.
992985
instance_count (int): The number of instances to run the jobs with.
993986
instance_type (str): Type of EC2 instance to use for the job, for example,
994987
'ml.m5.xlarge'.
@@ -1292,7 +1285,7 @@ def create_monitoring_schedule(
12921285
max_runtime_in_seconds=self.max_runtime_in_seconds,
12931286
environment=normalized_env,
12941287
network_config=network_config_dict,
1295-
role_arn=self.role,
1288+
role_arn=self.sagemaker_session.expand_role(self.role),
12961289
tags=self.tags,
12971290
)
12981291

@@ -1355,7 +1348,7 @@ def update_monitoring_schedule(
13551348
inter-container traffic, security group IDs, and subnets.
13561349
enable_cloudwatch_metrics (bool): Whether to publish cloudwatch metrics as part of
13571350
the baselining or monitoring jobs.
1358-
role (str): An AWS IAM role. The Amazon SageMaker jobs use this role.
1351+
role (str): An AWS IAM role name or ARN. The Amazon SageMaker jobs use this role.
13591352
13601353
"""
13611354
monitoring_inputs = None
@@ -1449,7 +1442,7 @@ def update_monitoring_schedule(
14491442
max_runtime_in_seconds=max_runtime_in_seconds,
14501443
environment=normalized_env,
14511444
network_config=network_config_dict,
1452-
role_arn=role,
1445+
role_arn=self.sagemaker_session.expand_role(self.role),
14531446
)
14541447

14551448
self._wait_for_schedule_changes_to_apply()

src/sagemaker/processing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(
5252
SageMaker processing tasks.
5353
5454
Args:
55-
role (str): An AWS IAM role. The Amazon SageMaker training jobs
55+
role (str): An AWS IAM role name or ARN. The Amazon SageMaker training jobs
5656
and APIs that create Amazon SageMaker endpoints use this role
5757
to access training data and model artifacts. After the endpoint
5858
is created, the inference code might use the IAM role, if it
@@ -281,7 +281,7 @@ def __init__(
281281
handles Amazon SageMaker processing tasks for jobs using script mode.
282282
283283
Args:
284-
role (str): An AWS IAM role. The Amazon SageMaker training jobs
284+
role (str): An AWS IAM role name or ARN. The Amazon SageMaker training jobs
285285
and APIs that create Amazon SageMaker endpoints use this role
286286
to access training data and model artifacts. After the endpoint
287287
is created, the inference code might use the IAM role, if it
@@ -538,7 +538,7 @@ def start_new(cls, processor, inputs, outputs, experiment_config):
538538
else:
539539
process_request_args["network_config"] = None
540540

541-
process_request_args["role_arn"] = processor.role
541+
process_request_args["role_arn"] = processor.sagemaker_session.expand_role(processor.role)
542542

543543
process_request_args["tags"] = processor.tags
544544

src/sagemaker/sklearn/processing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __init__(
4848
4949
Args:
5050
framework_version (str): The version of scikit-learn.
51-
role (str): An AWS IAM role. The Amazon SageMaker training jobs
51+
role (str): An AWS IAM role name or ARN. The Amazon SageMaker training jobs
5252
and APIs that create Amazon SageMaker endpoints use this role
5353
to access training data and model artifacts. After the endpoint
5454
is created, the inference code might use the IAM role, if it

tests/integ/test_auto_ml.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from tests.integ import DATA_DIR, AUTO_ML_DEFAULT_TIMEMOUT_MINUTES, auto_ml_utils
2525
from tests.integ.timeout import timeout
2626

27-
DEV_ACCOUNT = 142577830533
2827
ROLE = "SageMakerRole"
2928
PREFIX = "sagemaker/beta-automl-xgboost"
3029
HOSTING_INSTANCE_TYPE = "ml.c4.xlarge"
@@ -41,26 +40,10 @@
4140
# use a succeeded AutoML job to test describe and list candidates method, otherwise tests will run too long
4241
AUTO_ML_JOB_NAME = "python-sdk-integ-test-base-job"
4342

44-
EXPECTED_DEFAULT_INPUT_CONFIG = [
45-
{
46-
"DataSource": {
47-
"S3DataSource": {
48-
"S3DataType": "S3Prefix",
49-
"S3Uri": "s3://sagemaker-us-east-2-{}/{}/input/iris_training.csv".format(
50-
DEV_ACCOUNT, PREFIX
51-
),
52-
}
53-
},
54-
"TargetAttributeName": TARGET_ATTRIBUTE_NAME,
55-
}
56-
]
5743
EXPECTED_DEFAULT_JOB_CONFIG = {
5844
"CompletionCriteria": {"MaxCandidates": 3},
5945
"SecurityConfig": {"EnableInterContainerTrafficEncryption": False},
6046
}
61-
EXPECTED_DEFAULT_OUTPUT_CONFIG = {
62-
"S3OutputPath": "s3://sagemaker-us-east-2-{}/".format(DEV_ACCOUNT)
63-
}
6447

6548

6649
@pytest.mark.skipif(
@@ -119,7 +102,7 @@ def test_auto_ml_input_object_fit(sagemaker_session):
119102
reason="AutoML is not supported in the region yet.",
120103
)
121104
def test_auto_ml_fit_optional_args(sagemaker_session):
122-
output_path = "s3://sagemaker-us-east-2-{}/{}".format(DEV_ACCOUNT, "specified_ouput_path")
105+
output_path = "s3://{}/{}".format(sagemaker_session.default_bucket(), "specified_ouput_path")
123106
problem_type = "MulticlassClassification"
124107
job_objective = {"MetricName": "Accuracy"}
125108
auto_ml = AutoML(
@@ -163,8 +146,24 @@ def test_auto_ml_invalid_target_attribute(sagemaker_session):
163146
reason="AutoML is not supported in the region yet.",
164147
)
165148
def test_auto_ml_describe_auto_ml_job(sagemaker_session):
166-
auto_ml_utils.create_auto_ml_job_if_not_exist(sagemaker_session)
149+
expected_default_input_config = [
150+
{
151+
"DataSource": {
152+
"S3DataSource": {
153+
"S3DataType": "S3Prefix",
154+
"S3Uri": "s3://{}/{}/input/iris_training.csv".format(
155+
sagemaker_session.default_bucket(), PREFIX
156+
),
157+
}
158+
},
159+
"TargetAttributeName": TARGET_ATTRIBUTE_NAME,
160+
}
161+
]
162+
expected_default_output_config = {
163+
"S3OutputPath": "s3://{}/".format(sagemaker_session.default_bucket())
164+
}
167165

166+
auto_ml_utils.create_auto_ml_job_if_not_exist(sagemaker_session)
168167
auto_ml = AutoML(
169168
role=ROLE, target_attribute_name=TARGET_ATTRIBUTE_NAME, sagemaker_session=sagemaker_session
170169
)
@@ -173,9 +172,9 @@ def test_auto_ml_describe_auto_ml_job(sagemaker_session):
173172
assert desc["AutoMLJobName"] == AUTO_ML_JOB_NAME
174173
assert desc["AutoMLJobStatus"] == "Completed"
175174
assert isinstance(desc["BestCandidate"], dict)
176-
assert desc["InputDataConfig"] == EXPECTED_DEFAULT_INPUT_CONFIG
175+
assert desc["InputDataConfig"] == expected_default_input_config
177176
assert desc["AutoMLJobConfig"] == EXPECTED_DEFAULT_JOB_CONFIG
178-
assert desc["OutputDataConfig"] == EXPECTED_DEFAULT_OUTPUT_CONFIG
177+
assert desc["OutputDataConfig"] == expected_default_output_config
179178

180179

181180
@pytest.mark.skipif(

tests/integ/test_data_capture_config.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,17 @@
1717
import sagemaker
1818
import tests.integ
1919
import tests.integ.timeout
20-
21-
from tests.integ.retry import retries
22-
from sagemaker.model_monitor import NetworkConfig
23-
24-
from sagemaker.model_monitor import DataCaptureConfig
20+
from sagemaker.model_monitor import DataCaptureConfig, NetworkConfig
2521
from sagemaker.tensorflow.serving import Model
2622
from sagemaker.utils import unique_name_from_base
23+
from tests.integ.retry import retries
2724

2825
ROLE = "SageMakerRole"
29-
REGION = "us-west-2"
3026
SKLEARN_FRAMEWORK = "scikit-learn"
3127

3228
INSTANCE_COUNT = 1
3329
INSTANCE_TYPE = "ml.m5.xlarge"
3430
VOLUME_SIZE_IN_GB = 20
35-
VOLUME_KMS_KEY = "arn:aws:kms:us-west-2:012345678901:key/volume-kms-key"
36-
OUTPUT_KMS_KEY = "arn:aws:kms:us-west-2:012345678901:key/output-kms-key"
3731
MAX_RUNTIME_IN_SECONDS = 2 * 60 * 60
3832
ENVIRONMENT = {"env_key_1": "env_value_1"}
3933
TAGS = [{"Key": "tag_key_1", "Value": "tag_value_1"}]

tests/integ/test_model_monitor.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from tests.integ.kms_utils import get_or_create_kms_key
4343
from tests.integ.retry import retries
4444

45-
ROLE = "arn:aws:iam::142577830533:role/SageMakerRole"
45+
ROLE = "SageMakerRole"
4646
INSTANCE_COUNT = 1
4747
INSTANCE_TYPE = "ml.m5.xlarge"
4848
VOLUME_SIZE_IN_GB = 40
@@ -63,7 +63,7 @@
6363
DEFAULT_EXECUTION_MAX_RUNTIME_IN_SECONDS = 3600
6464
DEFAULT_IMAGE_SUFFIX = ".com/sagemaker-model-monitor-analyzer"
6565

66-
UPDATED_ROLE = "arn:aws:iam::142577830533:role/SageMakerRole"
66+
UPDATED_ROLE = "SageMakerRole"
6767
UPDATED_INSTANCE_COUNT = 2
6868
UPDATED_INSTANCE_TYPE = "ml.m5.2xlarge"
6969
UPDATED_VOLUME_SIZE_IN_GB = 50
@@ -99,7 +99,7 @@ def predictor(sagemaker_session, tf_full_version):
9999
):
100100
model = Model(
101101
model_data=model_data,
102-
role="SageMakerRole",
102+
role=ROLE,
103103
framework_version=tf_full_version,
104104
sagemaker_session=sagemaker_session,
105105
)
@@ -220,9 +220,10 @@ def byoc_monitoring_schedule_name(sagemaker_session, output_kms_key, volume_kms_
220220

221221
@pytest.fixture(scope="module")
222222
def volume_kms_key(sagemaker_session):
223+
role_arn = sagemaker_session.expand_role(ROLE)
223224
return get_or_create_kms_key(
224225
sagemaker_session=sagemaker_session,
225-
role_arn=ROLE,
226+
role_arn=role_arn,
226227
alias="integ-test-processing-volume-kms-key-{}".format(
227228
sagemaker_session.boto_session.region_name
228229
),
@@ -231,9 +232,10 @@ def volume_kms_key(sagemaker_session):
231232

232233
@pytest.fixture(scope="module")
233234
def output_kms_key(sagemaker_session):
235+
role_arn = sagemaker_session.expand_role(ROLE)
234236
return get_or_create_kms_key(
235237
sagemaker_session=sagemaker_session,
236-
role_arn=ROLE,
238+
role_arn=role_arn,
237239
alias="integ-test-processing-output-kms-key-{}".format(
238240
sagemaker_session.boto_session.region_name
239241
),
@@ -242,9 +244,10 @@ def output_kms_key(sagemaker_session):
242244

243245
@pytest.fixture(scope="module")
244246
def updated_volume_kms_key(sagemaker_session):
247+
role_arn = sagemaker_session.expand_role(ROLE)
245248
return get_or_create_kms_key(
246249
sagemaker_session=sagemaker_session,
247-
role_arn=ROLE,
250+
role_arn=role_arn,
248251
alias="integ-test-processing-volume-kms-key-updated-{}".format(
249252
sagemaker_session.boto_session.region_name
250253
),
@@ -253,9 +256,10 @@ def updated_volume_kms_key(sagemaker_session):
253256

254257
@pytest.fixture(scope="module")
255258
def updated_output_kms_key(sagemaker_session):
259+
role_arn = sagemaker_session.expand_role(ROLE)
256260
return get_or_create_kms_key(
257261
sagemaker_session=sagemaker_session,
258-
role_arn=ROLE,
262+
role_arn=role_arn,
259263
alias="integ-test-processing-output-kms-key-updated-{}".format(
260264
sagemaker_session.boto_session.region_name
261265
),
@@ -315,7 +319,7 @@ def test_default_monitor_suggest_baseline_and_create_monitoring_schedule_with_cu
315319
== volume_kms_key
316320
)
317321
assert DEFAULT_IMAGE_SUFFIX in baselining_job_description["AppSpecification"]["ImageUri"]
318-
assert baselining_job_description["RoleArn"] == ROLE
322+
assert ROLE in baselining_job_description["RoleArn"]
319323
assert (
320324
baselining_job_description["ProcessingInputs"][0]["InputName"] == "baseline_dataset_input"
321325
)
@@ -492,7 +496,7 @@ def test_default_monitor_suggest_baseline_and_create_monitoring_schedule_without
492496
is None
493497
)
494498
assert DEFAULT_IMAGE_SUFFIX in baselining_job_description["AppSpecification"]["ImageUri"]
495-
assert baselining_job_description["RoleArn"] == ROLE
499+
assert ROLE in baselining_job_description["RoleArn"]
496500
assert (
497501
baselining_job_description["ProcessingInputs"][0]["InputName"] == "baseline_dataset_input"
498502
)
@@ -1524,7 +1528,7 @@ def test_byoc_monitor_suggest_baseline_and_create_monitoring_schedule_with_custo
15241528
== volume_kms_key
15251529
)
15261530
assert DEFAULT_IMAGE_SUFFIX in baselining_job_description["AppSpecification"]["ImageUri"]
1527-
assert baselining_job_description["RoleArn"] == ROLE
1531+
assert ROLE in baselining_job_description["RoleArn"]
15281532
assert baselining_job_description["ProcessingInputs"][0]["InputName"] == "input-1"
15291533
assert (
15301534
baselining_job_description["ProcessingOutputConfig"]["Outputs"][0]["OutputName"]
@@ -1723,7 +1727,7 @@ def test_byoc_monitor_suggest_baseline_and_create_monitoring_schedule_without_cu
17231727
is None
17241728
)
17251729
assert DEFAULT_IMAGE_SUFFIX in baselining_job_description["AppSpecification"]["ImageUri"]
1726-
assert baselining_job_description["RoleArn"] == ROLE
1730+
assert ROLE in baselining_job_description["RoleArn"]
17271731
assert baselining_job_description["ProcessingInputs"][0]["InputName"] == "input-1"
17281732
assert (
17291733
baselining_job_description["ProcessingOutputConfig"]["Outputs"][0]["OutputName"]
@@ -2181,7 +2185,7 @@ def test_byoc_monitor_attach_followed_by_baseline_and_update_monitoring_schedule
21812185
== volume_kms_key
21822186
)
21832187
assert DEFAULT_IMAGE_SUFFIX in baselining_job_description["AppSpecification"]["ImageUri"]
2184-
assert baselining_job_description["RoleArn"] == ROLE
2188+
assert ROLE in baselining_job_description["RoleArn"]
21852189
assert baselining_job_description["ProcessingInputs"][0]["InputName"] == "input-1"
21862190
assert (
21872191
baselining_job_description["ProcessingOutputConfig"]["Outputs"][0]["OutputName"]

tests/integ/test_monitoring_files.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,10 @@
1919

2020
import tests.integ
2121
import tests.integ.timeout
22-
2322
from sagemaker.model_monitor import Statistics, Constraints, ConstraintViolations
2423
from sagemaker.s3 import S3Uploader
2524
from tests.integ.kms_utils import get_or_create_kms_key
2625

27-
ROLE = "arn:aws:iam::142577830533:role/SageMakerRole"
28-
2926

3027
@pytest.fixture(scope="module")
3128
def monitoring_files_kms_key(sagemaker_session):
@@ -40,7 +37,7 @@ def test_statistics_object_creation_from_file_path_with_customizations(
4037
kms_key=monitoring_files_kms_key,
4138
sagemaker_session=sagemaker_session,
4239
)
43-
#
40+
4441
assert statistics.file_s3_uri.startswith("s3://")
4542
assert statistics.file_s3_uri.endswith("statistics.json")
4643

0 commit comments

Comments
 (0)