Skip to main content
🎤 Luca Berton is speaking at Red Hat Summit & KubeCon EU 2026!Learn more →
Back to Blog

AWS IAM Roles and Policies Guide

Understand AWS IAM roles, policies, and best practices for secure cloud access. Least privilege principles, role assumption, and Terraform IAM automation.

Luca BertonMarch 6, 20262 min read

IAM (Identity and Access Management) controls who can do what in AWS. Getting it wrong means either security breaches or blocked deployments. This guide covers what DevOps engineers need.

Core Concepts

ConceptWhat It IsExample
UserA person or applicationalice, ci-bot
GroupCollection of usersdevelopers, admins
RoleTemporary credentials for services/usersec2-s3-access, lambda-execution
PolicyJSON document defining permissionsAllow S3 read on specific bucket

Rule of thumb: Use roles, not users. Users are for humans; roles are for everything else.

Policy Structure

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3Read",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "10.0.0.0/8"
        }
      }
    }
  ]
}
FieldPurpose
EffectAllow or Deny
ActionAWS API actions (e.g., s3:GetObject)
ResourceARNs of resources this applies to
ConditionOptional: IP, time, MFA, tags
Related Course

Master this topic with hands-on labs

Go beyond reading — build real projects in sandboxed environments with expert video guidance.

Browse Courses →

Least Privilege Principle

Start with zero permissions, add only what is needed:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "ecr:BatchCheckLayerAvailability"
      ],
      "Resource": "arn:aws:ecr:eu-west-1:123456789:repository/my-app"
    },
    {
      "Effect": "Allow",
      "Action": "ecr:GetAuthorizationToken",
      "Resource": "*"
    }
  ]
}

This CI role can only pull images from one specific ECR repository.

Common Role Patterns

EC2 Instance Role

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::app-assets/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:eu-west-1:123456789:secret:app/*"
    }
  ]
}

CI/CD Role (GitHub Actions OIDC)

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "ecr:PutImage",
        "ecr:InitiateLayerUpload",
        "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "eks:DescribeCluster",
        "eks:ListClusters"
      ],
      "Resource": "arn:aws:eks:eu-west-1:123456789:cluster/production"
    }
  ]
}

Trust policy (allow GitHub Actions to assume the role):

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}

Terraform IAM

hcl
# Role
resource "aws_iam_role" "app" {
  name = "app-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
    }]
  })
}

# Policy
resource "aws_iam_role_policy" "app_s3" {
  name = "app-s3-access"
  role = aws_iam_role.app.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = ["s3:GetObject", "s3:PutObject"]
      Resource = "${aws_s3_bucket.assets.arn}/*"
    }]
  })
}

# Instance profile
resource "aws_iam_instance_profile" "app" {
  name = "app-profile"
  role = aws_iam_role.app.name
}
Stay Updated

Get weekly IT automation tips

Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.

Subscribe Free →

IAM Best Practices

PracticeWhy
Use roles, not access keysKeys can leak; roles are temporary
Enable MFA for humansPrevents credential theft
Use OIDC for CI/CDNo long-lived credentials
Tag everythingTrack who created what
Review with IAM Access AnalyzerFind overly permissive policies
Use permission boundariesLimit what roles can grant
Separate accounts per environmentBlast radius reduction

Debugging IAM

bash
# Who am I?
aws sts get-caller-identity

# Simulate a policy
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789:role/app-role \
  --action-names s3:GetObject \
  --resource-arns arn:aws:s3:::my-bucket/file.txt

# Check recent access
aws iam generate-service-last-accessed-details \
  --arn arn:aws:iam::123456789:role/app-role

What's Next?

Our Terraform for Beginners course covers AWS IAM automation with Terraform across 15 hands-on lessons. First lesson is free. -e ---

Ready to go deeper? Explore our hands-on DevOps courses — practical labs covering Docker, Ansible, Terraform, and more.

Ready to learn by doing?

Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.

Share this article
LB
Luca Berton

Docker Captain, IT automation expert, Red Hat Summit & KubeCon speaker. Building hands-on education for DevOps engineers at CopyPasteLearn.

Related Articles

Explore topics

Browse more articles on the topics covered here.