Setting the file. One moment.
Create Role · Hf Cloud Sagemaker IAM Preflight · huggingface/skills · Skills Docs
ContentsBack to the top of the page scripts/create_role.py
scripts/ create_role.py
Python · 124 lines · 4 KB
python create_role.py <role-name> [<model-s3-bucket>]
17
18 Without bucket, the inline policy keeps a placeholder for later editing.
19 """
20
21 from __future__ import annotations
22
23 import json
24 import shutil
25 import subprocess
26 import sys
27 from pathlib import Path
28
29 REFERENCES = Path( __file__ ).resolve().parent.parent / "references"
30 TRUST_POLICY = REFERENCES / "trust-policy.json"
31 PERMISSIONS_TEMPLATE = REFERENCES / "minimum-permissions.json"
32
33 FULL_ACCESS_ARN = "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess"
34
35
36 def log (msg: str ) -> None :
37 print ( f "[create_role] { msg } " , file = sys.stderr, flush = True )
38
39
40 def aws_bin () -> str :
41 exe = shutil.which( "aws" )
42 if not exe:
43 log( "ERROR: the 'aws' CLI was not found on PATH. Install AWS CLI v2." )
44 sys.exit( 2 )
45 return exe
46
47
48 def run_aws (args: list[ str ], check: bool = False ) -> subprocess.CompletedProcess:
49 proc = subprocess.run([aws_bin(), * args], capture_output = True , text = True )
50 if check and proc.returncode != 0 :
51 log( f "AWS command failed: aws { ' ' .join(args) } " )
52 if proc.stderr.strip():
53 log(proc.stderr.strip())
54 sys.exit( 1 )
55 return proc
56
57
58 def main () -> int :
59 if len (sys.argv) < 2 :
60 log( f "Usage: { Path(sys.argv[ 0 ]).name } <role-name> [<model-s3-bucket>]" )
61 return 64
62
63 role_name = sys.argv[ 1 ]
64 model_bucket = sys.argv[ 2 ] if len (sys.argv) > 2 else ""
65
66 if run_aws([ "iam" , "get-role" , "--role-name" , role_name]).returncode == 0 :
67 log( f "Role ' { role_name } ' already exists. Use check_role.py to validate it." )
68 return 1
69
70 ident = run_aws([ "sts" , "get-caller-identity" , "--query" , "Arn" , "--output" , "text" ], check = True )
71 caller_arn = ident.stdout.strip()
72 if ":assumed-role/AWSReservedSSO_" in caller_arn:
73 log( f "WARNING: SSO caller ( { caller_arn } ) — IAM creation likely to fail with AccessDenied." )
74 log( "If it does, ask an AWS admin to create the role." )
75
76 trust_doc = TRUST_POLICY .read_text( encoding = "utf-8" )
77
78 log( f "Creating role: { role_name } " )
79 run_aws(
80 [
81 "iam" , "create-role" ,
82 "--role-name" , role_name,
83 "--assume-role-policy-document" , trust_doc,
84 "--description" , "SageMaker execution role (hf-cloud-sagemaker-iam-preflight skill)" ,
85 ],
86 check = True ,
87 )
88
89 log( "Attaching AmazonSageMakerFullAccess" )
90 run_aws(
91 [ "iam" , "attach-role-policy" , "--role-name" , role_name, "--policy-arn" , FULL_ACCESS_ARN ],
92 check = True ,
93 )
94
95 inline_policy = PERMISSIONS_TEMPLATE .read_text( encoding = "utf-8" )
96 if model_bucket:
97 inline_policy = inline_policy.replace( "REPLACE_WITH_MODEL_BUCKET" , model_bucket)
98 log( f "Inline policy will grant S3 access to: { model_bucket } " )
99 else :
100 log( "WARNING: No model bucket specified — policy contains placeholder." )
101 log( "Update before deployment, or pass the bucket name as the 2nd argument." )
102
103 log( "Attaching inline policy: SageMakerDeploymentMinimum" )
104 run_aws(
105 [
106 "iam" , "put-role-policy" ,
107 "--role-name" , role_name,
108 "--policy-name" , "SageMakerDeploymentMinimum" ,
109 "--policy-document" , inline_policy,
110 ],
111 check = True ,
112 )
113
114 arn = run_aws(
115 [ "iam" , "get-role" , "--role-name" , role_name, "--query" , "Role.Arn" , "--output" , "text" ],
116 check = True ,
117 ).stdout.strip()
118 log( f "Created: { arn } " )
119 print (arn)
120 return 0
121
122
123 if __name__ == "__main__" :
124 sys.exit(main())