$npx -y skills add huggingface/skills --skill hf-cloud-sagemaker-iam-preflightEnsure a usable SageMaker execution role exists before deploying or training. Use this skill whenever about to create a SageMaker endpoint, model, training job, or any resource that requires an execution role. Use it especially when the user has not provided a role ARN explicitly
| 1 | # SageMaker IAM Preflight |
| 2 | |
| 3 | Every SageMaker resource needs an **execution role** — the IAM role SageMaker assumes to read model artifacts from S3, pull serving containers from ECR, and write logs. Most deployments fail here because the script tried to create a new role without checking if a usable one already existed, then blew up because the caller is an SSO principal. |
| 4 | |
| 5 | This skill encodes the right order: discover, validate, only create if necessary. |
| 6 | |
| 7 | ## Running the helpers (cross-platform) |
| 8 | |
| 9 | The helpers are Python so they run identically on Windows, macOS, and Linux: |
| 10 | |
| 11 | ```bash |
| 12 | python3 scripts/check_role.py # macOS / Linux |
| 13 | python scripts/check_role.py # Windows (PowerShell / cmd) |
| 14 | ``` |
| 15 | |
| 16 | **Run them from the shell where the AWS CLI already works** — i.e. wherever `aws sts get-caller-identity` succeeds. The script shells out to that same `aws` binary and inherits the shell's profile, region, SSO session, proxy, and credential chain. |
| 17 | |
| 18 | > **Windows / WSL / Git Bash caveat.** Do **not** invoke these through a Bash shim (WSL, Git Bash, MSYS) on Windows. Those Bash environments frequently do **not** share the Windows AWS config, credentials, SSO sessions, environment variables, or proxy settings — so `aws sts get-caller-identity` fails inside Bash even when it works natively in PowerShell. (This is exactly why the old `.sh` helpers failed on Windows and were replaced with Python.) If you're in PowerShell, run `python ...\check_role.py` directly in PowerShell. If the helper still can't see your identity, run the same discovery natively (see "Native AWS CLI equivalent" below) in the shell where `aws sts get-caller-identity` returns your ARN. |
| 19 | |
| 20 | ## Order of operations |
| 21 | |
| 22 | ### Step 1 — Did the user provide a role? |
| 23 | |
| 24 | Validate that one specifically: |
| 25 | |
| 26 | ```bash |
| 27 | python3 scripts/check_role.py "<role-name-or-arn>" |
| 28 | ``` |
| 29 | |
| 30 | On success it prints the ARN to stdout (exit 0). On failure it logs why on stderr. Don't try to silently fix a broken role — surface the problem. |
| 31 | |
| 32 | ### Step 2 — Discover existing roles |
| 33 | |
| 34 | ```bash |
| 35 | python3 scripts/check_role.py |
| 36 | ``` |
| 37 | |
| 38 | Lists roles matching common SageMaker patterns (`AmazonSageMaker-ExecutionRole-*`, `SageMakerExecutionRole*`, etc.), **ranks by last-used date** (most recent first), validates trust policy in that order, returns the first usable ARN. Most accounts that have used SageMaker before already have one. |
| 39 | |
| 40 | Why rank by last-used: in accounts with multiple roles (auto-generated 2021 role + manual project role + etc.), the alphabetically-first one is rarely the actively-maintained one. The most-recently-used role is more likely to have current policies — including cross-account ECR pull. The script prints the ranking so you can see which got picked. |
| 41 | |
| 42 | IAM frequently reports **no** `RoleLastUsed` at all (tracking only covers recent activity). When every candidate ties at "never used", the script falls back to **newest creation date** — a newer role is more likely to have current policies than a 2021 leftover. |
| 43 | |
| 44 | ### Step 3 — Create, only if discovery found nothing |
| 45 | |
| 46 | **If the user can create** (has IAM permissions): |
| 47 | |
| 48 | ```bash |
| 49 | python3 scripts/create_role.py "<role-name>" "<model-bucket>" |
| 50 | ``` |
| 51 | |
| 52 | Second arg scopes S3 access to a specific bucket. Omit if unknown; script warns and the user can update the policy later. |
| 53 | |
| 54 | **If the user cannot create** (SSO principal — `hf-cloud-aws-context-discovery` will have flagged this): |
| 55 | |
| 56 | Stop and surface this clearly. Don't retry alternative IAM operations hoping one works: |
| 57 | |
| 58 | > I can't find an existing SageMaker execution role, and you're authenticated via SSO so you can't create one directly. Please either: |
| 59 | > - Ask your AWS admin for a SageMaker execution role ARN, or |
| 60 | > - Have them grant your SSO permission set `iam:CreateRole`, `iam:AttachRolePolicy`, `iam:PutRolePolicy` |
| 61 | |
| 62 | Specific instructions get unblocked fast; vague "permission denied" messages don't. |
| 63 | |
| 64 | ## What "validated" means |
| 65 | |
| 66 | A role is usable when (1) it exists, (2) its trust policy allows `sagemaker.amazonaws.com` to `sts:AssumeRole` — see `references/trust-policy.json` for the canonical form. |
| 67 | |
| 68 | `check_role.py` verifies these two. It does **not** deep-check permissions because comprehensive analysis is expensive (`iam:SimulatePrincipalPolicy` per action) and most existing SageMaker roles are over-permissioned via `AmazonSageMakerFullAccess`. If you |