Live
OpenTelemetry tracing expands across Cloudflare’s proxy stack in betaDynamic Model Triage: Engineering Implications of Grok Bot’s Multi‑Model BackendAccess Cloudflare Skills Directly Through the API MCP ServerCodeQL 2.27.2 expands language models and tightens macOS build support – what engineers need to knowTangible Certification: Turning a Kubernetes Badge into a Gold NecklaceGoogle Data Cloud GA updates: agent‑centric tooling, hybrid Spanner, and expanded Lakehouse catalogCloudflare folds Deno runtime into Workers: practical impact on serverless deploymentsManaging Copilot Code Review Costs and License Scope with New Org‑Level ControlsOpenTelemetry tracing expands across Cloudflare’s proxy stack in betaDynamic Model Triage: Engineering Implications of Grok Bot’s Multi‑Model BackendAccess Cloudflare Skills Directly Through the API MCP ServerCodeQL 2.27.2 expands language models and tightens macOS build support – what engineers need to knowTangible Certification: Turning a Kubernetes Badge into a Gold NecklaceGoogle Data Cloud GA updates: agent‑centric tooling, hybrid Spanner, and expanded Lakehouse catalogCloudflare folds Deno runtime into Workers: practical impact on serverless deploymentsManaging Copilot Code Review Costs and License Scope with New Org‑Level Controls
AWS

AWS IAM Explained: Users, Roles, Policies and Best Practices

Overview

This tutorial covers the core components of AWS Identity and Access Management (IAM): users, groups, roles, and policies. You will learn how to create and manage IAM identities using the AWS CLI, write least-privilege IAM policies in JSON, attach roles to EC2 instances, and apply security best practices that AWS expects in production environments.

Prerequisites:

  • An active AWS account with administrator access
  • AWS CLI v2 installed and configured (aws configure)
  • Basic understanding of JSON syntax
  • Familiarity with Linux/bash terminal

Why this matters for SAA-C03: IAM is tested heavily across every domain of the Solutions Architect Associate exam. Expect scenario-based questions on cross-account access, role delegation, policy evaluation logic, and the principle of least privilege. Understanding IAM deeply separates passing candidates from those who memorize and forget.

Getting Started

Before writing any policies, verify your CLI is configured and you can reach IAM endpoints:

# Verify CLI identity
aws sts get-caller-identity

# List existing IAM users
aws iam list-users --output table

# List existing IAM roles
aws iam list-roles --query 'Roles[*].[RoleName,Arn]' --output table

Create a dedicated IAM user for this tutorial so you are not working as root:

# Create a new IAM user
aws iam create-user --user-name ninja-dev

# Create programmatic access keys for the user
aws iam create-access-key --user-name ninja-dev

# Create a login profile for console access
aws iam create-login-profile \
  --user-name ninja-dev \
  --password 'TempP@ss2024!' \
  --password-reset-required

Important: Store the SecretAccessKey returned by create-access-key immediately — AWS will never show it again.

IAM Users, Groups, and Policies

IAM Users represent individual humans or applications that need long-term credentials. IAM Groups are collections of users that share the same permissions — always assign permissions to groups, not individual users.

# Create a developer group
aws iam create-group --group-name Developers

# Add the user to the group
aws iam add-user-to-group \
  --user-name ninja-dev \
  --group-name Developers

# Verify group membership
aws iam get-group --group-name Developers

IAM Policies are JSON documents that define what actions are allowed or denied on which resources. Save the following as s3-read-policy.json:

cat > s3-read-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3ReadOnly",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-ninja-bucket",
        "arn:aws:s3:::my-ninja-bucket/*"
      ]
    }
  ]
}
EOF

# Create the managed policy
aws iam create-policy \
  --policy-name S3NinjaBucketReadOnly \
  --policy-document file://s3-read-policy.json

# Attach policy to the Developers group
aws iam attach-group-policy \
  --group-name Developers \
  --policy-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):policy/S3NinjaBucketReadOnly

Common Pitfall: Using "Resource": "*" in policies is a frequent security mistake. Always scope resources to the minimum required ARN. Also remember that an explicit Deny always overrides any Allow — this is the core of IAM policy evaluation logic.

IAM Roles and Cross-Service Access

IAM Roles are the preferred way to grant permissions to AWS services, applications, and cross-account access. Unlike users, roles do not have long-term credentials — they issue temporary security tokens via AWS STS (Security Token Service).

Create a role that allows EC2 instances to read from S3:

# Create the trust policy (who can assume this role)
cat > ec2-trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# Create the IAM role
aws iam create-role \
  --role-name EC2S3ReadRole \
  --assume-role-policy-document file://ec2-trust-policy.json \
  --description "Allows EC2 instances to read S3 buckets"

# Attach the S3 read policy to the role
aws iam attach-role-policy \
  --role-name EC2S3ReadRole \
  --policy-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):policy/S3NinjaBucketReadOnly

# Create an instance profile and attach the role
aws iam create-instance-profile \
  --instance-profile-name EC2S3ReadProfile

aws iam add-role-to-instance-profile \
  --instance-profile-name EC2S3ReadProfile \
  --role-name EC2S3ReadRole

# Attach the instance profile to a running EC2 instance
aws ec2 associate-iam-instance-profile \
  --instance-id i-0abcd1234ef567890 \
  --iam-instance-profile Name=EC2S3ReadProfile

For cross-account role assumption, update the trust policy to allow another AWS account:

cat > cross-account-trust.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::TRUSTED_ACCOUNT_ID:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "UniqueExternalSecret42"
        }
      }
    }
  ]
}
EOF

# Assume the role from the trusted account (run from trusted account CLI)
aws sts assume-role \
  --role-arn arn:aws:iam::TARGET_ACCOUNT_ID:role/EC2S3ReadRole \
  --role-session-name CrossAccountSession \
  --external-id UniqueExternalSecret42

Best Practice: Always use an ExternalId condition when creating cross-account roles for third-party services. This prevents the confused deputy problem where an attacker tricks a trusted service into acting on their behalf.

Enable MFA enforcement for sensitive role assumptions by adding a condition to the trust policy:

"Condition": {
  "Bool": {
    "aws:MultiFactorAuthPresent": "true"
  },
  "NumericLessThan": {
    "aws:MultiFactorAuthAge": "3600"
  }
}

Exam Tips for AWS Solutions Architect Associate (SAA-C03)

Key concepts that appear on the exam:

  • Policy evaluation order: Explicit Deny > explicit Allow > implicit Deny. If no policy allows an action, it is denied by default.
  • IAM Roles vs. Users: EC2, Lambda, and other services must use roles — never embed access keys in code or AMIs.
  • Permission Boundaries: An advanced feature that sets the maximum permissions an IAM entity can have, even if attached policies grant more. Common in multi-team environments.
  • Service Control Policies (SCPs): Applied at the AWS Organizations level — they restrict what accounts can do but do not grant permissions on their own.
  • Resource-based policies: Attached directly to resources (S3 buckets, KMS keys, SQS queues). Combined with identity-based policies using logical OR for same-account, AND for cross-account.

Common exam scenarios:

  1. An EC2 instance cannot write to S3 — check that an instance profile is attached and the role has the correct policy.
  2. A Lambda function in Account A needs to read DynamoDB in Account B — create a role in Account B, add Account A as a trusted principal, and call sts:AssumeRole in the Lambda code.
  3. A developer can create IAM users but should not be able to grant admin — use a Permission Boundary to cap their maximum privilege.

Quick reference commands:

# Simulate policy evaluation before applying
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/ninja-dev \
  --action-names s3:PutObject \
  --resource-arns arn:aws:s3:::my-ninja-bucket/test.txt

# Generate a credential report for auditing
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 --decode

# Check which policies are attached to a role
aws iam list-attached-role-policies --role-name EC2S3ReadRole

# Audit inline policies (these are harder to manage — avoid them)
aws iam list-role-policies --role-name EC2S3ReadRole

Summary

Key takeaways from this tutorial:

  • Always follow the principle of least privilege — grant only the permissions required and scope resources to specific ARNs.
  • Use IAM Roles for all AWS service-to-service communication. Never use long-term access keys embedded in application code.
  • Assign permissions to IAM Groups, not individual users, to simplify access management at scale.
  • Use managed policies over inline policies for reusability and easier auditing.
  • Enforce MFA on the root account and all privileged IAM users immediately after account creation.
  • Regularly audit permissions using IAM Access Analyzer and the credential report to identify unused access and overly permissive policies.

Next steps:

  1. Explore AWS IAM Identity Center (SSO) for federated access across multiple accounts.
  2. Learn AWS Organizations and SCPs to enforce guardrails across your entire account structure.
  3. Practice writing and simulating policies in the IAM Policy Simulator in the AWS Console.
  4. Review the CloudNinjas SAA-C03 Certification Guide for full exam domain coverage.