Best Way for Giving Permission to AWS Services
Tags: aws, ec2, s3, iam
Published: 2022-07-20 04:57:39

For AWS IAM service, we must keep at least privileged access. It's the best practice in using IAM for security purposes. For IAM user, attaching policy at a group level is the best practice. For "specific" AWS services, IAM role is the best way to give permission for the source and IAM policy for the destination.

For example:

1. Use IAM role to give permission for EC2 instances, let's say for accessing S3 such as listing or creating a bucket.
    
2. Use IAM policy to only allow access from any sources, let's say for static website purposes we allow public access to specific buckets.
    

Here I'll you the first option which is IAM role!

**1\. Create EC2 instance**

Here I'll create an EC2 instance through CLI with Amazon Linux 2 as AMI and leave the rest to use default as it is. Before that, I'll also import the key pair.

```bash
$ aws ec2 import-key-pair --key-name "ec2-user" --public-key-material fileb://home/nurulramadhona/.ssh/id_rsa.pub
$ aws ec2 run-instances --image-id ami-021fb2b73ff1efc96 --count 1 --instance-type t3.micro --key-name ec2-user
$ aws ec2 describe-instances --query 'Reservations[].Instances[].{PublicIP:PublicIpAddress, ID:InstanceId}'
[
    {
        "PublicIP": "108.136.45.150",
        "ID": "i-0f3df2b1eb51bc6a1"
    }
]
```

**2\. Create IAM role & attach policy**

Trust document:

```bash
$ cat ec2-role.json 
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

```bash
$ aws iam create-role --role-name ec2-role --assume-role-policy-document file://ec2-role.json
$ aws iam attach-role-policy --role-name ec2-role --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
```

**3\. Create instance profile & add role**

An instance profile is a container for an IAM role that you can use to pass role information to an EC2 instance when the instance starts. Please note that we only can have one role per instance profile.

```bash
$ aws iam create-instance-profile --instance-profile-name ec2-profile
$ aws iam add-role-to-instance-profile --role-name ec2-role --instance-profile-name ec2-profile
```

**4\. Associate instance profile to EC2 instances**

```bash
aws ec2 associate-iam-instance-profile --instance-id i-0f3df2b1eb51bc6a1 --iam-instance-profile Name=ec2-profile
aws ec2 describe-iam-instance-profile-associations
```

Let's check! Before:

```bash
$ ssh ec2-user@108.136.45.150 

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
4 package(s) needed for security, out of 5 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-172-31-0-125 ~]$ aws s3 ls
Unable to locate credentials. You can configure credentials by running "aws configure".
```

After:

```bash
[ec2-user@ip-172-31-0-125 ~]$ aws s3 ls
[ec2-user@ip-172-31-0-125 ~]$ aws s3 mb s3://bucket-ec2-role
make_bucket failed: s3://bucket-ec2-role An error occurred (AccessDenied) when calling the CreateBucket operation: Access Denied
```

**5\. Least Privilege Access**

As we can see above, we can list a bucket (currently empty) but can't create a bucket with an error `Access Denied`. If we really need it, we can attach one more policy to the IAM role. This is what I mean by giving permission as needed. So, let's try!

```bash
$ aws iam attach-role-policy --role-name ec2-role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
```

```bash
[ec2-user@ip-172-31-0-125 ~]$ aws s3 mb s3://bucket-ec2-role
make_bucket: bucket-ec2-role
[ec2-user@ip-172-31-0-125 ~]$ aws s3 ls
2022-05-26 02:43:47 bucket-ec2-role
```

Then, we also can detach if the policy is no longer needed.

```bash
$ aws iam detach-role-policy --role-name ec2-role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
```

```bash
[ec2-user@ip-172-31-0-125 ~]$ aws s3 mb s3://bucket-ec2-role2
make_bucket failed: s3://bucket-ec2-role2 An error occurred (AccessDenied) when calling the CreateBucket operation: Access Denied
```

**Additional:** In case you want to delete the IAM role, make sure we have:

1. Remove the role from the instance profile before deleting the instance profile.
    
2. Delete instance profile.
    
3. Detach all policies from the role.
    

That's it! Thank you for coming and I'm looking forward to your feedback. Follow me to get notified when my new post is published!