Skip to content

Create an AWS EC2 instance with the AWS CLI - Step 2 - Attach Instance Role

Make sure you do this setup first:

  1. Setup macOS for AWS Cloud DevOps
  2. AWS Authentication

Steps:

  1. Launch an AWS EC2 instance. Make sure you do this first.
  2. Attach an instance role to allow S3 access (this post)
  3. Cleanup

Scripts are bash

Setup

Names

Assign resource names:

# instance
instance="instance-ec2"

# SSH access key
key="aws-ec2-key"

# instance role
instance_role="$instance-role"

# instance profile
instance_profile="$instance-profile"

Create temp dir

mkdir -p ~/temp
cd ~/temp

Create role

First check if the instance already has an IAM role attached

instance_id=$(aws ec2 describe-instances --filters Name=tag:Name,Values=$instance | jq -r '.Reservations[-1].Instances[-1].InstanceId')

aws ec2 describe-iam-instance-profile-associations --filters "Name=instance-id,Values=$instance_id"

Create a new IAM role

First create the "assume role" policy document:

cat << EOF > trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
Next create the role:

aws iam create-role --role-name $instance_role --assume-role-policy-document file://trust-policy.json

Next attach permission policies:

# attach the S3 full access policy to the role
aws iam attach-role-policy --role-name $instance_role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

Create an instance profile

Create an instance profile and add the role to it:

aws iam create-instance-profile --instance-profile-name $instance_profile
aws iam add-role-to-instance-profile --instance-profile-name $instance_profile --role-name $instance_role

Attach / Replace Instance profile

Attach the new role to the instance (or replace the existing one):

instance_id=$(aws ec2 describe-instances --filters Name=tag:Name,Values=$instance | jq -r '.Reservations[-1].Instances[-1].InstanceId')

# if there's no existing role
aws ec2 associate-iam-instance-profile --instance-id $instance_id --iam-instance-profile Name=$instance_profile

# ff there's an existing role you want to replace
iip_association=$(aws ec2 describe-iam-instance-profile-associations --filters "Name=instance-id,Values=$instance_id" | jq -r '.IamInstanceProfileAssociations[-1].AssociationId')

aws ec2 replace-iam-instance-profile-association --association-id $iip_association --iam-instance-profile Name=$instance_profile

Test

Login into the instance:

instance_public_ip=$(aws ec2 describe-instances --filters Name=tag:Name,Values=$instance | jq -r '.Reservations[-1].Instances[-1].PublicIpAddress')
ssh -i ~/.ssh/$key ec2-user@$instance_public_ip

Verify that you can access S3:

# run this on the instance
aws s3 ls

Next step: Cleanup