Limit which IAM roles can be attached to an EC2 instance by different IAM users

0

Hi!

Im trying to figure out if this is possible. I have 2 IAM users. I would like each one to be able to start/stop the same EC2 instance but have each IAM user be able to attach a different IAM role to this one EC2 instance. In other words, user1 should only be able to attach role1 to this ec2 instance, while user2 should only be able to attach role2 to this same EC2 instance. They would be using the ec2 instance at different times.

I'm using the aws ec2 associate-iam-instance-profile command to attach the IAM profile to the EC2 instance before starting it up and then detaching the profile once I shut it down. I would like for each IAM user to be able to attach only a specific IAM role to this one EC2 instance.

Is this possible? Any ideas or examples? Thank you!

  • I'd also like to point out that IAM Users have two drawbacks: 1) They don't scale as you grow larger than the maximum number of users and 2) You will require multiple authentication methods between your company and your AWS account, which can contribute to potential loss of credentials as well as lack of revocation when an employee leaves (higher management). We recommend you use a central identity provider, for example, AWS SSO if you don't have another.

3 Answers
2

Hi,

You can use tags attached to each of IAM role and then assign permission of accessing IAM roles based on those tags. Follow this link to know more about the same.

However, you also need to build a mechanism by which you can disassociate one IAM role when other user shutdown the machine or logs off. Since if user1 leave machine with their role attached to the machine it will be available in the same state to user2.

profile pictureAWS
irshad
answered 2 years ago
1

You can also do this specifying the instance id as the resource and using conditions keys for the InstanceProfile ARN in your policy for each user (different ARN's in each policy). See the documentation here:

https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html

Some good examples are here (including using tag keys/values as was previously suggested)

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-iam-roles

Hope this helps.

AWS
Jeff_S
answered 2 years ago
0

Here is the solution that worked for me.

  • I have two IAM users: deploy-staging and deploy-production.
  • I have a single EC2 instance that can deploy to a staging environment or a production environment depending on the IAM role it has assumed.
  • The deploy-staging IAM user has the following IAM policy attached. This policy will allow this user to start/stop the EC2 instance that is used to deploy code to staging and attach/detach the correct IAM role (deploy-role-staging) to that EC2 instance so it can have the correct permissions to deploy to staging. That is the ONLY IAM role that this user will be able to attach to this EC2 instance.
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "ec2:StartInstances",
                  "ec2:DisassociateIamInstanceProfile",
                  "ec2:ModifySecurityGroupRules",
                  "ec2:StopInstances",
                  "ec2:AssociateIamInstanceProfile",
                  "ec2:ReplaceIamInstanceProfileAssociation"
              ],
              "Resource": [
                  "arn:aws:ec2:*:account-id:security-group/sg-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:us-east-1:account-id:instance/i-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:*:account-id:security-group-rule/sgr-xxxxxxxxxxxxxx"
              ]
          },
          {
              "Sid": "VisualEditor1",
              "Effect": "Allow",
              "Action": [
                  "ec2:DescribeInstances",
                  "ec2:DescribeIamInstanceProfileAssociations"
              ],
              "Resource": "*"
          },
          {
              "Sid": "VisualEditor2",
              "Effect": "Allow",
              "Action": "iam:PassRole",
              "Resource": "arn:aws:iam::account-id:role/deploy-role-staging"
          }
      ]
    }
  • The deploy-production IAM user has the following IAM policy attached. This policy will allow this user to start/stop the EC2 instance that is used to deploy code to production and attach/detach the correct IAM role (deploy-role-production) to that EC2 instance so it can have the correct permissions to deploy to production. That is the ONLY IAM role that this user will be able to attach to this EC2 instance.
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "ec2:StartInstances",
                  "ec2:DisassociateIamInstanceProfile",
                  "ec2:ModifySecurityGroupRules",
                  "ec2:StopInstances",
                  "ec2:AssociateIamInstanceProfile",
                  "ec2:ReplaceIamInstanceProfileAssociation"
              ],
              "Resource": [
                  "arn:aws:ec2:*:account-id:security-group/sg-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:us-east-1:account-id:instance/i-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:*:account-id:security-group-rule/sgr-xxxxxxxxxxxxxx"
              ]
          },
          {
              "Sid": "VisualEditor1",
              "Effect": "Allow",
              "Action": [
                  "ec2:DescribeInstances",
                  "ec2:DescribeIamInstanceProfileAssociations"
              ],
              "Resource": "*"
          },
          {
              "Sid": "VisualEditor2",
              "Effect": "Allow",
              "Action": "iam:PassRole",
              "Resource": "arn:aws:iam::account-id:role/deploy-role-production"
          }
      ]
    }
  • The deploy-role-staging IAM role has policies attached to it that allow it to update the S3 buckets for staging and the Cloudfront distribution for staging.
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "cloudfront:GetInvalidation",
                  "cloudfront:CreateInvalidation"
              ],
              "Resource": [
                  "arn:aws:cloudfront::account-id:distribution/XXXXXXXXXXXXX"
              ]
          }
      ]
    }
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "s3:PutObject",
                  "s3:ListBucket",
                  "s3:DeleteObject",
                  "s3:PutObjectAcl"
              ],
              "Resource": [
                  "arn:aws:s3:::stagingXXX.example.com",
                  "arn:aws:s3:::stagingXXX.example.com/*"
              ]
          }
      ]
    }
  • The deploy-role-production IAM role has policies attached to it that allow it to update the S3 buckets for production and the Cloudfront distribution for production.
    They're the same as for staging, except the ID of Cloudfront distribution and the S3 bucket names are different.

In Summary: Each user will only be able to have the EC2 instance assume a particular role, thus giving that EC2 instance access to different resources.

Do not forget to write the code to actually start/stop the EC2 instance, attach/detach the IAM role using these CLI command samples (via /bin/bash):

    # Get the current IAM role association for the EC2 instance.
    EC2_IAM_ROLE_ASSOCIATION_ID=`aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=XXXXXXXXXXXX --query 'IamInstanceProfileAssociations[*].AssociationId' --output text --profile XXXX`

    # Only disassociate an IAM role if one is attached to the EC2 instance.
    if [ "$EC2_IAM_ROLE_ASSOCIATION_ID" ]; then
      # Disassociate any IAM role from the EC2 instance.
      aws ec2 disassociate-iam-instance-profile --association-id $EC2_IAM_ROLE_ASSOCIATION_ID --profile XXXX
    fi

    # Attach the correct IAM Role to the EC2 instance.
    EC2_IAM_ROLE_ASSOCIATION_ID=`aws ec2 associate-iam-instance-profile --instance-id XXXXXXXXXXXX --iam-instance-profile Name="$IAM_ROLE" --query 'IamInstanceProfileAssociation.AssociationId' --output text --profile XXXX`

    # Disassociate any IAM Role from the EC2 instance.
    aws ec2 disassociate-iam-instance-profile --association-id $EC2_IAM_ROLE_ASSOCIATION_ID --query 'IamInstanceProfileAssociation.State' --output text --profile XXXX
answered 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions