How to Assign an IAM Role to an EC2 Instance Using AWS CLI: A Complete Guide


1 views

When launching EC2 instances programmatically through AWS CLI, specifying IAM roles presents unique permission challenges that differ from the AWS Management Console experience. The key issue stems from the fact that IAM role assignment isn't simply metadata attachment - it's an explicit permission grant requiring higher privileges.

The AccessDenied error when running aws iam list-instance-profiles indicates missing IAM read permissions. The UnauthorizedOperation error during instance launch suggests insufficient permissions to associate IAM roles with EC2 instances.


# Common error patterns:
1. AccessDenied: iam:ListInstanceProfiles
2. UnauthorizedOperation: AssociateIamInstanceProfile

To successfully launch instances with IAM roles via CLI, your executing principal needs:

  • iam:ListInstanceProfiles - For role discovery
  • ec2:RunInstances - Basic instance launch
  • iam:PassRole - For role association

The correct run-instances command format with IAM role specification:


aws ec2 run-instances \
    --image-id ami-0abcdef1234567890 \
    --instance-type t3.micro \
    --iam-instance-profile Name="YourRoleName" \
    --key-name MyKeyPair

First, verify your available instance profiles:


aws iam list-instance-profiles --query 'InstanceProfiles[*].{Name:InstanceProfileName}'

Then create a minimal IAM policy for the launching user/role:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances",
                "iam:PassRole"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:ListInstanceProfiles",
            "Resource": "*"
        }
    ]
}
  • Ensure your CLI credentials have sufficient permissions (AdministratorAccess or custom equivalent)
  • Verify the IAM role exists in the same region where you're launching instances
  • Check for service-linked roles that might interfere with permission propagation

For automation scenarios, consider using AWS CloudFormation or Terraform which provide more robust IAM role handling:


# CloudFormation snippet
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: YourInstanceProfile
      ImageId: ami-0abcdef1234567890
      InstanceType: t3.micro

When launching EC2 instances programmatically, assigning IAM roles often triggers permission errors even when the roles work perfectly through the AWS Console. The root cause typically involves missing IAM permissions rather than incorrect CLI syntax.

An IAM role for EC2 requires an instance profile as its container. The correct CLI syntax requires either:

--iam-instance-profile Arn=arn:aws:iam::123456789012:instance-profile/YourRoleName
--iam-instance-profile Name=YourRoleName

Your executing identity needs these minimum permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:PassRole",
        "iam:ListInstanceProfiles"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "*"
    }
  ]
}

Scenario 1: Getting "AccessDenied" on ListInstanceProfiles
This indicates missing iam:ListInstanceProfiles permission. Either add it or specify the ARN directly.

Scenario 2: "UnauthorizedOperation" when passing roles
The executing identity lacks iam:PassRole permission for the target role.

For a role named "S3AccessRole":

aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t2.micro \
  --iam-instance-profile Name=S3AccessRole \
  --key-name MyKeyPair \
  --security-group-ids sg-903004f8 \
  --subnet-id subnet-6e7f829e

When working across accounts, include the external account ID in the trust policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::EXTERNAL_ACCOUNT_ID:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
  • Always follow least-privilege principle
  • Use instance profiles instead of embedding credentials
  • Regularly audit IAM policies with AWS Access Analyzer